Index: trunk/grails-app/services/CsvService.groovy
===================================================================
--- trunk/grails-app/services/CsvService.groovy	(revision 285)
+++ trunk/grails-app/services/CsvService.groovy	(revision 287)
@@ -11,6 +11,7 @@
 
     /**
-    * Import an asset tree for a single asset.
-    * @param file A csv file containing the asset tree for a single asset.
+    * Import an asset tree creating items as required.
+    * @param request The http request to run getFile against.
+    * Get file should return a csv format file containing the asset tree as per template.
     */
     def importAssetTree(request) {
@@ -20,11 +21,15 @@
         def fileMaxSize = 10 * megaByteMultiplier //Mb
 
+        def multiPartFile = request.getFile('file')
+
+        InputStreamReader sr = new InputStreamReader(multiPartFile.inputStream)
+        CSVReader reader = new CSVReader(sr)
+
         def fail = { Map m ->
             //status.setRollbackOnly()
-            result.error = [ code: m.code, args: ["Import Asset Tree"] ]
+            reader.close()
+            result.error = [ code: m.code, args: m.args ]
             return result
         }
-
-        def multiPartFile = request.getFile('file')
 
         if(!multiPartFile || multiPartFile.isEmpty())
@@ -32,33 +37,35 @@
 
         if (multiPartFile.getSize() > fileMaxSize)
-            return fail(code: "asset.tree.import.file.over.max.size")
+            return fail(code: "asset.tree.import.file.over.max.size", args: [fileMaxSize/megaByteMultiplier])
 
-        InputStreamReader sr = new InputStreamReader(multiPartFile.inputStream)
-        CSVReader reader = new CSVReader(sr)
-
-        def nextLine = reader.readNext()
+        def line = reader.readNext()
         def lineNumber = 1
 
         def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
-        if(nextLine != header)
+
+        if(line != header)
             return fail(code: "asset.tree.import.no.header")
 
-        nextLine = reader.readNext()
+        log.info "Import checks passed, start processing asset file."
+
+        // Prepare the first body line.
+        line = reader.readNext()
         lineNumber ++
 
-        while(nextLine) {
+        while(line) {
+            def lineSize = line.size()
+//             log.info lineNumber+ "(" + lineSize + ")" + " : " + line
+
+            if(line[0]) {
+                    if( !Site.findByName(line[0]) )
+                        new Site(name: line[0]).save()
+            }
+
+            line = reader.readNext()
             lineNumber ++
-
-            println lineNumber + " : " + nextLine[0]
-
-//             if(nextLine[0]) {
-//                 if( !Site.findByName(nextLine[0].toString()) )
-//                     println nextLine[0]
-//             }
-
-            nextLine = reader.readNext()
-        } //while(nextLine)
+        } //while(line)
 
         // Success.
+        reader.close()
         return result
 
@@ -77,11 +84,10 @@
         //Header
         def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
+        def blankLine = []
+        def noteLine = ["Note: the header is required, start by replacing this line."]
+
         writer.writeNext(header as String[])
-
-        //Rows
-        def row
-
-        row = []
-        writer.writeNext(row as String[]) //blank row between assets.
+        writer.writeNext(blankLine as String[])
+        writer.writeNext(noteLine as String[])
 
         writer.close()
