X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.graphfile%2Fsrc%2Forg%2Fsimantics%2Fgraphfile%2Futil%2FGraphFileUtil.java;h=76003e023d778a1a73826152e715190400ac31ea;hp=9fdbf62c7b5ba4c96c5ce2d5fc5781de000496b6;hb=refs%2Fchanges%2F38%2F238%2F2;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java b/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java index 9fdbf62c7..76003e023 100644 --- a/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java +++ b/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java @@ -1,579 +1,579 @@ -/******************************************************************************* - * 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() { - @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.getRelatedValue(res, gf.HasResourceName); - - 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 subFileResources = g.getObjects(folderRes, gf.HasFile); - Collection subFolderResources = g.getObjects(folderRes, gf.HasFolder); - - Map matching = new HashMap(); - - 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 subFileResources = g.getObjects(folderRes, gf.HasFile); - Collection subFolderResources = g.getObjects(folderRes, gf.HasFolder); - - Map matching = new HashMap(); - - 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 subFolderResources, String name) throws DatabaseException; - public Resource createFolder(WriteGraph g, String name) throws DatabaseException; - public Resource findFile(ReadGraph g, Collection 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 subFolderResources, String name) throws DatabaseException; - public Resource findFile(ReadGraph g, Collection 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 subFileResources = g.getObjects(folderRes, gf.HasFile); - Collection subFolderResources = g.getObjects(folderRes, gf.HasFolder); - - Map matching = new HashMap(); - - 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 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() { - - @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; - } - }); - } -} +/******************************************************************************* + * 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() { + @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.getRelatedValue(res, gf.HasResourceName); + + 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 subFileResources = g.getObjects(folderRes, gf.HasFile); + Collection subFolderResources = g.getObjects(folderRes, gf.HasFolder); + + Map matching = new HashMap(); + + 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 subFileResources = g.getObjects(folderRes, gf.HasFile); + Collection subFolderResources = g.getObjects(folderRes, gf.HasFolder); + + Map matching = new HashMap(); + + 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 subFolderResources, String name) throws DatabaseException; + public Resource createFolder(WriteGraph g, String name) throws DatabaseException; + public Resource findFile(ReadGraph g, Collection 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 subFolderResources, String name) throws DatabaseException; + public Resource findFile(ReadGraph g, Collection 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 subFileResources = g.getObjects(folderRes, gf.HasFile); + Collection subFolderResources = g.getObjects(folderRes, gf.HasFolder); + + Map matching = new HashMap(); + + 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 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() { + + @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; + } + }); + } +}