]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/VirtualGraphServerSupportImpl.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / VirtualGraphServerSupportImpl.java
diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/VirtualGraphServerSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/VirtualGraphServerSupportImpl.java
new file mode 100644 (file)
index 0000000..6c86c10
--- /dev/null
@@ -0,0 +1,386 @@
+package fi.vtt.simantics.procore.internal;\r
+\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.FilenameFilter;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.ObjectInputStream;\r
+import java.io.ObjectOutputStream;\r
+import java.io.OutputStream;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.concurrent.CopyOnWriteArrayList;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.VirtualGraph;\r
+import org.simantics.db.VirtualGraph.Persistency;\r
+import org.simantics.db.WriteOnlyGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.impl.ClusterI;\r
+import org.simantics.db.impl.ResourceImpl;\r
+import org.simantics.db.impl.TransientGraph;\r
+import org.simantics.db.impl.graph.ReadGraphImpl;\r
+import org.simantics.db.impl.support.VirtualGraphServerSupport;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.service.SerialisationSupport;\r
+import org.simantics.db.service.ServerInformation;\r
+import org.simantics.db.service.TransferableGraphSupport;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.utils.FileUtils;\r
+\r
+public class VirtualGraphServerSupportImpl implements VirtualGraphSupport, VirtualGraphServerSupport {\r
+\r
+       final private static boolean DEBUG = false;\r
+       final private SessionImplSocket session;\r
+\r
+       final public File virtualGraphStoragePath;\r
+       public String dbString = null;\r
+\r
+       public TIntHashSet virtuals = new TIntHashSet();\r
+\r
+       final public CopyOnWriteArrayList<TransientGraph>  providers          = new CopyOnWriteArrayList<TransientGraph>();\r
+       final private CopyOnWriteArrayList<TransientGraph> workspaceProviders = new CopyOnWriteArrayList<TransientGraph>();\r
+       final private CopyOnWriteArrayList<TransientGraph> memoryProviders    = new CopyOnWriteArrayList<TransientGraph>();\r
+\r
+       public AtomicInteger virtualId;\r
+       private boolean hasVirtuals = false;\r
+\r
+       public VirtualGraphServerSupportImpl(SessionImplSocket session, File path) {\r
+               this.session = session;\r
+               this.virtualGraphStoragePath = path;\r
+       }\r
+\r
+       void connect(String dbString) {\r
+\r
+               virtualId = new AtomicInteger(-2);\r
+\r
+               this.dbString = dbString;\r
+\r
+               File file = new File(virtualGraphStoragePath, "virtualGraphs." + dbString + ".dat");\r
+\r
+               //      System.out.println("scanning " + file.getAbsolutePath());\r
+\r
+               if(file.exists()) {\r
+                       try {\r
+                               InputStream stream = new FileInputStream(file);\r
+                               final ObjectInputStream os = new ObjectInputStream(stream);\r
+                               virtualId = new AtomicInteger(os.readInt());\r
+                               //                      System.out.println("virtualId=" + virtualId.get());\r
+                               os.close();\r
+                               stream.close();\r
+\r
+                               hasVirtuals = true;\r
+\r
+                               // Load existing workspace persistent graphs\r
+                               for(File virtualGraph : virtualGraphStoragePath.listFiles(new FilenameFilter() {\r
+                                       @Override\r
+                                       public boolean accept(File dir, String name) {\r
+                                               return name.endsWith(".vg");\r
+                                       }\r
+                               })) {\r
+                                       String name = virtualGraph.getName();\r
+                                       String[] parts = name.split("\\x2E", 2);\r
+                                       getWorkspacePersistent(parts[0]);\r
+                               }\r
+\r
+                       } catch (IOException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               } else {\r
+                       if (DEBUG)\r
+                               System.out.println("No stored virtual graphs.");\r
+               }\r
+\r
+       }\r
+\r
+       public void saveVirtualGraphState(SessionImplSocket session) {\r
+\r
+               if(!hasVirtuals) return;\r
+\r
+               try {\r
+\r
+                       String databaseId = session.getService(ServerInformation.class).getDatabaseId();\r
+                       String serverId = session.getService(ServerInformation.class).getServerId();\r
+                       File file = new File(virtualGraphStoragePath, "virtualGraphs." + databaseId + "." + serverId + ".dat");\r
+\r
+                       OutputStream stream = new FileOutputStream(file);\r
+                       final ObjectOutputStream os = new ObjectOutputStream(stream);\r
+                       os.writeInt(virtualId.get());\r
+                       os.flush();\r
+                       stream.close();\r
+\r
+               } catch (IOException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+       public void disposeVirtualGraphs() {\r
+\r
+               if(!hasVirtuals) return;\r
+\r
+               saveVirtualGraphState(session);\r
+               for(TransientGraph graph : workspaceProviders) graph.dispose();\r
+\r
+       }\r
+\r
+       public void saveVirtualGraphs() {\r
+\r
+               if(!hasVirtuals) return;\r
+\r
+               saveVirtualGraphState(session);\r
+               for(TransientGraph graph : workspaceProviders) graph.save();\r
+\r
+       }\r
+\r
+       @Override\r
+       public void saveAll() {\r
+               saveVirtualGraphs();\r
+       }\r
+\r
+       @Override\r
+       public VirtualGraph getMemoryPersistent(String identifier) {\r
+\r
+               if(identifier == null) throw new IllegalArgumentException("Argument cannot be null!");\r
+\r
+               for(TransientGraph graph : memoryProviders) {\r
+                       if(identifier.equals(graph.getIdentifier())) return graph;\r
+               }\r
+\r
+               String databaseId =  session.getService(ServerInformation.class).getDatabaseId();\r
+               VirtualGraphServerSupport vgss = session.getService(VirtualGraphServerSupport.class);\r
+\r
+        TransientGraph result = TransientGraph.memoryPersistent(new SerialisationSupportImpl(session), vgss, session.resourceSupport, session, databaseId, identifier);\r
+        memoryProviders.add(result);\r
+        providers.add(result);\r
+        return result;\r
+       }\r
+\r
+       private TransientGraph createWorkspacePersistentInternal(String identifier) {\r
+\r
+           String databaseId = session.getService(ServerInformation.class).getDatabaseId();\r
+           VirtualGraphServerSupport vgss = session.getService(VirtualGraphServerSupport.class);\r
+\r
+           try {\r
+               return TransientGraph.workspacePersistent(new SerialisationSupportImpl(session), vgss, session.resourceSupport, session, databaseId, identifier);\r
+           } catch (Exception e) {\r
+               Activator.log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Failed to restore contents of previous virtual graph with identifier '" + identifier + "'. Resetting its contents to empty. See exception for problem details.", e));\r
+            return TransientGraph.memoryPersistent(new SerialisationSupportImpl(session), vgss, session.resourceSupport, session, databaseId, identifier);\r
+           }\r
+\r
+       }\r
+       \r
+       @Override\r
+       public VirtualGraph getWorkspacePersistent(String identifier) {\r
+\r
+               if(identifier == null) throw new IllegalArgumentException("Argument cannot be null!");\r
+\r
+               for(TransientGraph graph : workspaceProviders) {\r
+                       if(identifier.equals(graph.getIdentifier())) return graph;\r
+               }\r
+\r
+               TransientGraph result = createWorkspacePersistentInternal(identifier);\r
+               \r
+        workspaceProviders.add(result);\r
+        providers.add(result);\r
+        hasVirtuals = true;\r
+        return result;\r
+\r
+       }\r
+\r
+       @Override\r
+       public boolean discard(VirtualGraph provider) {\r
+               if (!(provider instanceof TransientGraph))\r
+                       return false;\r
+               if (!providers.remove(provider))\r
+                       return false;\r
+\r
+               TransientGraph tg = (TransientGraph) provider;\r
+\r
+               if (workspaceProviders.remove(provider)) {\r
+                       // TODO: remove possibly existing data from disk\r
+                       tg.dispose();\r
+               } else if (memoryProviders.remove(provider)) {\r
+                       tg.dispose();\r
+               }\r
+               return true;\r
+       }\r
+\r
+       public Resource getPersistentResource(WriteOnlyGraph graph, Resource resource, Map<Resource, Resource> creation) throws DatabaseException {\r
+               if(resource.isPersistent()) return resource;\r
+               else {\r
+                       Resource result = creation.get(resource);\r
+                       if(result == null) {\r
+                               result = graph.newResource();\r
+                               creation.put(resource, result);\r
+                       }\r
+                       return result;\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public boolean integrate(WriteOnlyGraph graph, VirtualGraph provider) throws DatabaseException {\r
+\r
+               if (!(provider instanceof TransientGraph))\r
+                       return false;\r
+               if (!providers.remove(provider))\r
+                       return false;\r
+\r
+               workspaceProviders.remove(provider);\r
+               memoryProviders.remove(provider);\r
+               \r
+               TransferableGraphSupport tgSupport = graph.getService(TransferableGraphSupport.class);\r
+               TransientGraph tg = (TransientGraph) provider;\r
+               \r
+               Map<Resource, Resource> creation = new HashMap<Resource, Resource>();\r
+               for(Statement stm : tg.listStatements()) {\r
+                       Resource subject = getPersistentResource(graph, stm.getSubject(), creation);\r
+                       Resource predicate = getPersistentResource(graph, stm.getPredicate(), creation);\r
+                       Resource object = getPersistentResource(graph, stm.getObject(), creation);\r
+                       graph.claim(subject, predicate, null, object);\r
+               }\r
+               for(Resource r : tg.listValues()) {\r
+                       byte[] value = tg.getValue(((ResourceImpl)r).id);\r
+                       tgSupport.setValue(graph, getPersistentResource(graph, r, creation), null, value);\r
+               }\r
+               discard(provider);\r
+               return true;\r
+               \r
+       }\r
+\r
+       @Override\r
+       public Collection<TransientGraph> getVirtualGraphs(int subject) {\r
+               if(subject < 0 || virtuals.contains(subject)) return providers;\r
+               else return null; \r
+       }\r
+\r
+       @Override\r
+       public void removeVirtual(int id) {\r
+               virtuals.remove(id);\r
+       }\r
+\r
+       @Override\r
+       public void addVirtual(int id) {\r
+               assert(id > 0);\r
+               //              System.err.println("addVirtual " + id);\r
+               virtuals.add(id);\r
+               ClusterI cluster = session.clusterTable.getClusterByResourceKey(id);\r
+               cluster.markVirtual();\r
+       }\r
+\r
+       @Override\r
+       public int createVirtual() {\r
+               return virtualId.decrementAndGet();\r
+       }\r
+\r
+       @Override\r
+       public File storagePath() {\r
+               return virtualGraphStoragePath;\r
+       }\r
+\r
+       @Override\r
+       public Collection<Statement> listStatements(VirtualGraph graph_) {\r
+               TransientGraph graph = (TransientGraph)graph_;\r
+               return graph.listStatements();\r
+       }\r
+\r
+       @Override\r
+       public Collection<Resource> listValues(VirtualGraph graph_) {\r
+               TransientGraph graph = (TransientGraph)graph_;\r
+               return graph.listValues();\r
+       }\r
+\r
+       @Override\r
+       public Collection<VirtualGraph> listGraphs() {\r
+               ArrayList<VirtualGraph> result = new ArrayList<VirtualGraph>();\r
+               result.addAll(memoryProviders);\r
+               result.addAll(workspaceProviders);\r
+               return result;\r
+       }\r
+\r
+       public String report(final File file) {\r
+\r
+               session.asyncRequest(new Read<String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph) throws DatabaseException {\r
+\r
+                               SerialisationSupport ss = session.getService(SerialisationSupport.class);\r
+                               StringBuilder b = new StringBuilder();\r
+                               try {\r
+                                       for(VirtualGraph vg : listGraphs()) {\r
+                                               TransientGraph tg = (TransientGraph)vg;\r
+                                               if(Persistency.MEMORY == tg.getPersistency()) b.append("Memory persistent virtual graph '" + tg.getIdentifier() + "'\n");\r
+                                               if(Persistency.WORKSPACE == tg.getPersistency()) b.append("Workspace persistent virtual graph '" + tg.getIdentifier() + "'\n");\r
+                                               for(Statement stm : listStatements(tg)) {\r
+                                                       int s = ss.getTransientId(stm.getSubject());\r
+                                                       int p = ss.getTransientId(stm.getPredicate());\r
+                                                       int o = ss.getTransientId(stm.getObject());\r
+                                                       String sName = NameUtils.getSafeName(graph, stm.getSubject());\r
+                                                       String pName = NameUtils.getSafeName(graph, stm.getPredicate());\r
+                                                       String oName = NameUtils.getSafeName(graph, stm.getObject());\r
+                                                       b.append(" S '" + sName + "' '" + pName + "' '" + oName + "' " + s + " " + p + " " + o + "\n");\r
+                                               }\r
+                                               for(Resource r : listValues(tg)) {\r
+                                                       String sName = NameUtils.getSafeName(graph, r);\r
+                                                       Object value = graph.getPossibleValue(r);\r
+                                                       b.append(" V '" + sName + "' '" + value + "'\n");\r
+                                               }\r
+                                       }\r
+                                       FileUtils.writeFile(file, b.toString().getBytes());\r
+                               } catch (IOException e) {\r
+                                       e.printStackTrace();\r
+                                       return "ERROR";\r
+                               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                                       return "ERROR";\r
+                               }\r
+                               return "OK";\r
+\r
+                       }\r
+\r
+               });\r
+               return "OK";\r
+\r
+       }\r
+\r
+       @Override\r
+       public VirtualGraph getGraph(ReadGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException {\r
+               ReadGraphImpl impl = (ReadGraphImpl)graph;\r
+               return impl.processor.getProvider(subject, predicate, object);\r
+       }\r
+\r
+       @Override\r
+       public VirtualGraph getGraph(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {\r
+               ReadGraphImpl impl = (ReadGraphImpl)graph;\r
+               return impl.processor.getProvider(subject, predicate);\r
+       }\r
+\r
+       @Override\r
+       public VirtualGraph getGraph(ReadGraph graph, Resource subject) throws DatabaseException {\r
+               Layer0 L0 = Layer0.getInstance(graph);\r
+               if(graph.hasStatement(subject, L0.InstanceOf)) {\r
+                       return getGraph(graph, subject, L0.InstanceOf);\r
+               } else if (graph.hasStatement(subject, L0.Inherits)) {\r
+                       return getGraph(graph, subject, L0.Inherits);\r
+               } else if (graph.hasStatement(subject, L0.SubrelationOf)) {\r
+                       return getGraph(graph, subject, L0.SubrelationOf);\r
+               } else {\r
+                       throw new DatabaseException("Resource is invalid, should have a statement with either L0.InstanceOf, L0.Inherits or L0.SubrelationOf " + subject);\r
+               }\r
+       }\r
+       \r
+}\r