]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/FileDocumentUtil.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.document.ui / src / org / simantics / document / ui / graphfile / FileDocumentUtil.java
index ece4a38a533e50354931d869ce6c7db61ec7f673..4933ca25162a49a25f126ee5f27447aaa1602e75 100644 (file)
-package org.simantics.document.ui.graphfile;\r
-\r
-import java.io.BufferedReader;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.IOException;\r
-import java.io.InputStreamReader;\r
-import java.io.PrintStream;\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.ReadRequest;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.request.WriteResultRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.document.DocumentResource;\r
-import org.simantics.graphfile.ontology.GraphFileResource;\r
-import org.simantics.graphfile.util.GraphFileUtil;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-\r
-/**\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class FileDocumentUtil {\r
-       \r
-       /**\r
-        * Imports file, sets its L0.hasName, and and adds it to a library\r
-        * \r
-        * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.\r
-        * \r
-        * @param fileName\r
-        * @param lib\r
-        * @param rel\r
-        * @throws DatabaseException \r
-        */\r
-       public static Resource importFile(final String fileName, final Resource lib, final Resource rel) throws DatabaseException {\r
-               return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {\r
-                       @Override\r
-                       public Resource perform(WriteGraph graph) throws DatabaseException {\r
-                               return importFile(graph, fileName,lib,rel);\r
-                       }\r
-               });\r
-                       \r
-               \r
-       }\r
-       \r
-       public static void importFileAsync(final String fileName, final Resource lib, final Resource rel)  {\r
-               Simantics.getSession().asyncRequest(new WriteRequest() {\r
-                       \r
-                       @Override\r
-                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                                importFile(graph, fileName,lib,rel);\r
-                               \r
-                       }\r
-               },new org.simantics.utils.datastructures.Callback<DatabaseException>() {\r
-                       \r
-                       @Override\r
-                       public void run(DatabaseException parameter) {\r
-                               if (parameter != null)\r
-                                       ExceptionUtils.logAndShowError("Cannot import file " + fileName, parameter);\r
-                               \r
-                       }\r
-               });\r
-                       \r
-               \r
-       }\r
-       \r
-       /**\r
-        * Imports file, sets its L0.HasName, and and adds it to a library\r
-        * \r
-        * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.\r
-        * \r
-        * @param graph\r
-        * @param fileName\r
-        * @param lib\r
-        * @param rel\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource importFile(WriteGraph graph, String fileName, Resource lib, Resource rel) throws DatabaseException{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               Resource fileResource = importFile(graph, fileName);\r
-               graph.claim(lib, rel, fileResource);\r
-               File file = new File(fileName);\r
-               String name = file.getName();\r
-               graph.claimLiteral(fileResource, l0.HasName, name);\r
-               setUniqueName(graph, fileResource, lib, rel);\r
-               return fileResource;\r
-       }\r
-       \r
-       public static Resource importFileWithName(WriteGraph graph, String fileName) throws DatabaseException{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               Resource fileResource = importFile(graph, fileName);\r
-               File file = new File(fileName);\r
-               String name = file.getName();\r
-               graph.claimLiteral(fileResource, l0.HasName, name);\r
-               return fileResource;\r
-       }\r
-       \r
-       /**\r
-        * Imports folder of documents recursively (including all sub folders). \r
-        * @param graph\r
-        * @param folderName  Name of imported folder\r
-        * @param lib         Library, where imported folder is attached.\r
-        * @param folderType  Type of folders\r
-        * @param relation    Relation used to create file/folder hierarchy\r
-        * @return            the imported folder\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource lib, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{\r
-               Resource folderRes = importFolderWithName(graph, folderName, folderType, relation,monitor);\r
-               graph.claim(lib, relation, folderRes);\r
-               FileDocumentUtil.createUniqueName(graph, folderRes);\r
-               return folderRes;\r
-       }\r
-       \r
-       /**\r
-        * Imports folder of documents recursively (including all sub folders). \r
-        * @param graph\r
-        * @param folderName  Name of imported folder\r
-        * @param folderType  Type of folders\r
-        * @param relation    Relation used to create file/folder hierarchy\r
-        * @param monitor     ProgessMonitor or null\r
-        * @return            the imported folder\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               File folder = new File(folderName);\r
-               Resource rootFolderRes = graph.newResource();\r
-               graph.claim(rootFolderRes, l0.InstanceOf, folderType);\r
-               graph.claimLiteral(rootFolderRes, l0.HasName, folder.getName());\r
-               importFolder(graph, folder, rootFolderRes, relation, monitor);\r
-               return rootFolderRes;\r
-       }\r
-       \r
-       /**\r
-        * Imports folder of documents recursively (including all sub folders).\r
-        * @param graph\r
-        * @param folder            Imported folder\r
-        * @param folderResource    Resource folder matching file system folder\r
-        * @param relation          Relation used to create file/folder hierarchy\r
-        * @throws DatabaseException\r
-        */\r
-       public static void importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{\r
-               if (monitor != null) {\r
-                       int count = _countFiles(folder);\r
-                       monitor.beginTask("Import files", count);\r
-               }\r
-               _importFolder(graph, folder, folderResource, relation, monitor);\r
-               if (monitor != null)\r
-                       monitor.done();\r
-       }\r
-       \r
-       private static void _importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               File files[] = folder.listFiles();\r
-               for (File f : files) {\r
-                       if (f.isDirectory()) {\r
-                               Resource newFolderRes = graph.newResource();\r
-                               graph.claim(newFolderRes, l0.InstanceOf, graph.getSingleType(folderResource));\r
-                               graph.claim(folderResource, relation, newFolderRes);\r
-                               graph.claimLiteral(newFolderRes, l0.HasName, f.getName());\r
-                               _importFolder(graph, f, newFolderRes, relation,monitor);\r
-                       } else {\r
-                               Resource fileRes = null;\r
-                               if (isUrl(f)) {\r
-                               } else {\r
-                                   fileRes = importURL(graph, f);\r
-                                       fileRes = importFileWithName(graph, f.getAbsolutePath());\r
-                               }\r
-                               graph.claim(folderResource, relation, fileRes);\r
-                               if (monitor != null)\r
-                                       monitor.worked(1);\r
-                       }\r
-               }\r
-       }\r
-       \r
-       private static int _countFiles(File folder) {\r
-               \r
-               int count = 0;\r
-               File files[] = folder.listFiles();\r
-               for (File f : files) {\r
-                       if (f.isDirectory()) {\r
-                               count += _countFiles(f);\r
-                       } else {\r
-                               count++;\r
-                       }\r
-               }\r
-               return count;\r
-       }\r
-       \r
-       \r
-       public static void createUniqueName(WriteGraph graph, Resource document) throws DatabaseException {\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               Resource lib = graph.getPossibleObject(document, l0.PartOf);\r
-               if (lib == null)\r
-                       return;\r
-               setUniqueName(graph, document, lib, l0.ConsistsOf);\r
-       }\r
-       \r
-       public static void setUniqueName(WriteGraph graph, Resource res, Resource lib, Resource rel) throws DatabaseException{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               Set<String> names = new HashSet<String>();\r
-               for (Resource r : graph.getObjects(lib, rel)) {\r
-                       if (r.equals(res))\r
-                               continue;\r
-                       names.add((String)graph.getRelatedValue(r, l0.HasName));\r
-               }\r
-               String name = graph.getRelatedValue(res, l0.HasName);\r
-               if (!names.contains(name))\r
-                       return;\r
-               int i = 1;\r
-               while (true) {\r
-                       String proposal = name +" (" + i +")";\r
-                       if (!names.contains(proposal)) {\r
-                               graph.claimLiteral(res, l0.HasName, proposal);\r
-                               return;\r
-                       }\r
-                       i++;\r
-               }\r
-               \r
-       }\r
-       \r
-       /**\r
-        * Imports a file\r
-        * \r
-        * @param graph\r
-        * @param fileName\r
-        * @return\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource importFile(WriteGraph graph, String fileName) throws DatabaseException{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               DocumentResource doc = DocumentResource.getInstance(graph);\r
-               \r
-               Resource fileResource = graph.newResource();\r
-               graph.claim(fileResource, l0.InstanceOf, doc.FileDocument);\r
-               try {\r
-                       GraphFileUtil.toGraph(graph,fileName, fileResource);\r
-                       \r
-               } catch (IOException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-               return fileResource;\r
-               \r
-       }\r
-       \r
-       /**\r
-        * Exports graph folder recursively to file system. \r
-        * @param graph\r
-        * @param folderResource\r
-        * @param folder\r
-        * @param relation\r
-        * @throws DatabaseException\r
-        */\r
-       public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, boolean useResourceNames, final IProgressMonitor monitor) throws Exception{\r
-               Simantics.getSession().syncRequest(new ReadRequest() {\r
-                       \r
-                       @Override\r
-                       public void run(ReadGraph graph) throws DatabaseException {\r
-                               try {\r
-                                       exportDocumentFolder(graph, folderResource, folder, relation, useResourceNames, monitor);\r
-                               } catch (Exception e) {\r
-                                       throw new DatabaseException(e);\r
-                               }\r
-                               \r
-                       }\r
-               });\r
-       }\r
-       \r
-       \r
-       /**\r
-        * Exports graph folder recursively to file system. \r
-        * @param graph\r
-        * @param folderResource\r
-        * @param folder\r
-        * @param relation\r
-        * @throws DatabaseException\r
-        */\r
-       public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, boolean useResourceNames, IProgressMonitor monitor) throws Exception{\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               DocumentResource doc = DocumentResource.getInstance(graph);\r
-               GraphFileResource gf = GraphFileResource.getInstance(graph);\r
-               Set<String> names = new HashSet<String>();\r
-               Collection<Resource> folderType = graph.getPrincipalTypes(folderResource);\r
-               for (Resource r : graph.getObjects(folderResource, relation)) {\r
-                       if (graph.isInstanceOf(r, doc.Document)) {\r
-                               String name = null;\r
-                               boolean canExport = false;\r
-                               if (graph.isInstanceOf(r, doc.FileDocument)) {\r
-                                       name = graph.getRelatedValue(r, useResourceNames ? gf.HasResourceName : l0.HasName);\r
-                                       canExport = true;\r
-                               } else if (graph.isInstanceOf(r, doc.UrlDocument)) {\r
-                                       name = graph.getRelatedValue(r, l0.HasName) +".url";\r
-                                       canExport = true;\r
-                               }\r
-                               if (canExport) {\r
-                                       name = resolveName(folder, name, names, true);\r
-                                       File file = new File(folder.getAbsolutePath()+"/"+name);\r
-                                       if (graph.isInstanceOf(r, doc.FileDocument)) {\r
-                                               GraphFileUtil.writeDataToFile(graph,r, file);\r
-                                       } else if (graph.isInstanceOf(r, doc.UrlDocument)) {\r
-                                               String url = graph.getRelatedValue(r, doc.HasUrl);\r
-                                               String n = graph.getRelatedValue(r, l0.HasName);\r
-                                               exportUrl(file, n, url);\r
-                                       }\r
-                                       if (monitor != null)\r
-                                               monitor.worked(1);\r
-                               }\r
-                               \r
-                       } else {\r
-                               Collection<Resource> type = graph.getPrincipalTypes(r);\r
-                               if (type.size() == folderType.size() && folderType.containsAll(type)) {\r
-                                       String name = graph.getRelatedValue(r, l0.HasName);\r
-                                       name = resolveName(folder, name, names, false);\r
-                                       File subFolder = new File(folder.getAbsolutePath()+"/"+name);\r
-                                       if (!subFolder.exists()) {\r
-                                               if (!subFolder.mkdir()) {\r
-                                                       // TODO : error.\r
-                                                       continue;\r
-                                               }\r
-                                       }\r
-                                       exportDocumentFolder(graph, r, subFolder, relation, useResourceNames, monitor);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Print URL to a file (Windows specific format?)\r
-        * @param toFile\r
-        * @param url\r
-        * @throws DatabaseException\r
-        */\r
-       private static void exportUrl(File toFile, String name, String url) throws Exception{\r
-               PrintStream os = new PrintStream(toFile,"UTF-8");\r
-               os.println("[InternetShortcut]");\r
-               os.println("URL="+url);\r
-               os.println("name="+name);\r
-               os.flush();\r
-               os.close();\r
-       }\r
-       \r
-       public static Resource importURL(WriteGraph graph, File file) throws Exception{\r
-               String s = null;\r
-               String url = null;\r
-               String name = null;\r
-               BufferedReader is = null;\r
-               try {\r
-               is = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));\r
-               while ((s = is.readLine()) != null) {\r
-                       if (s.startsWith("URL=")) {\r
-                               url = s.substring(4);\r
-                       } else if (s.startsWith("name=")) {\r
-                               name = s.substring(5);\r
-                       }\r
-               }\r
-               } finally {\r
-                   if (is != null)\r
-                       is.close();\r
-               }\r
-               \r
-               if (url == null)\r
-                       return null;\r
-               \r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               DocumentResource doc = DocumentResource.getInstance(graph);\r
-               \r
-               Resource fileResource = graph.newResource();\r
-               graph.claim(fileResource, l0.InstanceOf, doc.UrlDocument);\r
-               if (name == null) {\r
-                       name = file.getName();\r
-                       name = unescape(name);\r
-                       name = name.substring(0,name.length()-4);\r
-               }\r
-               graph.claimLiteral(fileResource, l0.HasName, name);\r
-               graph.claimLiteral(fileResource, doc.HasUrl, url);\r
-               return fileResource;\r
-       }\r
-       \r
-       private static boolean isUrl(File file) throws Exception{\r
-               return (file.getAbsolutePath().endsWith(".url"));\r
-       }\r
-       \r
-       private static final char ESCAPE = '%';\r
-       \r
-       private static String escape(String s) {\r
-               \r
-               int len = s.length();\r
-               StringBuilder sb = new StringBuilder(len);\r
-               for (int i = 0; i < len; i++) {\r
-                   char ch = s.charAt(i);\r
-                   if (ch < ' ' || ch >= 0x7F || ch == '/'  || ch == '\\' || ch == ':' || ch == ESCAPE) {\r
-                       sb.append(ESCAPE);\r
-                       if (ch < 0x10) {\r
-                           sb.append('0');\r
-                       }\r
-                       sb.append(Integer.toHexString(ch));\r
-                   } else {\r
-                       sb.append(ch);\r
-                   }\r
-               }\r
-               return sb.toString();\r
-       }\r
-       \r
-       private static String unescape(String s) {\r
-               int len = s.length();\r
-               StringBuilder sb = new StringBuilder(len);\r
-               for (int i = 0; i < len; i++) {\r
-                   char ch = s.charAt(i);\r
-                   if (ch == ESCAPE) {\r
-                       String num = "0x";\r
-                       num += s.charAt(++i);\r
-                       num += s.charAt(++i);\r
-                       ch = (char)Integer.decode(num).intValue();\r
-                   }\r
-                   sb.append(ch);\r
-               }\r
-               return sb.toString();\r
-               \r
-       }\r
-       \r
-       private static String resolveName(File parentFolder, String proposal, Set<String> used, boolean file) {\r
-               String current = escape(proposal);\r
-               int i = 0;\r
-               if (file) {\r
-                       while (true) {\r
-                               i++;\r
-                               if (used.contains(current)) {\r
-                                       current = createFileName(proposal, i);\r
-                               } else {\r
-                                       File subFile = new File(parentFolder.getAbsolutePath()+"/"+current);\r
-                                       if (!subFile.exists())\r
-                                               break;\r
-                                       if (subFile.exists() && subFile.isFile() && subFile.canWrite()) {\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-               } else {\r
-                       while (true) {\r
-                               i++;\r
-                               if (used.contains(current)) {\r
-                                       current = proposal+i;\r
-                               } else {\r
-                                       File subFolder = new File(parentFolder.getAbsolutePath()+"/"+current);\r
-                                       if (!subFolder.exists())\r
-                                               break;\r
-                                       if (subFolder.exists() && subFolder.isDirectory()) {\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               used.add(current);\r
-               return current;\r
-       }\r
-       \r
-       private static String createFileName(String original, int i) {\r
-               int extIndex = original.lastIndexOf(".");\r
-               if (extIndex == -1)\r
-                       return original+i;\r
-               return original.substring(0,extIndex) + i + original.substring(extIndex);\r
-       }\r
-\r
-}\r
+package org.simantics.document.ui.graphfile;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.request.WriteResultRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.document.DocumentResource;
+import org.simantics.graphfile.ontology.GraphFileResource;
+import org.simantics.graphfile.util.GraphFileUtil;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.ui.ExceptionUtils;
+
+/**
+ * 
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class FileDocumentUtil {
+       
+       /**
+        * Imports file, sets its L0.hasName, and and adds it to a library
+        * 
+        * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.
+        * 
+        * @param fileName
+        * @param lib
+        * @param rel
+        * @throws DatabaseException 
+        */
+       public static Resource importFile(final String fileName, final Resource lib, final Resource rel) throws DatabaseException {
+               return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
+                       @Override
+                       public Resource perform(WriteGraph graph) throws DatabaseException {
+                               return importFile(graph, fileName,lib,rel);
+                       }
+               });
+                       
+               
+       }
+       
+       public static void importFileAsync(final String fileName, final Resource lib, final Resource rel)  {
+               Simantics.getSession().asyncRequest(new WriteRequest() {
+                       
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+                                importFile(graph, fileName,lib,rel);
+                               
+                       }
+               },new org.simantics.utils.datastructures.Callback<DatabaseException>() {
+                       
+                       @Override
+                       public void run(DatabaseException parameter) {
+                               if (parameter != null)
+                                       ExceptionUtils.logAndShowError("Cannot import file " + fileName, parameter);
+                               
+                       }
+               });
+                       
+               
+       }
+       
+       /**
+        * Imports file, sets its L0.HasName, and and adds it to a library
+        * 
+        * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.
+        * 
+        * @param graph
+        * @param fileName
+        * @param lib
+        * @param rel
+        * @throws DatabaseException
+        */
+       public static Resource importFile(WriteGraph graph, String fileName, Resource lib, Resource rel) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource fileResource = importFile(graph, fileName);
+               graph.claim(lib, rel, fileResource);
+               File file = new File(fileName);
+               String name = file.getName();
+               graph.claimLiteral(fileResource, l0.HasName, name);
+               setUniqueName(graph, fileResource, lib, rel);
+               return fileResource;
+       }
+       
+       public static Resource importFileWithName(WriteGraph graph, String fileName) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource fileResource = importFile(graph, fileName);
+               File file = new File(fileName);
+               String name = file.getName();
+               graph.claimLiteral(fileResource, l0.HasName, name);
+               return fileResource;
+       }
+       
+       /**
+        * Imports folder of documents recursively (including all sub folders). 
+        * @param graph
+        * @param folderName  Name of imported folder
+        * @param lib         Library, where imported folder is attached.
+        * @param folderType  Type of folders
+        * @param relation    Relation used to create file/folder hierarchy
+        * @return            the imported folder
+        * @throws DatabaseException
+        */
+       public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource lib, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{
+               Resource folderRes = importFolderWithName(graph, folderName, folderType, relation,monitor);
+               graph.claim(lib, relation, folderRes);
+               FileDocumentUtil.createUniqueName(graph, folderRes);
+               return folderRes;
+       }
+       
+       /**
+        * Imports folder of documents recursively (including all sub folders). 
+        * @param graph
+        * @param folderName  Name of imported folder
+        * @param folderType  Type of folders
+        * @param relation    Relation used to create file/folder hierarchy
+        * @param monitor     ProgessMonitor or null
+        * @return            the imported folder
+        * @throws DatabaseException
+        */
+       public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{
+               Layer0 l0 = Layer0.getInstance(graph);
+               File folder = new File(folderName);
+               Resource rootFolderRes = graph.newResource();
+               graph.claim(rootFolderRes, l0.InstanceOf, folderType);
+               graph.claimLiteral(rootFolderRes, l0.HasName, folder.getName());
+               importFolder(graph, folder, rootFolderRes, relation, monitor);
+               return rootFolderRes;
+       }
+       
+       /**
+        * Imports folder of documents recursively (including all sub folders).
+        * @param graph
+        * @param folder            Imported folder
+        * @param folderResource    Resource folder matching file system folder
+        * @param relation          Relation used to create file/folder hierarchy
+        * @throws DatabaseException
+        */
+       public static void importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{
+               if (monitor != null) {
+                       int count = _countFiles(folder);
+                       monitor.beginTask("Import files", count);
+               }
+               _importFolder(graph, folder, folderResource, relation, monitor);
+               if (monitor != null)
+                       monitor.done();
+       }
+       
+       private static void _importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{
+               Layer0 l0 = Layer0.getInstance(graph);
+               File files[] = folder.listFiles();
+               for (File f : files) {
+                       if (f.isDirectory()) {
+                               Resource newFolderRes = graph.newResource();
+                               graph.claim(newFolderRes, l0.InstanceOf, graph.getSingleType(folderResource));
+                               graph.claim(folderResource, relation, newFolderRes);
+                               graph.claimLiteral(newFolderRes, l0.HasName, f.getName());
+                               _importFolder(graph, f, newFolderRes, relation,monitor);
+                       } else {
+                               Resource fileRes = null;
+                               if (isUrl(f)) {
+                               } else {
+                                   fileRes = importURL(graph, f);
+                                       fileRes = importFileWithName(graph, f.getAbsolutePath());
+                               }
+                               graph.claim(folderResource, relation, fileRes);
+                               if (monitor != null)
+                                       monitor.worked(1);
+                       }
+               }
+       }
+       
+       private static int _countFiles(File folder) {
+               
+               int count = 0;
+               File files[] = folder.listFiles();
+               for (File f : files) {
+                       if (f.isDirectory()) {
+                               count += _countFiles(f);
+                       } else {
+                               count++;
+                       }
+               }
+               return count;
+       }
+       
+       
+       public static void createUniqueName(WriteGraph graph, Resource document) throws DatabaseException {
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource lib = graph.getPossibleObject(document, l0.PartOf);
+               if (lib == null)
+                       return;
+               setUniqueName(graph, document, lib, l0.ConsistsOf);
+       }
+       
+       public static void setUniqueName(WriteGraph graph, Resource res, Resource lib, Resource rel) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Set<String> names = new HashSet<String>();
+               for (Resource r : graph.getObjects(lib, rel)) {
+                       if (r.equals(res))
+                               continue;
+                       names.add((String)graph.getRelatedValue(r, l0.HasName));
+               }
+               String name = graph.getRelatedValue(res, l0.HasName);
+               if (!names.contains(name))
+                       return;
+               int i = 1;
+               while (true) {
+                       String proposal = name +" (" + i +")";
+                       if (!names.contains(proposal)) {
+                               graph.claimLiteral(res, l0.HasName, proposal);
+                               return;
+                       }
+                       i++;
+               }
+               
+       }
+       
+       /**
+        * Imports a file
+        * 
+        * @param graph
+        * @param fileName
+        * @return
+        * @throws DatabaseException
+        */
+       public static Resource importFile(WriteGraph graph, String fileName) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               DocumentResource doc = DocumentResource.getInstance(graph);
+               
+               Resource fileResource = graph.newResource();
+               graph.claim(fileResource, l0.InstanceOf, doc.FileDocument);
+               try {
+                       GraphFileUtil.toGraph(graph,fileName, fileResource);
+                       
+               } catch (IOException e) {
+                       throw new DatabaseException(e);
+               }
+               return fileResource;
+               
+       }
+       
+       /**
+        * Exports graph folder recursively to file system. 
+        * @param graph
+        * @param folderResource
+        * @param folder
+        * @param relation
+        * @throws DatabaseException
+        */
+       public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, boolean useResourceNames, final IProgressMonitor monitor) throws Exception{
+               Simantics.getSession().syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               try {
+                                       exportDocumentFolder(graph, folderResource, folder, relation, useResourceNames, monitor);
+                               } catch (Exception e) {
+                                       throw new DatabaseException(e);
+                               }
+                               
+                       }
+               });
+       }
+       
+       
+       /**
+        * Exports graph folder recursively to file system. 
+        * @param graph
+        * @param folderResource
+        * @param folder
+        * @param relation
+        * @throws DatabaseException
+        */
+       public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, boolean useResourceNames, IProgressMonitor monitor) throws Exception{
+               Layer0 l0 = Layer0.getInstance(graph);
+               DocumentResource doc = DocumentResource.getInstance(graph);
+               GraphFileResource gf = GraphFileResource.getInstance(graph);
+               Set<String> names = new HashSet<String>();
+               Collection<Resource> folderType = graph.getPrincipalTypes(folderResource);
+               for (Resource r : graph.getObjects(folderResource, relation)) {
+                       if (graph.isInstanceOf(r, doc.Document)) {
+                               String name = null;
+                               boolean canExport = false;
+                               if (graph.isInstanceOf(r, doc.FileDocument)) {
+                                       name = graph.getRelatedValue(r, useResourceNames ? gf.HasResourceName : l0.HasName);
+                                       canExport = true;
+                               } else if (graph.isInstanceOf(r, doc.UrlDocument)) {
+                                       name = graph.getRelatedValue(r, l0.HasName) +".url";
+                                       canExport = true;
+                               }
+                               if (canExport) {
+                                       name = resolveName(folder, name, names, true);
+                                       File file = new File(folder.getAbsolutePath()+"/"+name);
+                                       if (graph.isInstanceOf(r, doc.FileDocument)) {
+                                               GraphFileUtil.writeDataToFile(graph,r, file);
+                                       } else if (graph.isInstanceOf(r, doc.UrlDocument)) {
+                                               String url = graph.getRelatedValue(r, doc.HasUrl);
+                                               String n = graph.getRelatedValue(r, l0.HasName);
+                                               exportUrl(file, n, url);
+                                       }
+                                       if (monitor != null)
+                                               monitor.worked(1);
+                               }
+                               
+                       } else {
+                               Collection<Resource> type = graph.getPrincipalTypes(r);
+                               if (type.size() == folderType.size() && folderType.containsAll(type)) {
+                                       String name = graph.getRelatedValue(r, l0.HasName);
+                                       name = resolveName(folder, name, names, false);
+                                       File subFolder = new File(folder.getAbsolutePath()+"/"+name);
+                                       if (!subFolder.exists()) {
+                                               if (!subFolder.mkdir()) {
+                                                       // TODO : error.
+                                                       continue;
+                                               }
+                                       }
+                                       exportDocumentFolder(graph, r, subFolder, relation, useResourceNames, monitor);
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Print URL to a file (Windows specific format?)
+        * @param toFile
+        * @param url
+        * @throws DatabaseException
+        */
+       private static void exportUrl(File toFile, String name, String url) throws Exception{
+               PrintStream os = new PrintStream(toFile,"UTF-8");
+               os.println("[InternetShortcut]");
+               os.println("URL="+url);
+               os.println("name="+name);
+               os.flush();
+               os.close();
+       }
+       
+       public static Resource importURL(WriteGraph graph, File file) throws Exception{
+               String s = null;
+               String url = null;
+               String name = null;
+               BufferedReader is = null;
+               try {
+               is = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
+               while ((s = is.readLine()) != null) {
+                       if (s.startsWith("URL=")) {
+                               url = s.substring(4);
+                       } else if (s.startsWith("name=")) {
+                               name = s.substring(5);
+                       }
+               }
+               } finally {
+                   if (is != null)
+                       is.close();
+               }
+               
+               if (url == null)
+                       return null;
+               
+               Layer0 l0 = Layer0.getInstance(graph);
+               DocumentResource doc = DocumentResource.getInstance(graph);
+               
+               Resource fileResource = graph.newResource();
+               graph.claim(fileResource, l0.InstanceOf, doc.UrlDocument);
+               if (name == null) {
+                       name = file.getName();
+                       name = unescape(name);
+                       name = name.substring(0,name.length()-4);
+               }
+               graph.claimLiteral(fileResource, l0.HasName, name);
+               graph.claimLiteral(fileResource, doc.HasUrl, url);
+               return fileResource;
+       }
+       
+       private static boolean isUrl(File file) throws Exception{
+               return (file.getAbsolutePath().endsWith(".url"));
+       }
+       
+       private static final char ESCAPE = '%';
+       
+       private static String escape(String s) {
+               
+               int len = s.length();
+               StringBuilder sb = new StringBuilder(len);
+               for (int i = 0; i < len; i++) {
+                   char ch = s.charAt(i);
+                   if (ch < ' ' || ch >= 0x7F || ch == '/'  || ch == '\\' || ch == ':' || ch == ESCAPE) {
+                       sb.append(ESCAPE);
+                       if (ch < 0x10) {
+                           sb.append('0');
+                       }
+                       sb.append(Integer.toHexString(ch));
+                   } else {
+                       sb.append(ch);
+                   }
+               }
+               return sb.toString();
+       }
+       
+       private static String unescape(String s) {
+               int len = s.length();
+               StringBuilder sb = new StringBuilder(len);
+               for (int i = 0; i < len; i++) {
+                   char ch = s.charAt(i);
+                   if (ch == ESCAPE) {
+                       String num = "0x";
+                       num += s.charAt(++i);
+                       num += s.charAt(++i);
+                       ch = (char)Integer.decode(num).intValue();
+                   }
+                   sb.append(ch);
+               }
+               return sb.toString();
+               
+       }
+       
+       private static String resolveName(File parentFolder, String proposal, Set<String> used, boolean file) {
+               String current = escape(proposal);
+               int i = 0;
+               if (file) {
+                       while (true) {
+                               i++;
+                               if (used.contains(current)) {
+                                       current = createFileName(proposal, i);
+                               } else {
+                                       File subFile = new File(parentFolder.getAbsolutePath()+"/"+current);
+                                       if (!subFile.exists())
+                                               break;
+                                       if (subFile.exists() && subFile.isFile() && subFile.canWrite()) {
+                                               break;
+                                       }
+                               }
+                       }
+               } else {
+                       while (true) {
+                               i++;
+                               if (used.contains(current)) {
+                                       current = proposal+i;
+                               } else {
+                                       File subFolder = new File(parentFolder.getAbsolutePath()+"/"+current);
+                                       if (!subFolder.exists())
+                                               break;
+                                       if (subFolder.exists() && subFolder.isDirectory()) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               used.add(current);
+               return current;
+       }
+       
+       private static String createFileName(String original, int i) {
+               int extIndex = original.lastIndexOf(".");
+               if (extIndex == -1)
+                       return original+i;
+               return original.substring(0,extIndex) + i + original.substring(extIndex);
+       }
+
+}