]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java
Fall back to HasName if HasResourceName not available for GraphFile
[simantics/platform.git] / bundles / org.simantics.graphfile / src / org / simantics / graphfile / util / GraphFileUtil.java
index 9fdbf62c7b5ba4c96c5ce2d5fc5781de000496b6..fbfcc3a146e9c39a63853cec2faf3c6d52eaa29b 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2013 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.graphfile.util;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.nio.ByteBuffer;\r
-import java.nio.channels.FileChannel;\r
-import java.nio.file.Path;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import org.simantics.Simantics;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.util.binary.RandomAccessBinary;\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.common.utils.LiteralFileUtil;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.DoesNotContainValueException;\r
-import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
-import org.simantics.db.exception.NoSingleResultException;\r
-import org.simantics.db.exception.ServiceException;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.db.service.ClusteringSupport;\r
-import org.simantics.graphfile.ontology.GraphFileResource;\r
-import org.simantics.layer0.Layer0;\r
-\r
-/**\r
- * @author Marko Luukkainen\r
- */\r
-public class GraphFileUtil {\r
-       \r
-       \r
-       public static boolean USE_RANDOM_ACCESS_BINARY = true;\r
-       /**\r
-        * Creates a temp file of a graphFile.\r
-        * @param res\r
-        * @return\r
-        * @throws DatabaseException\r
-        */\r
-       public static File toTempFile(final Resource res)throws DatabaseException {\r
-               return Simantics.getSession().syncRequest(new Read<File>() {\r
-                       @Override\r
-                       public File perform(ReadGraph graph) throws DatabaseException {\r
-                               return toTempFile(graph, res);\r
-                       }\r
-               });\r
-       }\r
-\r
-       /**\r
-        * Creates a temp file of a graphFile.\r
-        * @param graph\r
-        * @param res\r
-        * @return\r
-        * @throws DatabaseException\r
-        */\r
-       public static File toTempFile(ReadGraph graph, Resource res)throws DatabaseException {\r
-\r
-               GraphFileResource gf = GraphFileResource.getInstance(graph);\r
-               String filename = graph.getRelatedValue(res, gf.HasResourceName);\r
-               \r
-               int index = filename.lastIndexOf(".");\r
-               String name = "";\r
-               String ext = "";\r
-               if (index > 0) {\r
-                       name = filename.substring(0,index);\r
-                       ext = filename.substring(index+1);\r
-               } else {\r
-                       name = filename;\r
-               }\r
-               if (name.length() < 3) {\r
-                       for (int i = name.length(); i < 3; i++)\r
-                               name += "_";\r
-               }\r
-               try {\r
-                       File file = File.createTempFile(name, "."+ ext);\r
-                       writeDataToFile(graph, res, file);\r
-                       return file;\r
-               } catch (Exception e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-       }\r
-       \r
-       public static void writeDataToFile(final Resource res, final File file) throws DatabaseException{\r
-               Simantics.getSession().syncRequest(new ReadRequest() {\r
-                       \r
-                       @Override\r
-                       public void run(ReadGraph graph) throws DatabaseException {\r
-                               try {\r
-                                       writeDataToFile(graph, res, file);\r
-                               } catch (IOException e) {\r
-                                       throw new DatabaseException(e);\r
-                               }\r
-                       }\r
-               });\r
-       }\r
-       \r
-       /**\r
-        * Writes contents of a graphFile to file.\r
-        * @param graph\r
-        * @param res\r
-        * @param file\r
-        * @throws DatabaseException\r
-        * @throws IOException\r
-        */\r
-       public static void writeDataToFile(ReadGraph graph, Resource res, File file) throws DatabaseException, IOException {\r
-               \r
-               GraphFileResource gf = GraphFileResource.getInstance(graph);\r
-               if (USE_RANDOM_ACCESS_BINARY) {\r
-                       Resource filedata = graph.getSingleObject(res, gf.HasFiledata);\r
-                       LiteralFileUtil.copyRandomAccessBinaryToFile(graph, filedata, file);\r
-               } else {\r
-               \r
-                       byte[] data = graph.getRelatedValue(res, gf.HasFiledata);\r
-                       FileOutputStream fos = new FileOutputStream(file);\r
-                       fos.write(data);\r
-                       fos.flush();\r
-                       fos.close();\r
-               \r
-               }\r
-               Long lastModified = graph.getPossibleRelatedValue(res, gf.LastModified);\r
-               if (lastModified != null)\r
-                       file.setLastModified(lastModified);\r
-       }\r
-\r
-       /**\r
-        * Updates contents of a graphFile, including the name.\r
-        * @param filename\r
-        * @param graphFile\r
-        * @throws DatabaseException\r
-        */\r
-       public static void toGraph(final String filename, final Resource graphFile)throws DatabaseException {\r
-               Simantics.getSession().syncRequest(new WriteRequest() {\r
-                       @Override\r
-                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                               try {\r
-                                       toGraph(graph, filename,graphFile);\r
-                               } catch (IOException e) {\r
-                                       throw new DatabaseException(e);\r
-                               }\r
-                       }\r
-               });\r
-       }\r
-       \r
-       /**\r
-        * Updates contents of a graphFile, including the name.\r
-        * @param graph\r
-        * @param filename\r
-        * @param graphFile\r
-        * @throws DatabaseException\r
-        * @throws IOException\r
-        */\r
-       public static void toGraph(WriteGraph graph, String filename, Resource graphFile) throws DatabaseException, IOException {\r
-               File file = new File(filename);\r
-               if (!file.exists())\r
-                       throw new IOException("File " + filename + " not found.");\r
-               \r
-               toGraph(graph, file, graphFile);\r
-       }\r
-       \r
-       /**\r
-        * Updates contents of a graphFile, including the name.\r
-        * @param graph\r
-        * @param file\r
-        * @param graphFile\r
-        * @throws DatabaseException\r
-        * @throws IOException\r
-        */\r
-       public static void toGraph(WriteGraph graph, File file, Resource graphFile) throws DatabaseException, IOException {\r
-\r
-               writeDataToGraph(graph, file, graphFile);\r
-               String name = file.getName();\r
-               GraphFileResource gf = GraphFileResource.getInstance(graph);\r
-               graph.claimLiteral(graphFile, gf.HasResourceName, name);\r
-               \r
-       }\r
-       \r
-       /**\r
-        * Writes contents of a file to a graphFile (data and time stamp).\r
-        * @param graph\r
-        * @param file\r
-        * @param graphFile\r
-        * @throws IOException\r
-        * @throws ManyObjectsForFunctionalRelationException\r
-        * @throws ServiceException\r
-        */\r
-       public static void writeDataToGraph(WriteGraph graph, File file, Resource graphFile) throws IOException, DatabaseException{\r
-               GraphFileResource gf = GraphFileResource.getInstance(graph);\r
-               if (USE_RANDOM_ACCESS_BINARY) {\r
-                       \r
-                       Resource fileData = graph.getPossibleObject(graphFile, gf.HasFiledata);\r
-                       RandomAccessBinary rab = null;\r
-                       if (fileData == null) {\r
-                               Layer0 l0 = Layer0.getInstance(graph);\r
-                               ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
-                               fileData = graph.newResource(cs.createCluster());\r
-                               graph.claim(fileData, l0.InstanceOf, l0.ByteArray);\r
-                               graph.claim(graphFile, gf.HasFiledata, fileData);\r
-                               rab = graph.createRandomAccessBinary(fileData, Bindings.BYTE_ARRAY.type(), null);\r
-                       } else {\r
-                               rab = graph.getRandomAccessBinary(fileData);\r
-                       }\r
-                       LiteralFileUtil.copyRandomAccessBinaryFromFile(file, rab);\r
-               } else {\r
-                       FileInputStream stream = new FileInputStream(file);\r
-                       FileChannel chan = stream.getChannel();\r
-                       long lsize = chan.size();\r
-                       if (lsize > Integer.MAX_VALUE)\r
-                               throw new IOException("File is too big");\r
-                       int size = (int)lsize;\r
-                       final byte[] array = new byte[size];\r
-                       ByteBuffer buf = ByteBuffer.wrap(array);\r
-                       while (size > 0)\r
-                               size -= chan.read(buf);\r
-                       \r
-                       graph.claimLiteral(graphFile, gf.HasFiledata, array);\r
-                       chan.close();\r
-                       stream.close();\r
-               }\r
-\r
-               graph.claimLiteral(graphFile, gf.LastModified, file.lastModified());\r
-               \r
-       }\r
-       \r
-       public static void writeDataToGraph(WriteGraph graph, byte data[], Resource graphFile) throws IOException, DatabaseException {\r
-               GraphFileResource gf = GraphFileResource.getInstance(graph);\r
-               if (USE_RANDOM_ACCESS_BINARY) {\r
-                       Resource fileData = graph.getPossibleObject(graphFile, gf.HasFiledata);\r
-                       if (fileData == null) {\r
-                               Layer0 l0 = Layer0.getInstance(graph);\r
-                               ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
-                               fileData = graph.newResource(cs.createCluster());\r
-                               graph.claim(fileData, l0.InstanceOf, l0.ByteArray);\r
-                               graph.claim(graphFile, gf.HasFiledata, fileData);\r
-                               graph.createRandomAccessBinary(fileData, Bindings.BYTE_ARRAY.type(), data);\r
-                       } else {\r
-                               InputStream input = new ByteArrayInputStream(data);\r
-                               LiteralFileUtil.copyStreamToRandomAccessBinary(graph, input, fileData);\r
-                       }\r
-               } else {\r
-                       graph.claimLiteral(graphFile, gf.HasFiledata, data);\r
-               }\r
-               graph.claimLiteral(graphFile, gf.LastModified, System.currentTimeMillis());\r
-       }\r
-       \r
-       /**\r
-        * Writes contents of a file to a graphFile (data and time stamp).\r
-        * @param file\r
-        * @param graphFile\r
-        * @throws DatabaseException\r
-        */\r
-       public static void writeDataToGraph(final File file, final Resource graphFile) throws DatabaseException {\r
-               Simantics.getSession().syncRequest(new WriteRequest() {\r
-                       \r
-                       @Override\r
-                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                               try {\r
-                                       writeDataToGraph(graph, file, graphFile);\r
-                               } catch (IOException e) {\r
-                                       throw new DatabaseException(e);\r
-                               }\r
-                               \r
-                       }\r
-               });\r
-       }\r
-       \r
-       public static void syncFolderToGraph(WriteGraph g, File folder, Resource folderRes) throws Exception {\r
-               File subFiles[] = folder.listFiles();\r
-               Layer0 l0 = Layer0.getInstance(g);\r
-               GraphFileResource gf = GraphFileResource.getInstance(g);\r
-               Collection<Resource> subFileResources = g.getObjects(folderRes, gf.HasFile);\r
-               Collection<Resource> subFolderResources = g.getObjects(folderRes, gf.HasFolder);\r
-                               \r
-               Map<Resource,File> matching = new HashMap<Resource, File>();\r
-               \r
-               for (File f : subFiles) {\r
-                       String name = f.getName();\r
-                       if (f.isDirectory()) {\r
-                               Resource matchingFolder = findWithName(g, subFolderResources, name);\r
-\r
-                               if (matchingFolder != null) {\r
-                                       if (matching.containsKey(matchingFolder))\r
-                                               throw new Exception("Matching folder already in use" + f.getAbsolutePath() + " " + matchingFolder);\r
-                                       \r
-                                       matching.put(matchingFolder, f);\r
-                                       syncFolderToGraph(g, f, matchingFolder);\r
-                               } else {\r
-                                       matchingFolder = g.newResource();\r
-                                       g.claim(matchingFolder, l0.InstanceOf, gf.Folder);\r
-                                       g.claimLiteral(matchingFolder, gf.HasResourceName, name);\r
-                                       g.claimLiteral(matchingFolder, l0.HasName, name);\r
-                                       g.claim(folderRes, gf.HasFolder, matchingFolder);\r
-                                       matching.put(matchingFolder, f);\r
-                                       syncFolderToGraph(g, f, matchingFolder);\r
-                               }\r
-                       } else { //file\r
-                               Resource fileRes = findWithName(g, subFileResources, name);\r
-                               if (fileRes != null) {\r
-                                       if (matching.containsKey(fileRes))\r
-                                               throw new Exception("Matching file already in use" + f.getAbsolutePath() + " " + fileRes);\r
-                                       matching.put(fileRes, f);\r
-                                       toGraph(g, f, fileRes);\r
-                               } else {\r
-                                       fileRes = g.newResource();\r
-                                       g.claim(fileRes, l0.InstanceOf, gf.File);\r
-                                       g.claimLiteral(fileRes, gf.HasResourceName, name);\r
-                                       g.claimLiteral(fileRes, l0.HasName, name);\r
-                                       g.claim(folderRes, gf.HasFile, fileRes);\r
-                                       matching.put(fileRes, f);\r
-                                       toGraph(g, f, fileRes);\r
-                               }\r
-                       }\r
-               }\r
-               // delete resources, which have no matching file (or folder)\r
-               for (Resource subFolder : subFolderResources) {\r
-                       if (!matching.containsKey(subFolder))\r
-                               g.deny(subFolder);\r
-               }\r
-               \r
-               for (Resource subFolder : subFileResources) {\r
-                       if (!matching.containsKey(subFolder))\r
-                               g.deny(subFolder);\r
-               }\r
-       }\r
-       \r
-       public static void writeFolderToDisk(ReadGraph g, Resource folderRes, File folder) throws DatabaseException, IOException{\r
-\r
-               GraphFileResource gf = GraphFileResource.getInstance(g);\r
-               for (Resource subFolder : g.getObjects(folderRes, gf.HasFolder)) {\r
-                       String name = g.getRelatedValue(subFolder, gf.HasResourceName);\r
-\r
-                       if (name.length() == 0)\r
-                               throw new DatabaseException("Empty folder name for " + subFolder);\r
-                       \r
-                       File newFolder = new File(folder.getAbsolutePath() + "/" + name);\r
-                       if (!newFolder.mkdir()) {\r
-                               throw new DatabaseException("Could not create folder " + name + " for resource " + subFolder);\r
-                       }\r
-                       writeFolderToDisk(g, subFolder, newFolder);\r
-               }\r
-               for (Resource fileRes : g.getObjects(folderRes, gf.HasFile)) {\r
-                       String name = g.getRelatedValue(fileRes, gf.HasResourceName);\r
-                       File file = new File(folder.getAbsolutePath() + "/" + name);\r
-                       writeDataToFile(g, fileRes, file);\r
-               }\r
-       }\r
-       \r
-       public static void syncFolderToGraph(WriteGraph g, File folder, Resource folderRes, ToGraphHelper helper) throws Exception {\r
-               File subFiles[] = folder.listFiles();\r
-               GraphFileResource gf = GraphFileResource.getInstance(g);\r
-               Collection<Resource> subFileResources = g.getObjects(folderRes, gf.HasFile);\r
-               Collection<Resource> subFolderResources = g.getObjects(folderRes, gf.HasFolder);\r
-                               \r
-               Map<Resource,File> matching = new HashMap<Resource, File>();\r
-               \r
-               for (File f : subFiles) {\r
-                       String name = f.getName();\r
-                       if (f.isDirectory()) {\r
-                               Resource matchingFolder = helper.findFolder(g, subFolderResources, name);\r
-\r
-                               if (matchingFolder != null) {\r
-                                       if (matching.containsKey(matchingFolder))\r
-                                               throw new Exception("Matching folder already in use" + f.getAbsolutePath() + " " + matchingFolder);\r
-                                       \r
-                                       matching.put(matchingFolder, f);\r
-                                       syncFolderToGraph(g, f, matchingFolder,helper);\r
-                               } else {\r
-                                       matchingFolder = helper.createFolder(g, name);\r
-                                       g.claim(folderRes, gf.HasFolder, matchingFolder);\r
-                                       matching.put(matchingFolder, f);\r
-                                       syncFolderToGraph(g, f, matchingFolder,helper);\r
-                               }\r
-                       } else { //file\r
-                               Resource fileRes = helper.findFile(g, subFileResources, name);\r
-                               if (fileRes != null) {\r
-                                       if (matching.containsKey(fileRes))\r
-                                               throw new Exception("Matching file already in use" + f.getAbsolutePath() + " " + fileRes);\r
-                                       matching.put(fileRes, f);\r
-                                       toGraph(g, f, fileRes);\r
-                               } else {\r
-                                       fileRes = helper.createFile(g, name);\r
-                                       g.claim(folderRes, gf.HasFile, fileRes);\r
-                                       matching.put(fileRes, f);\r
-                                       toGraph(g, f, fileRes);\r
-                               }\r
-                       }\r
-               }\r
-               // delete resources, which have no matching file (or folder)\r
-               for (Resource subFolder : subFolderResources) {\r
-                       if (!matching.containsKey(subFolder))\r
-                               g.deny(subFolder);\r
-               }\r
-               \r
-               for (Resource subFolder : subFileResources) {\r
-                       if (!matching.containsKey(subFolder))\r
-                               g.deny(subFolder);\r
-               }\r
-       }\r
-       \r
-       public static interface ToGraphHelper {\r
-               public Resource findFolder(ReadGraph g, Collection<Resource> subFolderResources, String name) throws DatabaseException;\r
-               public Resource createFolder(WriteGraph g, String name) throws DatabaseException;\r
-               public Resource findFile(ReadGraph g, Collection<Resource> subFileResources, String name) throws DatabaseException;\r
-               public Resource createFile(WriteGraph g, String name) throws DatabaseException;\r
-       }\r
-       \r
-       public static interface ToDiskHelper {\r
-               public String getName(ReadGraph g, Resource systemResource) throws DatabaseException;\r
-       }\r
-       \r
-       public static void writeFolderToDisk(ReadGraph g, Resource folderRes, File folder, ToDiskHelper helper) throws DatabaseException, IOException{\r
-               GraphFileResource gf = GraphFileResource.getInstance(g);\r
-               for (Resource subFolder : g.getObjects(folderRes, gf.HasFolder)) {\r
-                       String name = helper.getName(g, subFolder);\r
-\r
-                       if (name.length() == 0)\r
-                               throw new DatabaseException("Empty folder name for " + subFolder);\r
-                       \r
-                       File newFolder = new File(folder.getAbsolutePath() + "/" + name);\r
-                       if (!newFolder.mkdir()) {\r
-                               throw new DatabaseException("Could not create folder " + name + " for resource " + subFolder);\r
-                       }\r
-                       writeFolderToDisk(g, subFolder, newFolder, helper);\r
-               }\r
-               for (Resource fileRes : g.getObjects(folderRes, gf.HasFile)) {\r
-                       String name = helper.getName(g, fileRes);\r
-                       File file = new File(folder.getAbsolutePath() + "/" + name);\r
-                       writeDataToFile(g, fileRes, file);\r
-               }\r
-       }\r
-       \r
-       public static interface ToDiskHelper2 extends ToDiskHelper {\r
-               public Resource findFolder(ReadGraph g, Collection<Resource> subFolderResources, String name) throws DatabaseException;\r
-               public Resource findFile(ReadGraph g, Collection<Resource> subFileResources, String name) throws DatabaseException;\r
-       }\r
-       \r
-       public static void syncFolderToDisk(ReadGraph g, Resource folderRes, File folder, ToDiskHelper2 helper) throws Exception {\r
-               File subFiles[] = folder.listFiles();\r
-               GraphFileResource gf = GraphFileResource.getInstance(g);\r
-               Collection<Resource> subFileResources = g.getObjects(folderRes, gf.HasFile);\r
-               Collection<Resource> subFolderResources = g.getObjects(folderRes, gf.HasFolder);\r
-                               \r
-               Map<Resource,File> matching = new HashMap<Resource, File>();\r
-               \r
-               for (File f : subFiles) {\r
-                       String name = f.getName();\r
-                       if (f.isDirectory()) {\r
-                               Resource matchingFolder = helper.findFolder(g, subFolderResources, name);\r
-\r
-                               if (matchingFolder != null) {\r
-                                       if (matching.containsKey(matchingFolder))\r
-                                               throw new Exception("Matching folder already in use" + f.getAbsolutePath() + " " + matchingFolder);\r
-                                       \r
-                                       matching.put(matchingFolder, f);\r
-                                       syncFolderToDisk(g, matchingFolder, f, helper);\r
-                               } else {\r
-                                       deleteDirectoryStructure(f);\r
-                               }\r
-                       } else { //file\r
-                               Resource fileRes = helper.findFile(g, subFileResources, name);\r
-                               if (fileRes != null) {\r
-                                       if (matching.containsKey(fileRes))\r
-                                               throw new Exception("Matching file already in use" + f.getAbsolutePath() + " " + fileRes);\r
-                                       matching.put(fileRes, f);\r
-                                       writeDataToFile(g, fileRes, f);\r
-                               } else {\r
-                                       if (!f.delete())\r
-                                       throw new Exception("Cannot delete file " + f.getAbsolutePath());\r
-                               }\r
-                       }\r
-               }\r
-               // create files and folders, which have no matching graphFile (or folder)\r
-               for (Resource subFolder : subFolderResources) {\r
-                       if (!matching.containsKey(subFolder)) {\r
-                               String name = helper.getName(g, subFolder);\r
-\r
-                               if (name.length() == 0)\r
-                                       throw new DatabaseException("Empty folder name for " + subFolder);\r
-                               \r
-                               File newFolder = new File(folder.getAbsolutePath() + "/" + name);\r
-                               if (!newFolder.mkdir()) {\r
-                                       throw new DatabaseException("Could not create folder " + name + " for resource " + subFolder);\r
-                               }\r
-                               writeFolderToDisk(g, subFolder, newFolder, helper);\r
-                       }\r
-               }\r
-               \r
-               for (Resource fileRes : subFileResources) {\r
-                       if (!matching.containsKey(fileRes)) {\r
-                               String name = helper.getName(g, fileRes);\r
-                               File file = new File(folder.getAbsolutePath() + "/" + name);\r
-                               writeDataToFile(g, fileRes, file);\r
-                       }\r
-               }\r
-               \r
-       }\r
-       \r
-       \r
-       \r
-       public static Resource findWithName(ReadGraph g, Collection<Resource> resources, String name) throws ServiceException, NoSingleResultException, DoesNotContainValueException {\r
-               GraphFileResource gf = GraphFileResource.getInstance(g);\r
-               for (Resource r : resources)\r
-                       if (name.equals(g.getRelatedValue(r, gf.HasResourceName)))\r
-                               return r;\r
-               return null;\r
-       }\r
-       \r
-       /**\r
-        * Deletes the directory and all it contents.\r
-        * @param dir\r
-        * @throws Exception\r
-        */\r
-       public static void deleteDirectoryStructure(File dir) throws Exception{\r
-               deleteDirectoryStructure(dir, true);\r
-       }\r
-       \r
-       /**\r
-        * Deletes the directory's contents, but does not delete the directory.\r
-        * @param dir\r
-        * @throws Exception\r
-        */\r
-       public static void clearDirectoryStructure(File dir) throws Exception{\r
-               deleteDirectoryStructure(dir, false);\r
-       }\r
-       \r
-       private static void deleteDirectoryStructure(File dir, boolean deleteDir) throws Exception{\r
-               File subFiles[] = dir.listFiles();\r
-               for (File f : subFiles) {\r
-                       if (f.isDirectory())\r
-                               deleteDirectoryStructure(f,true);\r
-                       else\r
-                               if (!f.delete()) {\r
-                                       throw new Exception("Cannot delete file " + f.getAbsolutePath());\r
-                               }\r
-               }\r
-               if (deleteDir) {\r
-                       if (!dir.delete()) {\r
-                               throw new Exception("Cannot delete folder " + dir.getAbsolutePath());\r
-                       }\r
-               }\r
-       }\r
-\r
-    public static Resource createFileReference(final Resource parent, final Path path) throws DatabaseException {\r
-        return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {\r
-\r
-            @Override\r
-            public Resource perform(WriteGraph graph) throws DatabaseException {\r
-                Layer0 L0 = Layer0.getInstance(graph);\r
-                GraphFileResource GF = GraphFileResource.getInstance(graph);\r
-                Resource file = graph.newResource();\r
-                graph.claim(file, L0.PartOf, parent);\r
-                graph.claim(file, L0.InstanceOf, GF.File);\r
-                String name = path.getFileName().toString();\r
-                graph.claimLiteral(file, L0.HasName, name, Bindings.STRING);\r
-                graph.claimLiteral(file, GF.SystemPath, path.toAbsolutePath().toString(), Bindings.STRING);\r
-                return file;\r
-            }\r
-        });\r
-    }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2013 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.graphfile.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.util.binary.RandomAccessBinary;
+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.common.utils.LiteralFileUtil;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.DoesNotContainValueException;
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
+import org.simantics.db.exception.NoSingleResultException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.db.request.Read;
+import org.simantics.db.service.ClusteringSupport;
+import org.simantics.graphfile.ontology.GraphFileResource;
+import org.simantics.layer0.Layer0;
+
+/**
+ * @author Marko Luukkainen
+ */
+public class GraphFileUtil {
+       
+       
+       public static boolean USE_RANDOM_ACCESS_BINARY = true;
+       /**
+        * Creates a temp file of a graphFile.
+        * @param res
+        * @return
+        * @throws DatabaseException
+        */
+       public static File toTempFile(final Resource res)throws DatabaseException {
+               return Simantics.getSession().syncRequest(new Read<File>() {
+                       @Override
+                       public File perform(ReadGraph graph) throws DatabaseException {
+                               return toTempFile(graph, res);
+                       }
+               });
+       }
+
+       /**
+        * Creates a temp file of a graphFile.
+        * @param graph
+        * @param res
+        * @return
+        * @throws DatabaseException
+        */
+       public static File toTempFile(ReadGraph graph, Resource res)throws DatabaseException {
+
+               GraphFileResource gf = GraphFileResource.getInstance(graph);
+               String filename = graph.getPossibleRelatedValue(res, gf.HasResourceName);
+               if (filename == null)
+                   filename = graph.getRelatedValue(res, Layer0.getInstance(graph).HasName);
+               
+               int index = filename.lastIndexOf(".");
+               String name = "";
+               String ext = "";
+               if (index > 0) {
+                       name = filename.substring(0,index);
+                       ext = filename.substring(index+1);
+               } else {
+                       name = filename;
+               }
+               if (name.length() < 3) {
+                       for (int i = name.length(); i < 3; i++)
+                               name += "_";
+               }
+               try {
+                       File file = File.createTempFile(name, "."+ ext);
+                       writeDataToFile(graph, res, file);
+                       return file;
+               } catch (Exception e) {
+                       throw new DatabaseException(e);
+               }
+       }
+       
+       public static void writeDataToFile(final Resource res, final File file) throws DatabaseException{
+               Simantics.getSession().syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               try {
+                                       writeDataToFile(graph, res, file);
+                               } catch (IOException e) {
+                                       throw new DatabaseException(e);
+                               }
+                       }
+               });
+       }
+       
+       /**
+        * Writes contents of a graphFile to file.
+        * @param graph
+        * @param res
+        * @param file
+        * @throws DatabaseException
+        * @throws IOException
+        */
+       public static void writeDataToFile(ReadGraph graph, Resource res, File file) throws DatabaseException, IOException {
+               
+               GraphFileResource gf = GraphFileResource.getInstance(graph);
+               if (USE_RANDOM_ACCESS_BINARY) {
+                       Resource filedata = graph.getSingleObject(res, gf.HasFiledata);
+                       LiteralFileUtil.copyRandomAccessBinaryToFile(graph, filedata, file);
+               } else {
+               
+                       byte[] data = graph.getRelatedValue(res, gf.HasFiledata);
+                       FileOutputStream fos = new FileOutputStream(file);
+                       fos.write(data);
+                       fos.flush();
+                       fos.close();
+               
+               }
+               Long lastModified = graph.getPossibleRelatedValue(res, gf.LastModified);
+               if (lastModified != null)
+                       file.setLastModified(lastModified);
+       }
+
+       /**
+        * Updates contents of a graphFile, including the name.
+        * @param filename
+        * @param graphFile
+        * @throws DatabaseException
+        */
+       public static void toGraph(final String filename, final Resource graphFile)throws DatabaseException {
+               Simantics.getSession().syncRequest(new WriteRequest() {
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+                               try {
+                                       toGraph(graph, filename,graphFile);
+                               } catch (IOException e) {
+                                       throw new DatabaseException(e);
+                               }
+                       }
+               });
+       }
+       
+       /**
+        * Updates contents of a graphFile, including the name.
+        * @param graph
+        * @param filename
+        * @param graphFile
+        * @throws DatabaseException
+        * @throws IOException
+        */
+       public static void toGraph(WriteGraph graph, String filename, Resource graphFile) throws DatabaseException, IOException {
+               File file = new File(filename);
+               if (!file.exists())
+                       throw new IOException("File " + filename + " not found.");
+               
+               toGraph(graph, file, graphFile);
+       }
+       
+       /**
+        * Updates contents of a graphFile, including the name.
+        * @param graph
+        * @param file
+        * @param graphFile
+        * @throws DatabaseException
+        * @throws IOException
+        */
+       public static void toGraph(WriteGraph graph, File file, Resource graphFile) throws DatabaseException, IOException {
+
+               writeDataToGraph(graph, file, graphFile);
+               String name = file.getName();
+               GraphFileResource gf = GraphFileResource.getInstance(graph);
+               graph.claimLiteral(graphFile, gf.HasResourceName, name);
+               
+       }
+       
+       /**
+        * Writes contents of a file to a graphFile (data and time stamp).
+        * @param graph
+        * @param file
+        * @param graphFile
+        * @throws IOException
+        * @throws ManyObjectsForFunctionalRelationException
+        * @throws ServiceException
+        */
+       public static void writeDataToGraph(WriteGraph graph, File file, Resource graphFile) throws IOException, DatabaseException{
+               GraphFileResource gf = GraphFileResource.getInstance(graph);
+               if (USE_RANDOM_ACCESS_BINARY) {
+                       
+                       Resource fileData = graph.getPossibleObject(graphFile, gf.HasFiledata);
+                       RandomAccessBinary rab = null;
+                       if (fileData == null) {
+                               Layer0 l0 = Layer0.getInstance(graph);
+                               ClusteringSupport cs = graph.getService(ClusteringSupport.class);
+                               fileData = graph.newResource(cs.createCluster());
+                               graph.claim(fileData, l0.InstanceOf, l0.ByteArray);
+                               graph.claim(graphFile, gf.HasFiledata, fileData);
+                               rab = graph.createRandomAccessBinary(fileData, Bindings.BYTE_ARRAY.type(), null);
+                       } else {
+                               rab = graph.getRandomAccessBinary(fileData);
+                       }
+                       LiteralFileUtil.copyRandomAccessBinaryFromFile(file, rab);
+               } else {
+                       FileInputStream stream = new FileInputStream(file);
+                       FileChannel chan = stream.getChannel();
+                       long lsize = chan.size();
+                       if (lsize > Integer.MAX_VALUE)
+                               throw new IOException("File is too big");
+                       int size = (int)lsize;
+                       final byte[] array = new byte[size];
+                       ByteBuffer buf = ByteBuffer.wrap(array);
+                       while (size > 0)
+                               size -= chan.read(buf);
+                       
+                       graph.claimLiteral(graphFile, gf.HasFiledata, array);
+                       chan.close();
+                       stream.close();
+               }
+
+               graph.claimLiteral(graphFile, gf.LastModified, file.lastModified());
+               
+       }
+       
+       public static void writeDataToGraph(WriteGraph graph, byte data[], Resource graphFile) throws IOException, DatabaseException {
+               GraphFileResource gf = GraphFileResource.getInstance(graph);
+               if (USE_RANDOM_ACCESS_BINARY) {
+                       Resource fileData = graph.getPossibleObject(graphFile, gf.HasFiledata);
+                       if (fileData == null) {
+                               Layer0 l0 = Layer0.getInstance(graph);
+                               ClusteringSupport cs = graph.getService(ClusteringSupport.class);
+                               fileData = graph.newResource(cs.createCluster());
+                               graph.claim(fileData, l0.InstanceOf, l0.ByteArray);
+                               graph.claim(graphFile, gf.HasFiledata, fileData);
+                               graph.createRandomAccessBinary(fileData, Bindings.BYTE_ARRAY.type(), data);
+                       } else {
+                               InputStream input = new ByteArrayInputStream(data);
+                               LiteralFileUtil.copyStreamToRandomAccessBinary(graph, input, fileData);
+                       }
+               } else {
+                       graph.claimLiteral(graphFile, gf.HasFiledata, data);
+               }
+               graph.claimLiteral(graphFile, gf.LastModified, System.currentTimeMillis());
+       }
+       
+       /**
+        * Writes contents of a file to a graphFile (data and time stamp).
+        * @param file
+        * @param graphFile
+        * @throws DatabaseException
+        */
+       public static void writeDataToGraph(final File file, final Resource graphFile) throws DatabaseException {
+               Simantics.getSession().syncRequest(new WriteRequest() {
+                       
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+                               try {
+                                       writeDataToGraph(graph, file, graphFile);
+                               } catch (IOException e) {
+                                       throw new DatabaseException(e);
+                               }
+                               
+                       }
+               });
+       }
+       
+       public static void syncFolderToGraph(WriteGraph g, File folder, Resource folderRes) throws Exception {
+               File subFiles[] = folder.listFiles();
+               Layer0 l0 = Layer0.getInstance(g);
+               GraphFileResource gf = GraphFileResource.getInstance(g);
+               Collection<Resource> subFileResources = g.getObjects(folderRes, gf.HasFile);
+               Collection<Resource> subFolderResources = g.getObjects(folderRes, gf.HasFolder);
+                               
+               Map<Resource,File> matching = new HashMap<Resource, File>();
+               
+               for (File f : subFiles) {
+                       String name = f.getName();
+                       if (f.isDirectory()) {
+                               Resource matchingFolder = findWithName(g, subFolderResources, name);
+
+                               if (matchingFolder != null) {
+                                       if (matching.containsKey(matchingFolder))
+                                               throw new Exception("Matching folder already in use" + f.getAbsolutePath() + " " + matchingFolder);
+                                       
+                                       matching.put(matchingFolder, f);
+                                       syncFolderToGraph(g, f, matchingFolder);
+                               } else {
+                                       matchingFolder = g.newResource();
+                                       g.claim(matchingFolder, l0.InstanceOf, gf.Folder);
+                                       g.claimLiteral(matchingFolder, gf.HasResourceName, name);
+                                       g.claimLiteral(matchingFolder, l0.HasName, name);
+                                       g.claim(folderRes, gf.HasFolder, matchingFolder);
+                                       matching.put(matchingFolder, f);
+                                       syncFolderToGraph(g, f, matchingFolder);
+                               }
+                       } else { //file
+                               Resource fileRes = findWithName(g, subFileResources, name);
+                               if (fileRes != null) {
+                                       if (matching.containsKey(fileRes))
+                                               throw new Exception("Matching file already in use" + f.getAbsolutePath() + " " + fileRes);
+                                       matching.put(fileRes, f);
+                                       toGraph(g, f, fileRes);
+                               } else {
+                                       fileRes = g.newResource();
+                                       g.claim(fileRes, l0.InstanceOf, gf.File);
+                                       g.claimLiteral(fileRes, gf.HasResourceName, name);
+                                       g.claimLiteral(fileRes, l0.HasName, name);
+                                       g.claim(folderRes, gf.HasFile, fileRes);
+                                       matching.put(fileRes, f);
+                                       toGraph(g, f, fileRes);
+                               }
+                       }
+               }
+               // delete resources, which have no matching file (or folder)
+               for (Resource subFolder : subFolderResources) {
+                       if (!matching.containsKey(subFolder))
+                               g.deny(subFolder);
+               }
+               
+               for (Resource subFolder : subFileResources) {
+                       if (!matching.containsKey(subFolder))
+                               g.deny(subFolder);
+               }
+       }
+       
+       public static void writeFolderToDisk(ReadGraph g, Resource folderRes, File folder) throws DatabaseException, IOException{
+
+               GraphFileResource gf = GraphFileResource.getInstance(g);
+               for (Resource subFolder : g.getObjects(folderRes, gf.HasFolder)) {
+                       String name = g.getRelatedValue(subFolder, gf.HasResourceName);
+
+                       if (name.length() == 0)
+                               throw new DatabaseException("Empty folder name for " + subFolder);
+                       
+                       File newFolder = new File(folder.getAbsolutePath() + "/" + name);
+                       if (!newFolder.mkdir()) {
+                               throw new DatabaseException("Could not create folder " + name + " for resource " + subFolder);
+                       }
+                       writeFolderToDisk(g, subFolder, newFolder);
+               }
+               for (Resource fileRes : g.getObjects(folderRes, gf.HasFile)) {
+                       String name = g.getRelatedValue(fileRes, gf.HasResourceName);
+                       File file = new File(folder.getAbsolutePath() + "/" + name);
+                       writeDataToFile(g, fileRes, file);
+               }
+       }
+       
+       public static void syncFolderToGraph(WriteGraph g, File folder, Resource folderRes, ToGraphHelper helper) throws Exception {
+               File subFiles[] = folder.listFiles();
+               GraphFileResource gf = GraphFileResource.getInstance(g);
+               Collection<Resource> subFileResources = g.getObjects(folderRes, gf.HasFile);
+               Collection<Resource> subFolderResources = g.getObjects(folderRes, gf.HasFolder);
+                               
+               Map<Resource,File> matching = new HashMap<Resource, File>();
+               
+               for (File f : subFiles) {
+                       String name = f.getName();
+                       if (f.isDirectory()) {
+                               Resource matchingFolder = helper.findFolder(g, subFolderResources, name);
+
+                               if (matchingFolder != null) {
+                                       if (matching.containsKey(matchingFolder))
+                                               throw new Exception("Matching folder already in use" + f.getAbsolutePath() + " " + matchingFolder);
+                                       
+                                       matching.put(matchingFolder, f);
+                                       syncFolderToGraph(g, f, matchingFolder,helper);
+                               } else {
+                                       matchingFolder = helper.createFolder(g, name);
+                                       g.claim(folderRes, gf.HasFolder, matchingFolder);
+                                       matching.put(matchingFolder, f);
+                                       syncFolderToGraph(g, f, matchingFolder,helper);
+                               }
+                       } else { //file
+                               Resource fileRes = helper.findFile(g, subFileResources, name);
+                               if (fileRes != null) {
+                                       if (matching.containsKey(fileRes))
+                                               throw new Exception("Matching file already in use" + f.getAbsolutePath() + " " + fileRes);
+                                       matching.put(fileRes, f);
+                                       toGraph(g, f, fileRes);
+                               } else {
+                                       fileRes = helper.createFile(g, name);
+                                       g.claim(folderRes, gf.HasFile, fileRes);
+                                       matching.put(fileRes, f);
+                                       toGraph(g, f, fileRes);
+                               }
+                       }
+               }
+               // delete resources, which have no matching file (or folder)
+               for (Resource subFolder : subFolderResources) {
+                       if (!matching.containsKey(subFolder))
+                               g.deny(subFolder);
+               }
+               
+               for (Resource subFolder : subFileResources) {
+                       if (!matching.containsKey(subFolder))
+                               g.deny(subFolder);
+               }
+       }
+       
+       public static interface ToGraphHelper {
+               public Resource findFolder(ReadGraph g, Collection<Resource> subFolderResources, String name) throws DatabaseException;
+               public Resource createFolder(WriteGraph g, String name) throws DatabaseException;
+               public Resource findFile(ReadGraph g, Collection<Resource> subFileResources, String name) throws DatabaseException;
+               public Resource createFile(WriteGraph g, String name) throws DatabaseException;
+       }
+       
+       public static interface ToDiskHelper {
+               public String getName(ReadGraph g, Resource systemResource) throws DatabaseException;
+       }
+       
+       public static void writeFolderToDisk(ReadGraph g, Resource folderRes, File folder, ToDiskHelper helper) throws DatabaseException, IOException{
+               GraphFileResource gf = GraphFileResource.getInstance(g);
+               for (Resource subFolder : g.getObjects(folderRes, gf.HasFolder)) {
+                       String name = helper.getName(g, subFolder);
+
+                       if (name.length() == 0)
+                               throw new DatabaseException("Empty folder name for " + subFolder);
+                       
+                       File newFolder = new File(folder.getAbsolutePath() + "/" + name);
+                       if (!newFolder.mkdir()) {
+                               throw new DatabaseException("Could not create folder " + name + " for resource " + subFolder);
+                       }
+                       writeFolderToDisk(g, subFolder, newFolder, helper);
+               }
+               for (Resource fileRes : g.getObjects(folderRes, gf.HasFile)) {
+                       String name = helper.getName(g, fileRes);
+                       File file = new File(folder.getAbsolutePath() + "/" + name);
+                       writeDataToFile(g, fileRes, file);
+               }
+       }
+       
+       public static interface ToDiskHelper2 extends ToDiskHelper {
+               public Resource findFolder(ReadGraph g, Collection<Resource> subFolderResources, String name) throws DatabaseException;
+               public Resource findFile(ReadGraph g, Collection<Resource> subFileResources, String name) throws DatabaseException;
+       }
+       
+       public static void syncFolderToDisk(ReadGraph g, Resource folderRes, File folder, ToDiskHelper2 helper) throws Exception {
+               File subFiles[] = folder.listFiles();
+               GraphFileResource gf = GraphFileResource.getInstance(g);
+               Collection<Resource> subFileResources = g.getObjects(folderRes, gf.HasFile);
+               Collection<Resource> subFolderResources = g.getObjects(folderRes, gf.HasFolder);
+                               
+               Map<Resource,File> matching = new HashMap<Resource, File>();
+               
+               for (File f : subFiles) {
+                       String name = f.getName();
+                       if (f.isDirectory()) {
+                               Resource matchingFolder = helper.findFolder(g, subFolderResources, name);
+
+                               if (matchingFolder != null) {
+                                       if (matching.containsKey(matchingFolder))
+                                               throw new Exception("Matching folder already in use" + f.getAbsolutePath() + " " + matchingFolder);
+                                       
+                                       matching.put(matchingFolder, f);
+                                       syncFolderToDisk(g, matchingFolder, f, helper);
+                               } else {
+                                       deleteDirectoryStructure(f);
+                               }
+                       } else { //file
+                               Resource fileRes = helper.findFile(g, subFileResources, name);
+                               if (fileRes != null) {
+                                       if (matching.containsKey(fileRes))
+                                               throw new Exception("Matching file already in use" + f.getAbsolutePath() + " " + fileRes);
+                                       matching.put(fileRes, f);
+                                       writeDataToFile(g, fileRes, f);
+                               } else {
+                                       if (!f.delete())
+                                       throw new Exception("Cannot delete file " + f.getAbsolutePath());
+                               }
+                       }
+               }
+               // create files and folders, which have no matching graphFile (or folder)
+               for (Resource subFolder : subFolderResources) {
+                       if (!matching.containsKey(subFolder)) {
+                               String name = helper.getName(g, subFolder);
+
+                               if (name.length() == 0)
+                                       throw new DatabaseException("Empty folder name for " + subFolder);
+                               
+                               File newFolder = new File(folder.getAbsolutePath() + "/" + name);
+                               if (!newFolder.mkdir()) {
+                                       throw new DatabaseException("Could not create folder " + name + " for resource " + subFolder);
+                               }
+                               writeFolderToDisk(g, subFolder, newFolder, helper);
+                       }
+               }
+               
+               for (Resource fileRes : subFileResources) {
+                       if (!matching.containsKey(fileRes)) {
+                               String name = helper.getName(g, fileRes);
+                               File file = new File(folder.getAbsolutePath() + "/" + name);
+                               writeDataToFile(g, fileRes, file);
+                       }
+               }
+               
+       }
+       
+       
+       
+       public static Resource findWithName(ReadGraph g, Collection<Resource> resources, String name) throws ServiceException, NoSingleResultException, DoesNotContainValueException {
+               GraphFileResource gf = GraphFileResource.getInstance(g);
+               for (Resource r : resources)
+                       if (name.equals(g.getRelatedValue(r, gf.HasResourceName)))
+                               return r;
+               return null;
+       }
+       
+       /**
+        * Deletes the directory and all it contents.
+        * @param dir
+        * @throws Exception
+        */
+       public static void deleteDirectoryStructure(File dir) throws Exception{
+               deleteDirectoryStructure(dir, true);
+       }
+       
+       /**
+        * Deletes the directory's contents, but does not delete the directory.
+        * @param dir
+        * @throws Exception
+        */
+       public static void clearDirectoryStructure(File dir) throws Exception{
+               deleteDirectoryStructure(dir, false);
+       }
+       
+       private static void deleteDirectoryStructure(File dir, boolean deleteDir) throws Exception{
+               File subFiles[] = dir.listFiles();
+               for (File f : subFiles) {
+                       if (f.isDirectory())
+                               deleteDirectoryStructure(f,true);
+                       else
+                               if (!f.delete()) {
+                                       throw new Exception("Cannot delete file " + f.getAbsolutePath());
+                               }
+               }
+               if (deleteDir) {
+                       if (!dir.delete()) {
+                               throw new Exception("Cannot delete folder " + dir.getAbsolutePath());
+                       }
+               }
+       }
+
+    public static Resource createFileReference(final Resource parent, final Path path) throws DatabaseException {
+        return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
+
+            @Override
+            public Resource perform(WriteGraph graph) throws DatabaseException {
+                Layer0 L0 = Layer0.getInstance(graph);
+                GraphFileResource GF = GraphFileResource.getInstance(graph);
+                Resource file = graph.newResource();
+                graph.claim(file, L0.PartOf, parent);
+                graph.claim(file, L0.InstanceOf, GF.File);
+                String name = path.getFileName().toString();
+                graph.claimLiteral(file, L0.HasName, name, Bindings.STRING);
+                graph.claimLiteral(file, GF.SystemPath, path.toAbsolutePath().toString(), Bindings.STRING);
+                return file;
+            }
+        });
+    }
+}