-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.eclipse.osgi.util.NLS;
+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);
+
+ }
+ }, e -> {
+ if (e != null)
+ ExceptionUtils.logAndShowError(NLS.bind(Messages.FileDocumentUtil_CannotImportFile, fileName), e);
+ });
+
+
+ }
+
+ /**
+ * 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(Messages.FileDocumentUtil_MonitorImportFiles, 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 +")"; //$NON-NLS-1$ //$NON-NLS-2$
+ 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"; //$NON-NLS-1$
+ canExport = true;
+ }
+ if (canExport) {
+ name = resolveName(folder, name, names, true);
+ File file = new File(folder.getAbsolutePath()+"/"+name); //$NON-NLS-1$
+ 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); //$NON-NLS-1$
+ 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"); //$NON-NLS-1$
+ os.println("[InternetShortcut]"); //$NON-NLS-1$
+ os.println("URL="+url); //$NON-NLS-1$
+ os.println("name="+name); //$NON-NLS-1$
+ 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")); //$NON-NLS-1$
+ while ((s = is.readLine()) != null) {
+ if (s.startsWith("URL=")) { //$NON-NLS-1$
+ url = s.substring(4);
+ } else if (s.startsWith("name=")) { //$NON-NLS-1$
+ 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")); //$NON-NLS-1$
+ }
+
+ 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"; //$NON-NLS-1$
+ 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); //$NON-NLS-1$
+ 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); //$NON-NLS-1$
+ 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("."); //$NON-NLS-1$
+ if (extIndex == -1)
+ return original+i;
+ return original.substring(0,extIndex) + i + original.substring(extIndex);
+ }
+
+}