-package fi.vtt.simantics.procore.internal;\r
-\r
-import java.util.TreeMap;\r
-\r
-import org.simantics.db.Metadata;\r
-import org.simantics.db.Operation;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.VirtualGraph;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.MetadataUtils;\r
-import org.simantics.db.common.exception.DebugException;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ImmutableException;\r
-import org.simantics.db.exception.ServiceException;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.MemWatch;\r
-import org.simantics.db.impl.ResourceImpl;\r
-import org.simantics.db.impl.VirtualGraphImpl;\r
-import org.simantics.db.impl.graph.ReadGraphImpl;\r
-import org.simantics.db.impl.graph.WriteGraphImpl;\r
-import org.simantics.db.impl.graph.WriteSupport;\r
-import org.simantics.db.impl.query.QueryProcessor;\r
-import org.simantics.db.impl.query.QuerySupport;\r
-import org.simantics.db.procore.cluster.ClusterImpl;\r
-import org.simantics.db.procore.protocol.Constants;\r
-import org.simantics.db.request.Write;\r
-import org.simantics.db.request.WriteOnly;\r
-import org.simantics.db.request.WriteResult;\r
-import org.simantics.db.request.WriteTraits;\r
-import org.simantics.db.service.ByteReader;\r
-\r
-public class WriteSupportImpl implements WriteSupport {\r
-\r
- final private SessionImplSocket session;\r
- final private QueryProcessor queryProcessor;\r
- final private State state;\r
- final private QuerySupport querySupport;\r
- final private TreeMap<String, byte[]> metadata;\r
- \r
- WriteSupportImpl(SessionImplSocket session) {\r
- this.session = session;\r
- this.queryProcessor = session.getQueryProvider2();\r
- this.state = session.state;\r
- this.querySupport = session.querySupport;\r
- this.metadata = new TreeMap<String, byte[]>();\r
- assert(this.session != null);\r
- assert(this.queryProcessor != null);\r
- assert(this.state != null);\r
- assert(this.querySupport != null);\r
- }\r
- \r
- @Override\r
- public void flushCluster() {\r
- session.clusterTable.flushCluster(session.graphSession);\r
- if(session.defaultClusterSet != null) {\r
- long resourceId = session.defaultClusterSet.getResourceId();\r
- session.clusterSetsSupport.put(resourceId, Constants.NewClusterId);\r
- }\r
- }\r
-\r
- @Override\r
- public void flushCluster(Resource r) {\r
- session.clusterStream.reallyFlush();\r
- }\r
-\r
- @Override\r
- public boolean writeOnly() {\r
- return session.writeOnly;\r
- }\r
-\r
- @Override\r
- public void flush(boolean intermediate) {\r
-\r
- if (!session.state.isWriteTransaction())\r
- throw new IllegalStateException("Can only flush during transaction.");\r
-\r
- gc();\r
- \r
- }\r
- \r
- final public void claim(VirtualGraph provider, Resource subject, Resource predicate, Resource object) throws ServiceException {\r
- claim(provider, querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));\r
- }\r
-\r
- @Override\r
- final public void claim(VirtualGraph provider, int subject, int predicate, int object)\r
- throws ServiceException {\r
-\r
- provider = session.getProvider(provider); \r
- if (writeOnly()) {\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).claim(subject, predicate, object);\r
- queryProcessor.updateStatements(subject, predicate);\r
- session.clientChanges.claim(subject, predicate, object);\r
- } else {\r
- claimImpl2(subject, predicate, object);\r
- }\r
- } else {\r
-// queryProcessor.acquireWrite(writeState.getGraph());\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).claim(subject, predicate, object);\r
- queryProcessor.updateStatements(subject, predicate);\r
- session.clientChanges.claim(subject, predicate, object);\r
- } else {\r
- claimImpl(subject, predicate, object);\r
- }\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- }\r
- \r
- }\r
- \r
- @Override\r
- public void setValue(VirtualGraph provider, Resource resource, byte[] value) throws ServiceException {\r
-\r
- provider = session.getProvider(provider);\r
- if (writeOnly()) {\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).claimValue(((ResourceImpl) resource).id, value, value.length);\r
- queryProcessor.updateValue(querySupport.getId(resource));\r
- session.clientChanges.claimValue(resource);\r
- } else {\r
- try {\r
- addSetValue(((ResourceImpl) resource).id, value, value.length);\r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- }\r
- }\r
- } else {\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).claimValue(((ResourceImpl) resource).id, value, value.length);\r
- queryProcessor.updateValue(querySupport.getId(resource));\r
- session.clientChanges.claimValue(resource);\r
- } else {\r
- try {\r
- addSetValue(((ResourceImpl) resource).id, value, value.length);\r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- }\r
- }\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- }\r
-\r
- }\r
-\r
- @Override\r
- public Resource createResource(VirtualGraph provider) throws DatabaseException {\r
- if (provider != null) {\r
- int newId = ((VirtualGraphImpl)provider).newResource(false);\r
- return new ResourceImpl(session.resourceSupport, newId);\r
- } else {\r
- return session.getNewResource();\r
- }\r
- }\r
-\r
- @Override\r
- public Resource createResource(VirtualGraph provider, long clusterId)\r
- throws DatabaseException {\r
- assert (provider == null);\r
- return session.getNewResource(clusterId);\r
- }\r
-\r
- @Override\r
- public Resource createResource(VirtualGraph provider, Resource clusterSet)\r
- throws DatabaseException {\r
- assert(provider == null);\r
- assert(clusterSet != null);\r
- return session.getNewResource(clusterSet);\r
- }\r
-\r
- @Override\r
- public void createClusterSet(VirtualGraph provider, Resource clusterSet)\r
- throws DatabaseException {\r
- assert(provider == null);\r
- assert(clusterSet != null);\r
- session.getNewClusterSet(clusterSet);\r
- }\r
-\r
- @Override\r
- public boolean hasClusterSet(VirtualGraph dummy, Resource clusterSet)\r
- throws ServiceException {\r
- return session.containsClusterSet(clusterSet);\r
- }\r
-\r
- @Override\r
- public Resource setDefaultClusterSet(Resource clusterSet)\r
- throws ServiceException {\r
- return session.setDefaultClusterSet4NewResource(clusterSet);\r
- }\r
- @Override\r
- public void denyValue(VirtualGraph provider, Resource resource) throws ServiceException {\r
- provider = session.getProvider(provider);\r
- if (null == provider) {\r
- int key = ((ResourceImpl)resource).id;\r
- ClusterI cluster = session.clusterTable.getClusterByResourceKey(key);\r
- if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)\r
- if(key != queryProcessor.getRootLibrary())\r
- throw new ImmutableException("Trying to modify immutable resource key=" + key);\r
-\r
- try { \r
- cluster.removeValue(key, session.clusterTranslator);\r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- return;\r
- }\r
- queryProcessor.updateValue(key);\r
- session.clientChanges.claimValue(resource);\r
- } else {\r
- ((VirtualGraphImpl)provider).denyValue(((ResourceImpl) resource).id);\r
- queryProcessor.updateValue(querySupport.getId(resource));\r
- session.clientChanges.claimValue(resource);\r
- }\r
- if (!writeOnly())\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- }\r
-\r
-\r
- @Override\r
- public boolean removeStatement(VirtualGraph provider, Resource subject, Resource predicate,\r
- Resource object) throws ServiceException {\r
- boolean ret = true;\r
- if (writeOnly()) {\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).deny(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));\r
- queryProcessor.updateStatements(querySupport.getId(subject), querySupport.getId(predicate));\r
- } else {\r
- ret = removeStatement(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));\r
- }\r
- } else {\r
- if (provider != null) {\r
-// queryProcessor.acquireWrite(writeState.getGraph());\r
- ((VirtualGraphImpl)provider).deny(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));\r
- queryProcessor.updateStatements(querySupport.getId(subject), querySupport.getId(predicate));\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- } else {\r
- int sid = querySupport.getId(subject);\r
- int pid = querySupport.getId(predicate);\r
- int oid = querySupport.getId(object);\r
- if (sid < 0 || pid < 0 || oid < 0) {\r
- // One of the resources is virtual, cannot remove such\r
- // statement from persistent storage.\r
- return false;\r
- }\r
-// queryProcessor.acquireWrite(writeState.getGraph());\r
- ret = removeStatement(sid, pid, oid);\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- }\r
- }\r
- session.clientChanges.deny(subject, predicate, object);\r
- return ret;\r
- }\r
- \r
- @Override\r
- public synchronized void performWriteRequest(WriteGraph graph_, Write request) throws DatabaseException {\r
- WriteGraphImpl graph = (WriteGraphImpl)graph_;\r
-// graph.state.barrier.inc();\r
- try {\r
- request.perform(graph);\r
- } catch (Throwable t) {\r
- t.printStackTrace();\r
- }\r
-// graph.state.barrier.dec();\r
-// graph.waitAsync(request);\r
- \r
- queryProcessor.performDirtyUpdates(graph);\r
- \r
- // Do not fire metadata listeners for virtual requests\r
- if(graph.getProvider() == null) {\r
- //session.fireMetadataListeners(graph, session.clientChanges);\r
- state.commitAndContinue(graph, session.clusterStream, request);\r
- //session.clientChanges = new ClientChangesImpl(session);\r
- }\r
-\r
-// graph.state.barrier.assertReady();\r
- \r
- }\r
- \r
- @Override\r
- public synchronized <T> T performWriteRequest(WriteGraph graph_, WriteResult<T> request) throws DatabaseException {\r
-\r
- WriteGraphImpl graph = (WriteGraphImpl)graph_;\r
-// graph.state.barrier.inc();\r
- T result = null;\r
- Throwable t = null;\r
- try {\r
- result = request.perform(graph);\r
- } catch (Throwable t2) {\r
- if(DebugException.DEBUG) new DebugException(t2).printStackTrace();\r
- t = t2;\r
- }\r
- \r
-// graph.state.barrier.dec();\r
-// graph.waitAsync(request);\r
- \r
- queryProcessor.performDirtyUpdates(graph);\r
-\r
- // Do not fire metadata listeners for virtual requests\r
- if(graph.getProvider() == null) {\r
- //session.fireMetadataListeners((WriteGraphImpl)graph, session.clientChanges);\r
- state.commitAndContinue(graph, session.clusterStream, request);\r
- //session.clientChanges = new ClientChangesImpl(session);\r
- }\r
- \r
- if(t != null) {\r
- if(t instanceof DatabaseException) throw (DatabaseException)t;\r
- else throw new DatabaseException(t);\r
- }\r
- \r
- return result;\r
- \r
- }\r
-\r
- @Override\r
- public synchronized void performWriteRequest(WriteGraph graph, WriteOnly request) throws DatabaseException {\r
-\r
- session.acquireWriteOnly();\r
- \r
- request.perform(graph);\r
- \r
- ReadGraphImpl impl = (ReadGraphImpl)graph;\r
- \r
- queryProcessor.performDirtyUpdates(impl);\r
-\r
- // Do not fire metadata listeners for virtual requests\r
- if(graph.getProvider() == null) {\r
- //session.fireMetadataListeners(impl, session.clientChanges);\r
- state.commitAndContinue(session.writeState.getGraph(), session.clusterStream, request);\r
- //session.clientChanges = new ClientChangesImpl(session);\r
- } \r
- session.releaseWriteOnly(impl);\r
- \r
- }\r
-\r
- \r
- @Override\r
- public void gc() {\r
- if (MemWatch.isLowOnMemory()) {\r
- session.clusterTable.gc();\r
- queryProcessor.gc(0, Integer.MAX_VALUE);\r
- System.gc();\r
- }\r
- }\r
- \r
- @Override\r
- public void claimValue(VirtualGraph provider, Resource resource, byte[] value) throws DatabaseException {\r
- claimValue(provider, ((ResourceImpl)resource).id, value, value.length);\r
- }\r
-\r
- @Override\r
- public void claimValue(VirtualGraph provider, int resource, byte[] value, int length) throws DatabaseException {\r
-\r
- provider = session.getProvider(provider);\r
- if (writeOnly()) {\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).claimValue(resource, value, length);\r
- queryProcessor.updateValue(resource);\r
- session.clientChanges.claimValue(resource);\r
- } else {\r
- addSetValue(resource, value, length);\r
- }\r
- } else {\r
- if (provider != null) {\r
- ((VirtualGraphImpl)provider).claimValue(resource, value, length);\r
- queryProcessor.updateValue(resource);\r
- session.clientChanges.claimValue(resource);\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- } else {\r
- try {\r
- addSetValue(resource, value, length);\r
- } catch (DatabaseException e) {\r
- throw e;\r
- } catch (Throwable t) {\r
- throw new DatabaseException(t);\r
- } finally {\r
- queryProcessor.releaseWrite(session.writeState.getGraph());\r
- }\r
- }\r
- }\r
- }\r
- \r
- @Override\r
- public void claimValue(VirtualGraph provider, Resource resource, ByteReader reader, int amount) throws DatabaseException {\r
- claimValue(provider, resource, reader.readBytes(null, amount));\r
- }\r
-\r
- @Override\r
- public <T> void addMetadata(Metadata data) throws ServiceException {\r
- MetadataUtils.addMetadata(session, metadata, data);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public <T extends Metadata> T getMetadata(Class<T> clazz) throws ServiceException {\r
- return MetadataUtils.getMetadata(session, metadata, clazz);\r
- }\r
-\r
- @Override\r
- public TreeMap<String, byte[]> getMetadata() {\r
- return metadata;\r
- }\r
-\r
- @Override\r
- public void commitDone(WriteTraits writeTraits, long csid) {\r
- metadata.clear();\r
- if (this.writeTraits == writeTraits) {\r
- session.graphSession.undoContext.clear();\r
- this.writeTraits = null;\r
- }\r
-// if (null != operation)\r
-// operation = null;\r
- }\r
- @Override\r
- public int clearMetadata() {\r
- int ret = metadata.size();\r
- metadata.clear();\r
- return ret;\r
- }\r
- @Override\r
- public void clearUndoList(WriteTraits writeTraits) {\r
- this.writeTraits = writeTraits;\r
- }\r
- @Override\r
- public void startUndo() {\r
- session.state.setCombine(false);\r
- }\r
- private WriteTraits writeTraits = null;\r
- private void addSetValue(int subject, byte[] value, int length)\r
- throws DatabaseException {\r
-\r
- ClusterI cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)\r
- if(subject != queryProcessor.getRootLibrary())\r
- throw new ImmutableException("Trying to modify immutable resource key=" + subject);\r
- \r
- ClusterI cluster2 = cluster.setValue(subject, value, length, session.clusterTranslator);\r
- if (cluster2 != cluster)\r
- session.clusterTable.replaceCluster(cluster2);\r
- \r
- session.clientChanges.claimValue(subject);\r
- \r
- if (cluster2.isWriteOnly())\r
- return;\r
-\r
- queryProcessor.updateValue(subject);\r
-\r
- }\r
-\r
- final private void claimImpl(int subject, int predicate, int object)\r
- throws ServiceException {\r
-\r
- assert (subject != 0);\r
- assert (predicate != 0);\r
- assert (object != 0);\r
-\r
- ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- assert (null != cluster);\r
- if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)\r
- if(subject != queryProcessor.getRootLibrary())\r
- throw new ImmutableException("Trying to modify immutable resource key=" + subject);\r
- try {\r
- ClusterI c = cluster.addRelation(subject, predicate, object, session.clusterTranslator);\r
- if (null != c && c != cluster)\r
- session.clusterTable.replaceCluster(c);\r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- throw new RuntimeException(e);\r
- }\r
- queryProcessor.updateStatements(subject, predicate);\r
- session.clientChanges.claim(subject, predicate, object);\r
-\r
- }\r
-\r
- final private void claimImpl2(int subject, int predicate, int object) {\r
- \r
- assert (subject != 0);\r
- assert (predicate != 0);\r
- assert (object != 0);\r
-\r
- ClusterI cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- try {\r
- ClusterI c = cluster.addRelation(subject, predicate, object, session.clusterTranslator);\r
- if (null != c && c != cluster)\r
- session.clusterTable.replaceCluster(c);\r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- }\r
- if (cluster.isWriteOnly())\r
- return;\r
- queryProcessor.updateStatements(subject, predicate);\r
-\r
- }\r
- \r
- private boolean removeStatement(int subject, int predicate, int object) throws ImmutableException {\r
-\r
- assert (subject != 0);\r
- assert (predicate != 0);\r
- assert (object != 0);\r
-\r
- ClusterI cluster = session.clusterTable.getClusterByResourceKey(subject);\r
- assert (null != cluster);\r
-\r
- if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)\r
- if(subject != queryProcessor.getRootLibrary())\r
- throw new ImmutableException("Trying to modify immutable resource key=" + subject);\r
-\r
- try {\r
- cluster.denyRelation(subject, predicate, object, session.clusterTranslator);\r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- return false;\r
- }\r
- queryProcessor.updateStatements(subject, predicate);\r
- return true;\r
-\r
- }\r
- \r
-}\r
+package fi.vtt.simantics.procore.internal;
+
+import java.util.TreeMap;
+
+import org.simantics.db.Metadata;
+import org.simantics.db.Resource;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.MetadataUtils;
+import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ImmutableException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.MemWatch;
+import org.simantics.db.impl.ResourceImpl;
+import org.simantics.db.impl.VirtualGraphImpl;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.graph.WriteGraphImpl;
+import org.simantics.db.impl.graph.WriteSupport;
+import org.simantics.db.impl.query.QueryProcessor;
+import org.simantics.db.impl.query.QuerySupport;
+import org.simantics.db.procore.cluster.ClusterImpl;
+import org.simantics.db.procore.protocol.Constants;
+import org.simantics.db.request.Write;
+import org.simantics.db.request.WriteOnly;
+import org.simantics.db.request.WriteResult;
+import org.simantics.db.request.WriteTraits;
+import org.simantics.db.service.ByteReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WriteSupportImpl implements WriteSupport {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(WriteSupportImpl.class);
+
+ final private SessionImplSocket session;
+ final private QueryProcessor queryProcessor;
+ final private State state;
+ final private QuerySupport querySupport;
+ final private TreeMap<String, byte[]> metadata;
+
+ WriteSupportImpl(SessionImplSocket session) {
+ this.session = session;
+ this.queryProcessor = session.getQueryProvider2();
+ this.state = session.state;
+ this.querySupport = session.querySupport;
+ this.metadata = new TreeMap<String, byte[]>();
+ assert(this.session != null);
+ assert(this.queryProcessor != null);
+ assert(this.state != null);
+ assert(this.querySupport != null);
+ }
+
+ @Override
+ public void flushCluster() {
+ session.clusterTable.flushCluster(session.graphSession);
+ if(session.defaultClusterSet != null) {
+ long resourceId = session.defaultClusterSet.getResourceId();
+ session.clusterSetsSupport.put(resourceId, Constants.NewClusterId);
+ }
+ }
+
+ @Override
+ public void flushCluster(Resource r) {
+ session.clusterStream.reallyFlush();
+ }
+
+ @Override
+ public boolean writeOnly() {
+ return session.writeOnly;
+ }
+
+ @Override
+ public void flush(boolean intermediate) {
+
+ if (!session.state.isWriteTransaction())
+ throw new IllegalStateException("Can only flush during transaction.");
+
+ gc();
+
+ }
+
+ final public void claim(VirtualGraph provider, Resource subject, Resource predicate, Resource object) throws ServiceException {
+ claim(provider, querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));
+ }
+
+ @Override
+ final public void claim(VirtualGraph provider, int subject, int predicate, int object)
+ throws ServiceException {
+
+ provider = session.getProvider(provider);
+ if (writeOnly()) {
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).claim(subject, predicate, object);
+ queryProcessor.updateStatements(subject, predicate);
+ session.clientChanges.claim(subject, predicate, object);
+ } else {
+ claimImpl2(subject, predicate, object);
+ }
+ } else {
+// queryProcessor.acquireWrite(writeState.getGraph());
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).claim(subject, predicate, object);
+ queryProcessor.updateStatements(subject, predicate);
+ session.clientChanges.claim(subject, predicate, object);
+ } else {
+ claimImpl(subject, predicate, object);
+ }
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ }
+
+ }
+
+ @Override
+ public void setValue(VirtualGraph provider, Resource resource, byte[] value) throws ServiceException {
+
+ provider = session.getProvider(provider);
+ if (writeOnly()) {
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).claimValue(((ResourceImpl) resource).id, value, value.length);
+ queryProcessor.updateValue(querySupport.getId(resource));
+ session.clientChanges.claimValue(resource);
+ } else {
+ try {
+ addSetValue(((ResourceImpl) resource).id, value, value.length);
+ } catch (DatabaseException e) {
+ LOGGER.error("writeOnly setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e);
+ }
+ }
+ } else {
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).claimValue(((ResourceImpl) resource).id, value, value.length);
+ queryProcessor.updateValue(querySupport.getId(resource));
+ session.clientChanges.claimValue(resource);
+ } else {
+ try {
+ addSetValue(((ResourceImpl) resource).id, value, value.length);
+ } catch (DatabaseException e) {
+ LOGGER.error("setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e);
+ }
+ }
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ }
+
+ }
+
+ @Override
+ public Resource createResource(VirtualGraph provider) throws DatabaseException {
+ if (provider != null) {
+ int newId = ((VirtualGraphImpl)provider).newResource(false);
+ return new ResourceImpl(session.resourceSupport, newId);
+ } else {
+ return session.getNewResource();
+ }
+ }
+
+ @Override
+ public Resource createResource(VirtualGraph provider, long clusterId)
+ throws DatabaseException {
+ assert (provider == null);
+ return session.getNewResource(clusterId);
+ }
+
+ @Override
+ public Resource createResource(VirtualGraph provider, Resource clusterSet)
+ throws DatabaseException {
+ assert(provider == null);
+ assert(clusterSet != null);
+ return session.getNewResource(clusterSet);
+ }
+
+ @Override
+ public void createClusterSet(VirtualGraph provider, Resource clusterSet)
+ throws DatabaseException {
+ assert(provider == null);
+ assert(clusterSet != null);
+ session.getNewClusterSet(clusterSet);
+ }
+
+ @Override
+ public boolean hasClusterSet(VirtualGraph dummy, Resource clusterSet)
+ throws ServiceException {
+ return session.containsClusterSet(clusterSet);
+ }
+
+ @Override
+ public Resource setDefaultClusterSet(Resource clusterSet)
+ throws ServiceException {
+ return session.setDefaultClusterSet4NewResource(clusterSet);
+ }
+ @Override
+ public void denyValue(VirtualGraph provider, Resource resource) throws ServiceException {
+ provider = session.getProvider(provider);
+ if (null == provider) {
+ int key = ((ResourceImpl)resource).id;
+ ClusterI cluster = session.clusterTable.getClusterByResourceKey(key);
+ if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)
+ if(key != queryProcessor.getRootLibrary())
+ throw new ImmutableException("Trying to modify immutable resource key=" + key);
+
+ try {
+ cluster.removeValue(key, session.clusterTranslator);
+ } catch (DatabaseException e) {
+ LOGGER.error("denyValue({}, {}) failed", provider, resource, e);
+ return;
+ }
+ queryProcessor.updateValue(key);
+ session.clientChanges.claimValue(resource);
+ } else {
+ ((VirtualGraphImpl)provider).denyValue(((ResourceImpl) resource).id);
+ queryProcessor.updateValue(querySupport.getId(resource));
+ session.clientChanges.claimValue(resource);
+ }
+ if (!writeOnly())
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ }
+
+
+ @Override
+ public boolean removeStatement(VirtualGraph provider, Resource subject, Resource predicate,
+ Resource object) throws ServiceException {
+ boolean ret = true;
+ if (writeOnly()) {
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).deny(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));
+ queryProcessor.updateStatements(querySupport.getId(subject), querySupport.getId(predicate));
+ } else {
+ ret = removeStatement(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));
+ }
+ } else {
+ if (provider != null) {
+// queryProcessor.acquireWrite(writeState.getGraph());
+ ((VirtualGraphImpl)provider).deny(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));
+ queryProcessor.updateStatements(querySupport.getId(subject), querySupport.getId(predicate));
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ } else {
+ int sid = querySupport.getId(subject);
+ int pid = querySupport.getId(predicate);
+ int oid = querySupport.getId(object);
+ if (sid < 0 || pid < 0 || oid < 0) {
+ // One of the resources is virtual, cannot remove such
+ // statement from persistent storage.
+ return false;
+ }
+// queryProcessor.acquireWrite(writeState.getGraph());
+ ret = removeStatement(sid, pid, oid);
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ }
+ }
+ session.clientChanges.deny(subject, predicate, object);
+ return ret;
+ }
+
+ @Override
+ public synchronized void performWriteRequest(WriteGraph graph_, Write request) throws DatabaseException {
+ WriteGraphImpl graph = (WriteGraphImpl)graph_;
+// graph.state.barrier.inc();
+ try {
+ request.perform(graph);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+// graph.state.barrier.dec();
+// graph.waitAsync(request);
+
+ queryProcessor.propagateChangesInQueryCache(graph);
+
+ // Do not fire metadata listeners for virtual requests
+ if(graph.getProvider() == null) {
+ //session.fireMetadataListeners(graph, session.clientChanges);
+ state.commitAndContinue(graph, session.clusterStream, request);
+ //session.clientChanges = new ClientChangesImpl(session);
+ }
+
+// graph.state.barrier.assertReady();
+
+ }
+
+ @Override
+ public synchronized <T> T performWriteRequest(WriteGraph graph_, WriteResult<T> request) throws DatabaseException {
+
+ WriteGraphImpl graph = (WriteGraphImpl)graph_;
+// graph.state.barrier.inc();
+ T result = null;
+ Throwable t = null;
+ try {
+ result = request.perform(graph);
+ } catch (Throwable t2) {
+ if(DebugException.DEBUG) new DebugException(t2).printStackTrace();
+ t = t2;
+ }
+
+// graph.state.barrier.dec();
+// graph.waitAsync(request);
+
+ queryProcessor.propagateChangesInQueryCache(graph);
+
+ // Do not fire metadata listeners for virtual requests
+ if(graph.getProvider() == null) {
+ //session.fireMetadataListeners((WriteGraphImpl)graph, session.clientChanges);
+ state.commitAndContinue(graph, session.clusterStream, request);
+ //session.clientChanges = new ClientChangesImpl(session);
+ }
+
+ if(t != null) {
+ if(t instanceof DatabaseException) throw (DatabaseException)t;
+ else throw new DatabaseException(t);
+ }
+
+ return result;
+
+ }
+
+ @Override
+ public synchronized void performWriteRequest(WriteGraph graph, WriteOnly request) throws DatabaseException {
+
+ session.acquireWriteOnly();
+
+ request.perform(graph);
+
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+
+ queryProcessor.propagateChangesInQueryCache(impl);
+
+ // Do not fire metadata listeners for virtual requests
+ if(graph.getProvider() == null) {
+ //session.fireMetadataListeners(impl, session.clientChanges);
+ state.commitAndContinue(session.writeState.getGraph(), session.clusterStream, request);
+ //session.clientChanges = new ClientChangesImpl(session);
+ }
+ session.releaseWriteOnly(impl);
+
+ }
+
+
+ @Override
+ public void gc() {
+ if (MemWatch.isLowOnMemory()) {
+ session.clusterTable.gc();
+ queryProcessor.gc(0, Integer.MAX_VALUE);
+ System.gc();
+ }
+ }
+
+ @Override
+ public void claimValue(VirtualGraph provider, Resource resource, byte[] value) throws DatabaseException {
+ claimValue(provider, ((ResourceImpl)resource).id, value, value.length);
+ }
+
+ @Override
+ public void claimValue(VirtualGraph provider, int resource, byte[] value, int length) throws DatabaseException {
+
+ provider = session.getProvider(provider);
+ if (writeOnly()) {
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).claimValue(resource, value, length);
+ queryProcessor.updateValue(resource);
+ session.clientChanges.claimValue(resource);
+ } else {
+ addSetValue(resource, value, length);
+ }
+ } else {
+ if (provider != null) {
+ ((VirtualGraphImpl)provider).claimValue(resource, value, length);
+ queryProcessor.updateValue(resource);
+ session.clientChanges.claimValue(resource);
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ } else {
+ try {
+ addSetValue(resource, value, length);
+ } catch (DatabaseException e) {
+ throw e;
+ } catch (Throwable t) {
+ throw new DatabaseException(t);
+ } finally {
+ queryProcessor.releaseWrite(session.writeState.getGraph());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void claimValue(VirtualGraph provider, Resource resource, ByteReader reader, int amount) throws DatabaseException {
+ claimValue(provider, resource, reader.readBytes(null, amount));
+ }
+
+ @Override
+ public <T> void addMetadata(Metadata data) throws ServiceException {
+ MetadataUtils.addMetadata(session, metadata, data);
+ }
+
+ @Override
+ public <T extends Metadata> T getMetadata(Class<T> clazz) throws ServiceException {
+ return MetadataUtils.getMetadata(session, metadata, clazz);
+ }
+
+ @Override
+ public TreeMap<String, byte[]> getMetadata() {
+ return metadata;
+ }
+
+ @Override
+ public void commitDone(WriteTraits writeTraits, long csid) {
+ metadata.clear();
+ if (this.writeTraits == writeTraits) {
+ session.graphSession.undoContext.clear();
+ this.writeTraits = null;
+ }
+// if (null != operation)
+// operation = null;
+ }
+ @Override
+ public int clearMetadata() {
+ int ret = metadata.size();
+ metadata.clear();
+ return ret;
+ }
+ @Override
+ public void clearUndoList(WriteTraits writeTraits) {
+ this.writeTraits = writeTraits;
+ }
+ @Override
+ public void startUndo() {
+ session.state.setCombine(false);
+ }
+ private WriteTraits writeTraits = null;
+ private void addSetValue(int subject, byte[] value, int length)
+ throws DatabaseException {
+
+ ClusterI cluster = session.clusterTable.getClusterByResourceKey(subject);
+ if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)
+ if(subject != queryProcessor.getRootLibrary())
+ throw new ImmutableException("Trying to modify immutable resource key=" + subject);
+
+ ClusterI cluster2 = cluster.setValue(subject, value, length, session.clusterTranslator);
+ if (cluster2 != cluster)
+ session.clusterTable.replaceCluster(cluster2);
+
+ session.clientChanges.claimValue(subject);
+
+ if (cluster2.isWriteOnly())
+ return;
+
+ queryProcessor.updateValue(subject);
+
+ }
+
+ final private void claimImpl(int subject, int predicate, int object)
+ throws ServiceException {
+
+ assert (subject != 0);
+ assert (predicate != 0);
+ assert (object != 0);
+
+ ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
+ assert (null != cluster);
+ if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)
+ if(subject != queryProcessor.getRootLibrary())
+ throw new ImmutableException("Trying to modify immutable resource key=" + subject);
+ try {
+ ClusterI c = cluster.addRelation(subject, predicate, object, session.clusterTranslator);
+ if (null != c && c != cluster)
+ session.clusterTable.replaceCluster(c);
+ } catch (DatabaseException e) {
+ LOGGER.error("claimImpl({}, {}, {}) failed", subject, predicate, object, e);
+ throw new RuntimeException(e);
+ }
+ queryProcessor.updateStatements(subject, predicate);
+ session.clientChanges.claim(subject, predicate, object);
+
+ }
+
+ final private void claimImpl2(int subject, int predicate, int object) {
+
+ assert (subject != 0);
+ assert (predicate != 0);
+ assert (object != 0);
+
+ ClusterI cluster = session.clusterTable.getClusterByResourceKey(subject);
+ try {
+ ClusterI c = cluster.addRelation(subject, predicate, object, session.clusterTranslator);
+ if (null != c && c != cluster)
+ session.clusterTable.replaceCluster(c);
+ } catch (DatabaseException e) {
+ LOGGER.error("claimImpl2({}, {}, {}) failed", subject, predicate, object, e);
+ }
+ if (cluster.isWriteOnly())
+ return;
+ queryProcessor.updateStatements(subject, predicate);
+
+ }
+
+ private boolean removeStatement(int subject, int predicate, int object) throws ImmutableException {
+
+ assert (subject != 0);
+ assert (predicate != 0);
+ assert (object != 0);
+
+ ClusterI cluster = session.clusterTable.getClusterByResourceKey(subject);
+ assert (null != cluster);
+
+ if (cluster.getImmutable() && (session.serviceMode & SessionImplSocket.SERVICE_MODE_ALLOW) == 0)
+ if(subject != queryProcessor.getRootLibrary())
+ throw new ImmutableException("Trying to modify immutable resource key=" + subject);
+
+ try {
+ cluster.denyRelation(subject, predicate, object, session.clusterTranslator);
+ } catch (DatabaseException e) {
+ LOGGER.error("removeStatement({}, {}, {}) failed", subject, predicate, object, e);
+ return false;
+ }
+ queryProcessor.updateStatements(subject, predicate);
+ return true;
+
+ }
+
+}