package org.simantics.db.impl.graph; import gnu.trove.set.hash.TIntHashSet; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashMap; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.parser.repository.DataValueRepository; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.VirtualGraph; import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.ResourceImpl; import org.simantics.db.service.TransferableGraphSupport; import org.simantics.db.service.VirtualGraphSupport; import org.simantics.utils.Development; import org.simantics.utils.FileUtils; public class WriteLogger { //final public static String LOG = "WriteLogger.log"; public static File logFile; public static RandomAccessFile raf; public static boolean enable = false; public static TIntHashSet created; static { if(Development.DEVELOPMENT) { created = new TIntHashSet(); logFile = new File("write.log"); try { raf = new RandomAccessFile(logFile, "rw"); } catch (FileNotFoundException e) { e.printStackTrace(); } } } private static String resourceLog(ReadGraph graph, Resource resource) throws DatabaseException { if(!enable) return null; if(resource == null) return "N"; ResourceImpl impl = (ResourceImpl)resource; int id = impl.id; if(created.contains(id)) return "I" + impl.id; else { String uri = graph.getPossibleURI(resource); if(uri != null) return "U" + uri; else return "N"; } } private static String virtualGraphLog(ReadGraph graph) { WriteGraphImpl impl = (WriteGraphImpl)graph; VirtualGraph vg = impl.getProvider(); if(vg == null) return "N"; else { if(VirtualGraph.Persistency.MEMORY == vg.getPersistency()) return "M" + vg.getIdentifier(); else return "W" + vg.getIdentifier(); } } private static void logLine(String line) { if(!enable) return; try { byte[] data = line.getBytes(); raf.write(data); } catch (IOException e) { } } public static void logClaim(ReadGraph graph, Resource subject, Resource predicate, Resource inverse, Resource object) throws DatabaseException { logLine("C\t" + virtualGraphLog(graph) + "\t" + resourceLog(graph, subject) + "\t" + resourceLog(graph, predicate) + "\t" + resourceLog(graph, inverse) + "\t" + resourceLog(graph, object) + "\n"); } public static void logDeny(ReadGraph graph, Resource subject, Resource predicate, Resource inverse, Resource object) throws DatabaseException { logLine("D\t" + virtualGraphLog(graph) + "\t" + resourceLog(graph, subject) + "\t" + resourceLog(graph, predicate) + "\t" + resourceLog(graph, inverse) + "\t" + resourceLog(graph, object) + "\n"); } public static void logNewResource(ReadGraph graph, Resource subject) throws DatabaseException { if(!enable) return; ResourceImpl impl = (ResourceImpl)subject; created.add(impl.id); logLine("R\t" + virtualGraphLog(graph) + "\t" + resourceLog(graph, subject) + "\n"); } public static void logValue(ReadGraph graph, Resource subject, byte[] value) throws DatabaseException { if(!enable) return; try { logLine("V\t" + virtualGraphLog(graph) + "\t" + resourceLog(graph, subject) + "\t" + Bindings.BYTE_ARRAY.toString(value) + "\n"); } catch (BindingException e) { e.printStackTrace(); } } private static Resource readResource(WriteGraph graph, String id, HashMap ids) throws DatabaseException { if(id.startsWith("I")) { Resource result = ids.get(id); if(result == null) { System.err.println("undeclared id='" + id + "'"); } return result; } else if (id.startsWith("U")) { return graph.getPossibleResource(id.substring(1)); } else { return null; } } private static VirtualGraph vg = null; private static VirtualGraph getVirtualGraph(WriteGraphImpl graph, String id) { if("N".equals(id)) return null; VirtualGraphSupport vgs = graph.getService(VirtualGraphSupport.class); if (id.startsWith("M")) { return vgs.getMemoryPersistent(id.substring(1)); } else { return vgs.getWorkspacePersistent(id.substring(1)); } } private static WriteGraphImpl applyVirtualGraph(WriteGraphImpl graph, String id) { VirtualGraph target = getVirtualGraph(graph, id); if(target != vg) { vg = target; return (WriteGraphImpl)graph.newSync(target); } else { return graph; } } public static void read(WriteGraph _graph) throws Exception { vg = null; WriteGraphImpl graph = (WriteGraphImpl)_graph; String data = FileUtils.getContents(new FileInputStream(logFile)).replace("\r", ""); HashMap ids = new HashMap(); for(String line : data.split("\n")) { String[] parts = line.split("\t"); if("C".equals(parts[0])) { graph = applyVirtualGraph(graph, parts[1]); Resource subject = readResource(graph, parts[2], ids); Resource predicate = readResource(graph, parts[3], ids); Resource inverse = readResource(graph, parts[4], ids); Resource object = readResource(graph, parts[5], ids); if(subject == null || predicate == null || object == null) { System.err.println("skipped statement"); } else { graph.claim(subject, predicate, inverse, object); } } else if("D".equals(parts[0])) { graph = applyVirtualGraph(graph, parts[1]); Resource subject = readResource(graph, parts[2], ids); Resource predicate = readResource(graph, parts[3], ids); Resource inverse = readResource(graph, parts[4], ids); Resource object = readResource(graph, parts[5], ids); if(subject == null || predicate == null || object == null) { System.err.println("skipped statement"); } else { graph.deny(subject, predicate, inverse, object); } } else if ("R".equals(parts[0])) { graph = applyVirtualGraph(graph, parts[1]); Resource resource = graph.newResource(); ids.put(parts[2], resource); } else if ("V".equals(parts[0])) { graph = applyVirtualGraph(graph, parts[1]); Resource subject = readResource(graph, parts[2], ids); // This is an error if(subject == null) continue; byte[] value = (byte[])Bindings.BYTE_ARRAY.parseValue(parts[3], new DataValueRepository()); TransferableGraphSupport tgSupport = graph.getService(TransferableGraphSupport.class); tgSupport.setValue(graph, subject, vg, value); } } } }