/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
*******************************************************************************/
package org.simantics.db.impl.graph;
-import gnu.trove.map.hash.TObjectIntHashMap;
-
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
-import java.nio.BufferUnderflowException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
import java.util.Set;
+import java.util.function.Consumer;
import org.eclipse.core.runtime.Platform;
import org.simantics.databoard.Accessors;
import org.simantics.databoard.util.binary.BinaryFile;
import org.simantics.databoard.util.binary.RandomAccessBinary;
import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ComputationalValue;
import org.simantics.db.DevelopmentKeys;
import org.simantics.db.ExternalValueSupport;
import org.simantics.db.ReadGraph;
import org.simantics.db.common.primitiverequest.ValueImplied;
import org.simantics.db.common.primitiverequest.VariantValueImplied;
import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
+import org.simantics.db.common.procedure.adapter.AsyncProcedureAdapter;
import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
import org.simantics.db.common.procedure.adapter.TransientCacheListener;
import org.simantics.db.common.procedure.single.SyncReadProcedure;
import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
+import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
+import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
import org.simantics.db.impl.ResourceImpl;
import org.simantics.db.impl.internal.RandomAccessValueSupport;
import org.simantics.db.impl.internal.ResourceData;
-import org.simantics.db.impl.procedure.CallWrappedSingleQueryProcedure4;
-import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4;
-import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4;
+import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
import org.simantics.db.impl.query.CacheEntry;
+import org.simantics.db.impl.query.QueryCache;
+import org.simantics.db.impl.query.QueryCacheBase;
import org.simantics.db.impl.query.QueryProcessor;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
import org.simantics.db.impl.query.QuerySupport;
import org.simantics.db.impl.query.TripleIntProcedure;
import org.simantics.db.impl.support.ResourceSupport;
import org.simantics.db.request.MultiRead;
import org.simantics.db.request.Read;
import org.simantics.db.request.ReadInterface;
-import org.simantics.db.request.RequestFlags;
import org.simantics.db.request.Write;
import org.simantics.db.request.WriteInterface;
import org.simantics.db.request.WriteOnly;
import org.simantics.scl.runtime.function.Function3;
import org.simantics.utils.DataContainer;
import org.simantics.utils.Development;
-import org.simantics.utils.datastructures.Callback;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.datastructures.collections.CollectionUtils;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+public class ReadGraphImpl implements AsyncReadGraph {
-public class ReadGraphImpl implements ReadGraph {
+ private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
final static boolean EMPTY_RESOURCE_CHECK = false;
final public CacheEntry parent;
+ public final ReadGraphImpl parentGraph;
final public QueryProcessor processor;
+ public final AsyncBarrierImpl asyncBarrier;
+
final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
try {
- return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
- id));
+ Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
+ // FIXME: stupid to throw this here and catch and wrap it right away
+ if(rid == 0) throw new ResourceNotFoundException(id);
+ return processor.querySupport.getResource(rid);
} catch (ResourceNotFoundException e) {
- throw new ResourceNotFoundException(e);
+ throw new ResourceNotFoundException(id, e);
} catch (ValidationException e) {
try {
- return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
- id));
+ return getResource(id);
} catch (ResourceNotFoundException e) {
}
}
+
+ @Override
+ public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
+
+ assert (resource != null);
+
+ try {
+
+ int rId = processor.querySupport.getId(resource);
+ return QueryCache.resultChildMap(this, rId, parent, null);
+
+ } catch (ValidationException e) {
+
+ throw new ValidationException(e);
+
+ } catch (ServiceException e) {
+
+ throw new ServiceException(e);
+
+ } catch (DatabaseException e) {
+
+ throw new ServiceException(INTERNAL_ERROR_STRING, e);
+
+ }
+
+ }
final public Resource getRootLibrary() {
return processor.getRootLibraryResource();
} catch (ResourceNotFoundException e) {
- throw new ResourceNotFoundException(e);
+ throw new ResourceNotFoundException(id, e);
} catch (ServiceException e) {
if( relation == null) throw new IllegalArgumentException("relation can not be null");
try {
-
int single = processor.getSingleObject(this, subject, relation);
- if(single == 0) throw new NoSingleResultException("subject=" + subject + " relation="+relation);
+ if (single == 0) {
+ if (EMPTY_RESOURCE_CHECK) {
+ if (!hasStatement(subject)) {
+ throw new EmptyResourceException("Resource " + debugString(subject));
+ }
+ }
+ throw new NoSingleResultException("No single object for subject " + debugString(subject)
+ + " and relation " + debugString(relation), single);
+ }
return processor.querySupport.getResource(single);
-
} catch (NoSingleResultException e) {
-
- if(EMPTY_RESOURCE_CHECK) {
- if(!hasStatement(subject)) throw new EmptyResourceException("Resource " + debugString(subject));
- }
-
- throw new NoSingleResultException("No single object for subject "
- + debugString(subject) + " and relation "
- + debugString(relation), e);
-
+ throw e;
} catch (DatabaseException e) {
-
throw new ServiceException(e);
-
}
-
}
@Override
- final public Statement getSingleStatement(final Resource subject,
- final Resource relation) throws NoSingleResultException,
- ManyObjectsForFunctionalRelationException, ServiceException {
-
+ final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
assert (subject != null);
assert (relation != null);
-
try {
-
Collection<Statement> statements = getStatements(subject, relation);
- if(statements.size() == 1) return statements.iterator().next();
- else throw new NoSingleResultException("");
-
- } catch (NoSingleResultException e) {
-
- if(EMPTY_RESOURCE_CHECK) {
- if(!hasStatement(subject)) throw new EmptyResourceException("Resource " + debugString(subject));
- }
-
- throw new NoSingleResultException("No single statement for subject "
- + debugString(subject) + " and relation "
- + debugString(relation), e);
-
- } catch (DatabaseException e) {
-
- throw new ServiceException(e);
-
- }
-
+ if (statements.size() == 1) {
+ return statements.iterator().next();
+ } else {
+ if (EMPTY_RESOURCE_CHECK)
+ if (!hasStatement(subject))
+ throw new EmptyResourceException("Resource " + debugString(subject));
+ throw new NoSingleResultException("No single statement for subject " + debugString(subject)
+ + " and relation " + debugString(relation), statements.size());
+ }
+ } catch (ServiceException e) {
+ throw new ServiceException(e);
+ }
}
@Override
- final public Resource getSingleType(final Resource subject) throws NoSingleResultException,
- ServiceException {
-
+ final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
assert (subject != null);
-
try {
-
ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
- if(principalTypes.size() == 1) return principalTypes.get(0);
- else throw new NoSingleResultException("");
-
- } catch (NoSingleResultException e) {
-
- throw new NoSingleResultException(e);
-
+ if (principalTypes.size() == 1) {
+ return principalTypes.get(0);
+ } else {
+ throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
+ }
} catch (ServiceException e) {
-
throw new ServiceException(e);
-
}
-
}
@Override
assert (baseType != null);
try {
-
return syncRequest(new SingleType(subject, baseType));
-
- } catch (NoSingleResultException e) {
-
- throw new NoSingleResultException(new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, e));
-
- } catch (ServiceException e) {
-
- throw new ServiceException(e);
-
} catch (DatabaseException e) {
-
- throw new ServiceException(INTERNAL_ERROR_STRING, e);
-
+ throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
}
-
}
@Override
assert (subject != null);
+ byte[] bytes = null;
try {
- byte[] bytes = processor.getValue(this, subject);
+ bytes = processor.getValue(this, subject);
if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
Serializer serializer = getSerializer(binding);
throw new DoesNotContainValueException(e);
- } catch (IOException e) {
-
- throw new ServiceException(e);
-
- } catch (DatabaseException e) {
-
- throw new ServiceException(e);
-
- } catch (BufferUnderflowException e) {
- // This is sometimes thrown when deserialize fails because wrong format.
- // For callers of this method this is just an service exception.
- throw new ServiceException(e);
- }
-
+ } catch (Throwable t) {
+ throw new ServiceException("Could not getValue for subject " + debugString(subject) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(bytes), t);
+ }
}
@Override
assert (relation != null);
try {
-
Resource object = getSingleObject(subject, relation);
return getValue(object);
-
} catch (NoSingleResultException e) {
-
- throw new NoSingleResultException(e);
-
+ throw new NoSingleResultException("No single value found for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
} catch (DoesNotContainValueException e) {
-
try {
Layer0 L0 = processor.getL0(this);
Resource object = getPossibleObject(subject, relation);
if(isInstanceOf(object, L0.Literal)) {
throw new DoesNotContainValueException(e);
} else {
- throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)");
+ throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
}
} else {
- throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value");
+ throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
}
} catch (DoesNotContainValueException e2) {
throw e2;
} catch (DatabaseException e2) {
throw new InternalException("The client failed to analyse the cause of the following exception", e);
}
-
} catch (ServiceException e) {
-
throw new ServiceException(e);
-
- }
-
+ }
}
@Override
assert (relation != null);
try {
-
Resource object = getSingleObject(subject, relation);
return getVariantValue(object);
-
} catch (NoSingleResultException e) {
-
- throw new NoSingleResultException(e);
-
+ throw new NoSingleResultException("No single object for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
} catch (DoesNotContainValueException e) {
-
try {
Layer0 L0 = processor.getL0(this);
Resource object = getPossibleObject(subject, relation);
if(isInstanceOf(object, L0.Literal)) {
throw new DoesNotContainValueException(e);
} else {
- throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)");
+ throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
}
} else {
- throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value");
+ throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
}
} catch (DoesNotContainValueException e2) {
throw e2;
} catch (DatabaseException e2) {
throw new InternalException("The client failed to analyse the cause of the following exception", e);
}
-
} catch (ServiceException e) {
-
throw new ServiceException(e);
-
}
-
}
@Override
assert (relation != null);
try {
-
Resource object = getSingleObject(subject, relation);
return getValue(object, binding);
-
} catch (NoSingleResultException e) {
-
String message = "";
-
try {
-
String subjectName = NameUtils.getSafeName(this, subject, true);
String relationName = NameUtils.getSafeName(this, relation, true);
message = "Subject: " + subjectName + ", Relation: " + relationName;
-
} catch (DatabaseException e2) {
}
-
- throw new NoSingleResultException(message);
-
+ throw new NoSingleResultException(message, e.getResultCount(), e);
} catch (DoesNotContainValueException e) {
-
throw new DoesNotContainValueException(e);
-
} catch (ServiceException e) {
-
throw new ServiceException(e);
-
- } catch (DatabaseException e) {
-
- throw new ServiceException(INTERNAL_ERROR_STRING, e);
-
}
-
}
@Override
try {
- int result = processor.getSingleObject(this, subject, relation);
- if(result == 0) return null;
-
- return processor.querySupport.getResource(result);
+ int result = processor.getSingleObject(this, subject, relation);
+ if(result == 0) return null;
- } catch (ManyObjectsForFunctionalRelationException e) {
+ return processor.querySupport.getResource(result);
+
+ } catch (ManyObjectsForFunctionalRelationException e) {
+
+ throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
- throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
-
} catch (DatabaseException e) {
throw new ServiceException(e);
}
- final AsyncProcedure NONE = new AsyncProcedure() {
+ final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
@Override
public void execute(AsyncReadGraph graph, Object result) {
* Implementation of the interface RequestProcessor
*/
- @Override
- public <T> T syncRequest(final Read<T> request) throws DatabaseException {
-
- assert (request != null);
-
- if (parent != null) {
-
- try {
- return processor.queryRead(this, request, parent, null, null);
- } catch (Throwable e) {
- if(e instanceof DatabaseException) throw (DatabaseException)e;
- else throw new DatabaseException(e);
- }
-
- } else {
-
- try {
-
- return processor.tryQuery(this, request);
-
- } catch (Throwable throwable) {
-
- //Logger.defaultLogError("Internal read request failure", throwable);
-
- if (throwable instanceof DatabaseException)
- throw (DatabaseException) throwable;
- else
- throw new DatabaseException(
- "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
- throwable);
-
- }
-
- }
-
- }
+ @Override
+ public <T> T syncRequest(final Read<T> request) throws DatabaseException {
+ assert (request != null);
+ return (T)QueryCache.runnerReadEntry(this, request, parent, null, null, true);
+ }
@Override
public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
return syncRequest(request, new NoneToAsyncListener<T>(procedure));
}
- @Override
- public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
-
- assert (request != null);
-
- ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
-
- if (parent != null || listener != null) {
-
- try {
- return processor.queryRead(this, request, parent, procedure, listener);
- } catch (Throwable e) {
- if(e instanceof DatabaseException) throw (DatabaseException)e;
- else throw new DatabaseException(e);
- }
-
- } else {
-
- try {
-
- T t = processor.tryQuery(this, request);
- if(procedure != null)
- procedure.execute(this, t);
-
- return t;
-
- } catch (Throwable throwable) {
-
- Logger.defaultLogError("Internal read request failure", throwable);
-
- if(procedure != null)
- procedure.exception(this, throwable);
-
- if (throwable instanceof DatabaseException)
- throw (DatabaseException) throwable;
- else
- throw new DatabaseException(
- "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
- throwable);
-
- }
-
- }
-
- }
+ @Override
+ public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
+ assert (request != null);
+ ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
+ return (T)QueryCache.runnerReadEntry(this, request, parent, listener, procedure, true);
+ }
@Override
public <T> T syncRequest(final Read<T> request,
throw (DatabaseException) exception;
else
throw new DatabaseException(
- "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
+ "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
exception);
}
}
throws DatabaseException {
assert (request != null);
- AsyncReadProcedure<T> procedure = new AsyncReadProcedure<T>();
- syncRequest(request, procedure);
- procedure.checkAndThrow();
- return procedure.result;
-
-// return syncRequest(request, new AsyncProcedureAdapter<T>());
+ return syncRequest(request, new AsyncProcedureAdapter<>() );
}
return syncRequest(request, new NoneToAsyncListener<T>(procedure));
}
- @Override
- final public <T> T syncRequest(final AsyncRead<T> request,
- final AsyncProcedure<T> procedure) throws DatabaseException {
-
- assert (request != null);
-
- // System.out.println("syncRequest " + request + " syncParent=" +
- // syncParent);
-
- ListenerBase listener = getListenerBase(procedure);
-
- if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
-
- Object syncParent = request;
-
-// final ReadGraphImpl newGraph = newSync();
-
- final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
- procedure, request);
-
- processor.query(this, request, parent, wrapper, listener);
-
-// newGraph.waitAsync(syncParent);
-
- Throwable e = wrapper.getException();
- if (e != null) {
- // The request was async - produce meaningful stack trace by
- // wrapping
- if (e instanceof DatabaseException)
- throw (DatabaseException) e;
- else
- throw new DatabaseException(e);
- }
-
- return wrapper.getResult();
-
- } else {
-
- // System.out.println("direct call " + request );
-
- // Do not set the sync state.parent for external threads
- Object syncParent = request;
-
-// final ReadGraphImpl newGraph = newSync();
-
- final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
- procedure, request);
-
- try {
-
- processor.tryQuery(this, request, wrapper);
-
- } catch (Throwable t) {
-
- wrapper.exception(this, t);
-
- }
-
- Throwable e = wrapper.getException();
- if (e != null) {
- // The request was async - produce meaningful stack trace by
- // wrapping
- if (e instanceof DatabaseException)
- throw (DatabaseException) e;
- else
- throw new DatabaseException(e);
- }
-
- return wrapper.getResult();
-
- }
-
- }
-
- final private <T> void syncRequest(final AsyncRead<T> request, final AsyncReadProcedure<T> procedure) throws DatabaseException {
-
- assert (request != null);
-
- // System.out.println("syncRequest " + request + " syncParent=" +
- // syncParent);
-
- ListenerBase listener = getListenerBase(procedure);
-
- if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
-
-// final ReadGraphImpl newGraph = newSync();
-
- final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
- procedure, request);
-
- processor.query(this, request, parent, wrapper, listener);
-
- } else {
-
- try {
-
-// final ReadGraphImpl newGraph = newSync();
- processor.tryQuery(this, request, procedure);
-// newGraph.waitAsync(null);
- waitAsyncProcedure(procedure);
-
- } catch (Throwable t) {
- if(Development.DEVELOPMENT) {
- if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
- t.printStackTrace();
- }
- }
- procedure.exception(this, t);
- waitAsyncProcedure(procedure);
- }
-
- }
-
- }
+ @Override
+ final public <T> T syncRequest(final AsyncRead<T> request,
+ final AsyncProcedure<T> procedure) throws DatabaseException {
+ assert (request != null);
+ ListenerBase listener = getListenerBase(procedure);
+ return (T)QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure, true);
+ }
@Override
public <T> T syncRequest(AsyncRead<T> request,
final ArrayList<T> result = new ArrayList<T>();
final DataContainer<Throwable> exception = new DataContainer<Throwable>();
- syncRequest(request, new AsyncMultiProcedure<T>() {
+ syncRequest(request, new SyncMultiProcedure<T>() {
@Override
- public void execute(AsyncReadGraph graph, T t) {
+ public void execute(ReadGraph graph, T t) {
synchronized (result) {
result.add(t);
}
}
@Override
- public void finished(AsyncReadGraph graph) {
+ public void finished(ReadGraph graph) {
}
@Override
- public void exception(AsyncReadGraph graph, Throwable t) {
+ public void exception(ReadGraph graph, Throwable t) {
exception.set(t);
}
}
- @Override
- public <T> Collection<T> syncRequest(MultiRead<T> request,
- AsyncMultiListener<T> procedure) {
- return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
- }
-
@Override
public <T> Collection<T> syncRequest(MultiRead<T> request,
SyncMultiListener<T> procedure) {
- return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
+ return syncRequest(request, (SyncMultiProcedure<T>)procedure);
}
@Override
public <T> Collection<T> syncRequest(MultiRead<T> request,
MultiListener<T> procedure) {
- return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
+ return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
}
@Override
public <T> Collection<T> syncRequest(MultiRead<T> request,
- AsyncMultiProcedure<T> procedure) {
+ SyncMultiProcedure<T> procedure) {
assert (request != null);
ListenerBase listener = getListenerBase(procedure);
+ final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
+
if (parent != null || listener != null) {
- Object syncParent = request;
+// Object syncParent = request;
// final ReadGraphImpl newGraph = newSync();
- processor.query(this, request, parent, procedure, listener);
+ processor.query(this, request, parent, wrapper, listener);
// newGraph.waitAsync(syncParent);
} else {
- Object syncParent = request;
+// Object syncParent = request;
// final ReadGraphImpl newGraph = newSync();
- final ResultCallWrappedQueryProcedure4<T> wrapper = new ResultCallWrappedQueryProcedure4<T>(procedure);
-
try {
-
request.perform(this, wrapper);
-
} catch (Throwable t) {
-
wrapper.exception(this, t);
-// newGraph.waitAsync(syncParent);
-
}
}
- // TODO
- return null;
-
- }
+ return wrapper.get();
- @Override
- public <T> Collection<T> syncRequest(MultiRead<T> request,
- SyncMultiProcedure<T> procedure) {
- return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
}
@Override
public <T> Collection<T> syncRequest(MultiRead<T> request,
MultiProcedure<T> procedure) {
- return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
+ return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
}
static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
if (parent != null || listener != null) {
- Object syncParent = request;
+// Object syncParent = request;
// final ReadGraphImpl newGraph = newSync();
if (parent != null || listener != null) {
- Object syncParent = request;
+// Object syncParent = request;
// final ReadGraphImpl newGraph = newSync();
} else {
- Object syncParent = request;
+// Object syncParent = request;
// final ReadGraphImpl newGraph = newSync();
final public <T> T syncRequest(final ExternalRead<T> request,
final Procedure<T> procedure) throws DatabaseException {
- assert (request != null);
-
- ListenerBase listener = getListenerBase(procedure);
-
- final DataContainer<Throwable> exception = new DataContainer<Throwable>();
- final DataContainer<T> result = new DataContainer<T>();
-
- if (parent != null || listener != null) {
-
-// final ReadGraphImpl newGraph = newSync();
-
- processor.query(this, request, parent, new Procedure<T>() {
-
- @Override
- public void exception(Throwable throwable) {
- exception.set(throwable);
- procedure.exception(throwable);
- }
-
- @Override
- public void execute(T t) {
- result.set(t);
- procedure.execute(t);
- }
-
- }, listener);
-
-// newGraph.waitAsync(request);
-
- } else {
-
- try {
-
- T t = processor.tryQuery(this, request);
- result.set(t);
- procedure.execute(t);
-
- } catch (Throwable t) {
-
- if (t instanceof DatabaseException) {
- exception.set((DatabaseException)t);
- procedure.exception(exception.get());
- } else {
- exception.set(new DatabaseException(
- "Unexpected exception in ReadGraph.syncRequest(Read)",
- t));
- procedure.exception(exception.get());
- }
-
- }
-
- }
-
- Throwable t = exception.get();
- if (t != null) {
- if (t instanceof DatabaseException)
- throw (DatabaseException) t;
- else
- throw new DatabaseException(
- "Unexpected exception in ReadGraph.syncRequest(Read)",
- t);
- }
+ assert (request != null);
- return result.get();
+ ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
+ return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
}
}
-// @Override
-// final public void forEachDirectObject(final Resource subject,
-// final Resource relation,
-// final AsyncMultiProcedure<Resource> procedure) {
-//
-// processor.forEachDirectObject(this, subject, relation, procedure);
-//
-// }
-//
-// @Override
-// public void forEachDirectObject(Resource subject, Resource relation,
-// SyncMultiProcedure<Resource> procedure) {
-// forEachDirectObject(subject, relation,
-// new SyncToAsyncMultiProcedure<Resource>(procedure));
-// }
-//
-// @Override
-// public void forEachDirectObject(Resource subject, Resource relation,
-// MultiProcedure<Resource> procedure) {
-// forEachDirectObject(subject, relation,
-// new NoneToAsyncMultiProcedure<Resource>(procedure));
-// }
-
@Override
- final public void forEachDirectPredicate(final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
+ final public void forEachDirectPredicate(final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
processor.forEachDirectPredicate(this, subject, procedure);
}
@Override
- public void forEachDirectPredicate(Resource subject, SyncMultiProcedure<Resource> procedure) {
- forEachDirectPredicate(subject, new SyncToAsyncMultiProcedure<Resource>(procedure));
+ final public void forEachDirectPredicate(final Resource subject, final SyncProcedure<Set<Resource>> procedure) {
+ forEachDirectPredicate(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
}
@Override
- public void forEachDirectPredicate(Resource subject, MultiProcedure<Resource> procedure) {
- forEachDirectPredicate(subject, new NoneToAsyncMultiProcedure<Resource>(procedure));
+ public void forEachDirectPredicate(Resource subject, Procedure<Set<Resource>> procedure) {
+ forEachDirectPredicate(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
}
@Override
// else
procedure.execute(graph, (T) obj);
- } catch (IOException e) {
- procedure.exception(graph, e);
- } catch (BufferUnderflowException e) {
- procedure.exception(graph, e);
} catch (Throwable t) {
- procedure.exception(graph, t);
+ procedure.exception(graph, new ServiceException("Could not forValue for subject " + debugString(resource) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(result), t));
}
-
}
@Override
});
}
+
+ private static String safeArrayToString(byte[] a) {
+ if (a == null)
+ return "null";
+ int iMax = a.length - 1;
+ if (iMax == -1)
+ return "[]";
+
+ StringBuilder b = new StringBuilder();
+ b.append('[');
+ for (int i = 0; i < 100; i++) { // limit to first 100 items
+ b.append(a[i]);
+ if (i == iMax)
+ return b.append(']').toString();
+ b.append(", ");
+ }
+ return b.append(", ... (" + a.length + ")]").toString();
+ }
@Override
public <T> void forValue(Resource subject, Binding binding,
else
procedure.execute(graph, (T) obj);
- } catch (IOException e) {
- procedure.exception(graph, e);
- } catch (BufferUnderflowException e) {
- procedure.exception(graph, e);
} catch (Throwable t) {
- procedure.exception(graph, t);
+ procedure.exception(graph, new ServiceException("Could not forValue for subject " + debugString(resource) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(result), t));
}
-
}
@Override
listener);
}
-// @Override
-// final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
-// final AsyncProcedure<T> procedure) {
-//
-// forPossibleRelatedValue(subject, relation, binding, procedure, false);
-//
-// }
-
final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
final AsyncProcedure<T> procedure) {
return processor.getSession();
}
-// @Override
-// final public Builtins getBuiltins() {
-// return processor.getSession().getBuiltins();
-// }
-
@Override
public <T> void asyncRequest(final Read<T> request) {
assert (request != null);
assert (procedure != null);
+
+ AsyncBarrierImpl barrier = asyncBarrier;
+ if(barrier != null)
+ barrier.inc();
+
+ processor.scheduleNow(new SessionTask(this) {
- final ListenerBase listener = getListenerBase(procedure);
-
- if (parent != null || listener != null) {
-
- try {
- processor.queryRead(this, request, parent, procedure,
- listener);
- } catch (Throwable e) {
- // This throwable has already been transferred to procedure at this point - do nothing about it
- //Logger.defaultLogError("Internal error ", e);
- }
-
- } else {
-
-// final ReadGraphImpl newGraph = newSync();
-
- try {
-
- T result = request.perform(this);
-
- try {
- procedure.execute(this, result);
- } catch (Throwable t) {
- Logger.defaultLogError(t);
- }
-
- } catch (Throwable t) {
-
+ @Override
+ public void run0(int thread) {
try {
- procedure.exception(this, t);
- } catch (Throwable t2) {
- Logger.defaultLogError(t2);
+ final ListenerBase listener = getListenerBase(procedure);
+ QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
+ } catch (DatabaseException e) {
+ Logger.defaultLogError(e);
+ } finally {
+ if(barrier != null)
+ barrier.dec();
}
-
- } finally {
-
}
-
- }
+
+ });
}
public static ReadGraphImpl createAsync(QueryProcessor support) {
- return new ReadGraphImpl(null, support);
- }
-
- public static ReadGraphImpl forRecompute(CacheEntry entry, QueryProcessor support) {
- return new ReadGraphImpl(entry, support);
+ return new ReadGraphImpl(null, null, support);
}
@Override
asyncRequest(request, new NoneToAsyncListener<T>(procedure));
}
- @Override
- final public <T> void asyncRequest(final AsyncRead<T> request,
- final AsyncProcedure<T> procedure) {
-
- assert (request != null);
- assert (procedure != null);
-
- final ListenerBase listener = getListenerBase(procedure);
-
- if (parent != null || listener != null) {
+ @Override
+ final public <T> void asyncRequest(final AsyncRead<T> request,
+ final AsyncProcedure<T> procedure) {
- processor.query(this, request, parent, procedure, listener);
+ assert (request != null);
+ assert (procedure != null);
- } else {
+ AsyncBarrierImpl barrier = asyncBarrier;
+ if(barrier != null)
+ barrier.inc();
- try {
-
- request.perform(this, new CallWrappedSingleQueryProcedure4<T>(procedure, request));
+ processor.scheduleNow(new SessionTask(this) {
- } catch (Throwable t) {
+ @Override
+ public void run0(int thread) {
- if (t instanceof DatabaseException)
- procedure.exception(this, t);
- else
- procedure
- .exception(
- this,
- new DatabaseException(
- "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
- t));
+ if(barrier != null)
+ barrier.inc();
- }
+ try {
+ final ListenerBase listener = getListenerBase(procedure);
+ QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, new AsyncProcedure<T>() {
+
+ @Override
+ public void execute(AsyncReadGraph graph, T result) {
+ procedure.execute(graph, result);
+ if(barrier != null)
+ barrier.dec();
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ procedure.exception(graph, throwable);
+ if(barrier != null)
+ barrier.dec();
+ }
+
+ }, false);
+ } catch (DatabaseException e) {
+ LOGGER.error("Error while executing async request", e);
+ } finally {
+ if(barrier != null)
+ barrier.dec();
+ }
+ }
- }
+ });
- }
+ }
@Override
public <T> void asyncRequest(AsyncRead<T> request,
assert (request != null);
- asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
+ asyncRequest(request, new SyncMultiProcedureAdapter<T>() {
@Override
- public void exception(AsyncReadGraph graph, Throwable t) {
+ public void exception(ReadGraph graph, Throwable t) {
Logger.defaultLogError(t);
}
}
- @Override
- public <T> void asyncRequest(MultiRead<T> request,
- AsyncMultiListener<T> procedure) {
- asyncRequest(request, (AsyncMultiProcedure<T>) procedure);
- }
-
@Override
public <T> void asyncRequest(MultiRead<T> request,
SyncMultiListener<T> procedure) {
- asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
+ asyncRequest(request, (SyncMultiProcedure<T>)procedure);
}
@Override
public <T> void asyncRequest(MultiRead<T> request,
MultiListener<T> procedure) {
- asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
+ asyncRequest(request, new NoneToSyncMultiListener<T>(procedure));
}
+
@Override
public <T> void asyncRequest(final MultiRead<T> request,
- final AsyncMultiProcedure<T> procedure) {
+ final SyncMultiProcedure<T> procedure) {
assert (request != null);
assert (procedure != null);
} catch (Throwable t) {
- procedure.exception(this, t);
+ try {
+ procedure.exception(this, t);
+ } catch (DatabaseException e) {
+ LOGGER.error("Unexpected exception while handling exception", e);
+ }
}
}
- @Override
- public <T> void asyncRequest(MultiRead<T> request,
- SyncMultiProcedure<T> procedure) {
- asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
- }
-
@Override
public <T> void asyncRequest(MultiRead<T> request,
MultiProcedure<T> procedure) {
- asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
+ asyncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
}
@Override
assert (request != null);
assert (procedure != null);
- ListenerBase listener = getListenerBase(procedure);
+ final ListenerBase listener = getListenerBase(procedure);
if (parent != null || listener != null) {
- processor.query(this, request, parent, procedure, listener);
-
- } else {
-
try {
+ QueryCacheBase.resultExternalReadEntry(this, request, parent, listener, procedure);
+ } catch (DatabaseException e) {
+ Logger.defaultLogError(e);
+ // This throwable has already been transferred to procedure at this point - do nothing about it
+ }
- request.register(this, new Listener<T>() {
-
- @Override
- public void execute(T result) {
- procedure.execute(result);
- }
-
- @Override
- public void exception(Throwable t) {
- procedure.exception(t);
- }
-
- @Override
- public String toString() {
- return "asyncRequest(PrimitiveRead) -> " + request;
- }
+ } else {
- @Override
- public boolean isDisposed() {
- return true;
- }
+ request.register(this, new Listener<T>() {
+ @Override
+ public void execute(T result) {
+ procedure.execute(result);
+ }
- });
+ @Override
+ public void exception(Throwable t) {
+ procedure.exception(t);
+ }
- } catch (Throwable t) {
+ @Override
+ public String toString() {
+ return "asyncRequest(PrimitiveRead) -> " + request;
+ }
- if (t instanceof DatabaseException)
- procedure.exception(t);
- else
- procedure
- .exception(new DatabaseException(
- "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
- t));
+ @Override
+ public boolean isDisposed() {
+ return true;
+ }
- }
+ });
}
}
@Override
- public void asyncRequest(Write request, Callback<DatabaseException> callback) {
+ public void asyncRequest(Write request, Consumer<DatabaseException> callback) {
assert (request != null);
@Override
public void asyncRequest(DelayedWrite r,
- Callback<DatabaseException> callback) {
+ Consumer<DatabaseException> callback) {
throw new Error("Not implemented.");
}
}
@Override
- public void asyncRequest(WriteOnly r, Callback<DatabaseException> callback) {
+ public void asyncRequest(WriteOnly r, Consumer<DatabaseException> callback) {
throw new Error("Not implemented.");
}
* Internal routines
*/
- protected static String INTERNAL_ERROR_STRING = "Transaction aborted due to internal client error. Contact application support.";
+ protected static String INTERNAL_ERROR_STRING = "Transaction aborted due to internal client error.";
/*
* callerThread is the currently running thread state.syncThread is blocking for
* this execution state.syncParent is the blocking request
*/
- final private boolean isExternal(int thread) {
- return thread == Integer.MIN_VALUE;
- }
-
-// final private boolean isSync(int thread) {
-// return thread < -1 && thread > Integer.MIN_VALUE;
-// }
-
- ReadGraphImpl(ReadGraphImpl graph) {
- this(graph.parent, graph.processor);
- }
-
- ReadGraphImpl(CacheEntry parent, QueryProcessor support) {
-// this.state = new ReadGraphState(barrier, support);
+ ReadGraphImpl(ReadGraphImpl parentGraph, CacheEntry parent, QueryProcessor support) {
+ this.parentGraph = parentGraph;
this.parent = parent;
this.processor = support;
- }
-
- ReadGraphImpl(final QueryProcessor support) {
-
-// this.state = state;
- this.processor = support;
- this.parent = null;
-
+ this.asyncBarrier = prepareBarrier(parentGraph, parent, null, false);
}
-// public static ReadGraphImpl createSync(int syncThread, Object syncParent,
-// ReadGraphSupportImpl support) {
-// return new ReadGraphImpl(syncThread, syncThread, syncParent, null,
-// support, new AsyncBarrierImpl(null));
-// }
+ ReadGraphImpl(ReadGraphImpl parentGraph, CacheEntry parent, QueryProcessor support, AsyncBarrierImpl asyncBarrier) {
+ this.parentGraph = parentGraph;
+ this.parent = parent;
+ this.processor = support;
+ this.asyncBarrier = asyncBarrier;
+ }
- public static ReadGraphImpl create(QueryProcessor support) {
- return new ReadGraphImpl(support);
+ ReadGraphImpl(ReadGraphImpl graph, CacheEntry parent) {
+ this(graph, parent, graph.processor);
}
-// public ReadGraphImpl newAsync() {
-// return this;
-//// if(!state.synchronizedExecution) {
-//// return this;
-//// } else {
-//// return new ReadGraphImpl(false, parent, state.support, state.barrier);
-//// }
-// }
+ ReadGraphImpl(ReadGraphImpl parentGraph, CacheEntry parent, Runnable callback, boolean needsToBlock) {
+ this(parentGraph, parent, parentGraph.processor, prepareBarrier(parentGraph, parent, callback, needsToBlock));
+ }
+
+ static AsyncBarrierImpl prepareBarrier(ReadGraphImpl parentGraph, CacheEntry parent, Runnable callback, boolean needsToBlock) {
+ return new AsyncBarrierImpl(parentGraph != null ? parentGraph.asyncBarrier : null, parent, callback, needsToBlock);
+ }
+
+ ReadGraphImpl(ReadGraphImpl graph) {
+ this(graph, graph.parent);
+ }
-// public ReadGraphImpl newSync() {
-// return new ReadGraphImpl(parent, processor);
-// }
+ public ReadGraphImpl withParent(CacheEntry parent, Runnable callback, boolean needsToBlock) {
+ return new ReadGraphImpl(this, parent, callback, needsToBlock);
+ }
- public ReadGraphImpl newSync(CacheEntry parentEntry) {
- return new ReadGraphImpl(parentEntry, processor);
+ public ReadGraphImpl forRecompute(CacheEntry parent) {
+ return new ReadGraphImpl(null, parent, processor);
}
+ public static ReadGraphImpl create(QueryProcessor support) {
+ ReadGraphImpl result = new ReadGraphImpl(null, null, support);
+ return result;
+ }
+
public ReadGraphImpl newRestart(ReadGraphImpl impl) {
WriteGraphImpl write = processor.getSession().getService(
WriteGraphImpl.class);
-// if (write.callerThread != impl.callerThread)
-// return new WriteGraphImpl(impl.callerThread, parent, state.support, write.writeSupport, write.provider, write.state.barrier);
return write;
}
-// public ReadGraphImpl newSync(Object parentRequest) {
-// return new ReadGraphImpl(callerThread, state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-// }
-
-// public ReadGraphImpl newSync(final int callerThread, Object parentRequest) {
-// assert (state.syncThread == callerThread || (state.syncThread == Integer.MIN_VALUE && callerThread != Integer.MIN_VALUE));
-// return new ReadGraphImpl(callerThread, callerThread, parentRequest,
-// state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-// }
-//
-// public ReadGraphImpl newSyncAsync(Object parentRequest) {
-//// assert (callerThread < 0);
-// return new ReadGraphImpl(callerThread, state.syncThread, parentRequest,
-// state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-// }
-//
-// public ReadGraphImpl newSyncAsync(final int callerThread,
-// Object parentRequest) {
-//// assert (callerThread < 0);
-// // assert(state.syncThread == callerThread || (state.syncThread == Integer.MIN_VALUE
-// // && callerThread != Integer.MIN_VALUE) );
-// return new ReadGraphImpl(callerThread, callerThread, parentRequest,
-// state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-// }
-
- public ReadGraphImpl withAsyncParent(CacheEntry parent) {
- return new ReadGraphImpl(parent, processor);
- }
-
- public ReadGraphImpl withParent(CacheEntry parent) {
- if(parent == this.parent) return this;
- else return new ReadGraphImpl(parent, processor);
- }
-
final private ListenerBase getListenerBase(final Object procedure) {
if (procedure instanceof ListenerBase)
return (ListenerBase) procedure;
assert(procedure.done());
-// while (!procedure.done()) {
-//
-// boolean executed = processor.resumeTasks(callerThread, null, null);
-// if (!executed) {
-// try {
-// Thread.sleep(1);
-// // sema.tryAcquire(1, TimeUnit.MILLISECONDS);
-// } catch (InterruptedException e) {
-// e.printStackTrace();
-// }
-// }
-//
-// }
-
}
public <T> void waitAsyncProcedure(AsyncReadProcedure<T> procedure) {
assert(procedure.done());
-// while (!procedure.done()) {
-//
-// boolean executed = processor.processor.resume(this);
-// if (!executed) {
-// try {
-// Thread.sleep(1);
-// // sema.tryAcquire(1, TimeUnit.MILLISECONDS);
-// } catch (InterruptedException e) {
-// e.printStackTrace();
-// }
-// }
-//
-// }
-
}
-
-// public void waitAsync(Object request) {
-// try {
-// state.barrier.waitBarrier(request, this);
-// } catch (Throwable t) {
-// t.printStackTrace();
-// processor.scanPending();
-// processor.querySupport.checkTasks();
-// throw new RuntimeDatabaseException(t);
-// }
-// }
-
-// public void restart() {
-// state.barrier.restart();
-// }
public boolean resumeTasks() {
return processor.resumeTasks(this);
}
Serializer serializer = binding.serializer();
byte[] bytes = serializer.serialize(initialValue);
+ // In case the file has been previously accessed and was larger we set the correct size now
+ rd.binaryFile.setLength(bytes.length);
rd.binaryFile.write(bytes);
ravs.put(resource, rd);
return rd;
}
}
- @SuppressWarnings("unchecked")
@Override
public Variant getVariantValue2(Resource r, Object context) throws DatabaseException {
Layer0 L0 = processor.getL0(this);
return getValue(r, binding);
}
} else if(types.contains(L0.ExternalValue)) {
- try {
- return (T)ReflectionUtils.getValue(getURI(r)).getValue();
- } catch(ValueNotFoundException e) {
- throw new DatabaseException(e);
- } catch(ClassCastException e) {
- throw new DatabaseException(e);
+ ComputationalValue cv = syncRequest(new PossibleAdapter<ComputationalValue>(r, ComputationalValue.class), TransientCacheAsyncListener.instance());
+ if(cv != null) {
+ return cv.getValue(this, r);
+ } else {
+ // This should not even be possible since L0 defines an adapter for all values
+ try {
+ return (T)ReflectionUtils.getValue(getURI(r)).getValue();
+ } catch(ValueNotFoundException e) {
+ throw new DatabaseException(e);
+ } catch(ClassCastException e) {
+ throw new DatabaseException(e);
+ }
}
}
else {
@Override
public <T> T getRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
if(Development.DEVELOPMENT) {
- String error = L0Validations.checkValueType(this, subject, relation);
- if(error != null) {
- Logger.defaultLogError(new ValidationException(error));
- //throw new ValidationException(error);
- new ValidationException(error).printStackTrace();
+ if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
+ String error = L0Validations.checkValueType(this, subject, relation);
+ if(error != null) {
+ Logger.defaultLogError(new ValidationException(error));
+ throw new ValidationException(error);
+ }
}
}
return getValue2(getSingleObject(subject, relation), context);
@Override
public Variant getRelatedVariantValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
if(Development.DEVELOPMENT) {
- String error = L0Validations.checkValueType(this, subject, relation);
- if(error != null) {
- Logger.defaultLogError(new ValidationException(error));
- //throw new ValidationException(error);
- new ValidationException(error).printStackTrace();
- }
+ if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
+ String error = L0Validations.checkValueType(this, subject, relation);
+ if(error != null) {
+ Logger.defaultLogError(new ValidationException(error));
+ throw new ValidationException(error);
+ }
+ }
}
return getVariantValue2(getSingleObject(subject, relation), context);
}
throw new DatabaseException(e);
}
}
-
+
+ private static ThreadLocal<Boolean> syncGraph = new ThreadLocal<Boolean>() {
+ protected Boolean initialValue() {
+ return true;
+ }
+ };
+
@Override
public boolean setSynchronous(boolean value) {
- boolean old = processor.synch;
- processor.synch = value;
+ boolean old = getSynchronous();
+ syncGraph.set(value);
return old;
}
-
+
@Override
public boolean getSynchronous() {
- return processor.synch;
+ return syncGraph.get();
}
public void ensureLoaded(int resource) {
public Object getModificationCounter() {
return processor.getSession().getModificationCounter();
}
+
+ @Override
+ public boolean performPending() {
+ return processor.performPending(this);
+ }
+
+ public Set<ReadGraphImpl> ancestorSet() {
+ HashSet<ReadGraphImpl> result = new HashSet<>();
+ ReadGraphImpl g = this;
+ while(g != null) {
+ result.add(g);
+ g = g.parentGraph;
+ }
+ return result;
+ }
+
+ public int getLevel() {
+ return getLevelStatic(this);
+ }
+
+ private static int getLevelStatic(ReadGraphImpl impl) {
+ if(impl == null) return 0;
+ else return 1 + getLevelStatic(impl.parentGraph);
+ }
+
+ public boolean isParent(ReadGraphImpl impl) {
+ if(impl == null) return false;
+ if(this == impl) return true;
+ return isParent(impl.parentGraph);
+ }
+ public ReadGraphImpl getTopLevelGraph() {
+ return getTopLevelGraphStatic(this);
+ }
+
+ private static ReadGraphImpl getTopLevelGraphStatic(ReadGraphImpl impl) {
+ if(impl.parentGraph == null) return impl;
+ else return getTopLevelGraphStatic(impl.parentGraph);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T l0() {
+ return (T) processor.getL0();
+ }
+
}