/******************************************************************************* * 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 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.impl.graph; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; 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.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.Bindings; import org.simantics.databoard.accessor.Accessor; import org.simantics.databoard.accessor.error.AccessorConstructionException; import org.simantics.databoard.adapter.AdaptException; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; import org.simantics.databoard.binding.impl.ObjectVariantBinding; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.binary.BinaryFile; import org.simantics.databoard.util.binary.RandomAccessBinary; import org.simantics.db.AsyncReadGraph; import org.simantics.db.DevelopmentKeys; import org.simantics.db.ExternalValueSupport; import org.simantics.db.ReadGraph; import org.simantics.db.RelationContext; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.Statement; import org.simantics.db.adaption.AdaptionService; import org.simantics.db.common.primitiverequest.Adapter; import org.simantics.db.common.primitiverequest.Builtin; import org.simantics.db.common.primitiverequest.DatatypeBinding; import org.simantics.db.common.primitiverequest.ForEachAssertedObject; import org.simantics.db.common.primitiverequest.ForEachAssertedStatement; import org.simantics.db.common.primitiverequest.HasStatement; import org.simantics.db.common.primitiverequest.HasStatementSubject; import org.simantics.db.common.primitiverequest.HasStatementSubjectObject; import org.simantics.db.common.primitiverequest.HasValue; import org.simantics.db.common.primitiverequest.Inverse; import org.simantics.db.common.primitiverequest.IsInheritedFrom; import org.simantics.db.common.primitiverequest.IsInstanceOf; import org.simantics.db.common.primitiverequest.IsSubrelationOf; import org.simantics.db.common.primitiverequest.OrderedSet; import org.simantics.db.common.primitiverequest.PossibleAdapter; import org.simantics.db.common.primitiverequest.PossibleInverse; import org.simantics.db.common.primitiverequest.PossibleObject; import org.simantics.db.common.primitiverequest.PossibleRelatedValue; import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied; import org.simantics.db.common.primitiverequest.PossibleStatement; import org.simantics.db.common.primitiverequest.PossibleType; import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter; import org.simantics.db.common.primitiverequest.PossibleValue; import org.simantics.db.common.primitiverequest.PossibleValueImplied; import org.simantics.db.common.primitiverequest.RelatedValue; import org.simantics.db.common.primitiverequest.RelatedValueImplied; import org.simantics.db.common.primitiverequest.SingleObject; import org.simantics.db.common.primitiverequest.SingleStatement; import org.simantics.db.common.primitiverequest.SingleType; import org.simantics.db.common.primitiverequest.SingleTypeAny; import org.simantics.db.common.primitiverequest.Types; import org.simantics.db.common.primitiverequest.UniqueAdapter; import org.simantics.db.common.primitiverequest.Value; 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.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.single.wrapper.DeepSingleOrErrorProcedure; import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure; import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure; import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure; import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure; import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure; import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure; import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener; import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener; 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.common.procedure.wrapper.SyncToAsyncProcedure; import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure; import org.simantics.db.common.request.AdaptValue; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.utils.Logger; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.common.validation.L0Validations; import org.simantics.db.exception.AdaptionException; import org.simantics.db.exception.ArgumentException; import org.simantics.db.exception.AssumptionException; import org.simantics.db.exception.BindingException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.DoesNotContainValueException; import org.simantics.db.exception.EmptyResourceException; import org.simantics.db.exception.InternalException; import org.simantics.db.exception.InvalidLiteralException; import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; import org.simantics.db.exception.NoInverseException; import org.simantics.db.exception.NoSingleResultException; import org.simantics.db.exception.ResourceNotFoundException; import org.simantics.db.exception.ServiceException; import org.simantics.db.exception.ValidationException; import org.simantics.db.impl.BlockingAsyncProcedure; import org.simantics.db.impl.RelationContextImpl; 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.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.procedure.AsyncListener; import org.simantics.db.procedure.AsyncMultiListener; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.db.procedure.AsyncSetListener; import org.simantics.db.procedure.Listener; import org.simantics.db.procedure.ListenerBase; import org.simantics.db.procedure.MultiListener; import org.simantics.db.procedure.MultiProcedure; import org.simantics.db.procedure.Procedure; import org.simantics.db.procedure.SetListener; import org.simantics.db.procedure.StatementProcedure; import org.simantics.db.procedure.SyncListener; import org.simantics.db.procedure.SyncMultiListener; import org.simantics.db.procedure.SyncMultiProcedure; import org.simantics.db.procedure.SyncProcedure; import org.simantics.db.procedure.SyncSetListener; import org.simantics.db.request.AsyncMultiRead; import org.simantics.db.request.AsyncRead; import org.simantics.db.request.DelayedWrite; import org.simantics.db.request.DelayedWriteResult; import org.simantics.db.request.ExternalRead; import org.simantics.db.request.MultiRead; import org.simantics.db.request.Read; import org.simantics.db.request.ReadInterface; import org.simantics.db.request.Write; import org.simantics.db.request.WriteInterface; import org.simantics.db.request.WriteOnly; import org.simantics.db.request.WriteOnlyResult; import org.simantics.db.request.WriteResult; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException; import org.simantics.scl.reflection.ReflectionUtils; import org.simantics.scl.reflection.ValueNotFoundException; import org.simantics.scl.runtime.function.Function3; import org.simantics.utils.DataContainer; import org.simantics.utils.Development; 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 { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class); final static boolean EMPTY_RESOURCE_CHECK = false; final public CacheEntry parent; final public QueryProcessor processor; public AsyncBarrierImpl asyncBarrier = null; final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class); final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL); final public static TObjectIntHashMap counters = new TObjectIntHashMap(); public static void resetCounters() { counters.clear(); } public static String listCounters(File file) throws IOException { PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file))); for(Pair p : CollectionUtils.valueSortedEntries(counters)) { b.print(-p.second + " " + p.first + "\n"); } b.close(); return "Dumped " + counters.size() + " queries."; } /* * Implementation of the interface ReadGraph */ final public String getURI(final Resource resource) throws AssumptionException, ValidationException, ServiceException { assert (resource != null); try { return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource)); } catch (AssumptionException e) { throw new AssumptionException(e); } 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 String getPossibleURI(final Resource resource) throws ValidationException, ServiceException { assert (resource != null); try { return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource)); } 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 getResource(final String id) throws ResourceNotFoundException, ValidationException, ServiceException { assert (id != null); try { 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(id, e); } 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 getPossibleResource(final String id) throws ResourceNotFoundException, ValidationException, ServiceException { assert (id != null); try { return getResource(id); } catch (ResourceNotFoundException e) { return 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); } } @Override public Map 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(); } final public Resource getBuiltin(final String id) throws ResourceNotFoundException, ServiceException { assert (id != null); try { return syncRequest(new Builtin(id)); } catch (ResourceNotFoundException e) { throw new ResourceNotFoundException(id, e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure { private static Throwable DONE = new Throwable(); Throwable exception = null; final ResourceSupport support; public StatementReadProcedure(ResourceSupport support) { this.support = support; } @Override public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) { add(s); add(p); add(o); } @Override public void finished(AsyncReadGraph graph) { exception = DONE; } @Override public void exception(AsyncReadGraph graph, Throwable t) { exception = t; } public void checkAndThrow() throws DatabaseException { if(exception != DONE) { if (exception instanceof DatabaseException) throw (DatabaseException) exception; else throw new DatabaseException( "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)", exception); } } public boolean done() { return exception != null; } @Override public boolean contains(Object obj) { if(!(obj instanceof InternalStatement)) return false; InternalStatement statement = (InternalStatement)obj; int s = statement.s; int p = statement.p; int o = statement.o; for(int i=0;i T[] toArray(T[] a) { int length = sizeInternal() / 3; if(length > a.length) { Class arrayType = a.getClass(); a = (arrayType == Object[].class) ? (T[]) new Object[length] : (T[]) Array.newInstance(arrayType.getComponentType(), length); } else { for(int i=length;i c) { throw new UnsupportedOperationException(); } class IteratorImpl implements ListIterator { int index; public IteratorImpl(int index) { this.index = index; } @Override public boolean hasNext() { return index < sizeInternal(); } @Override public Statement next() { Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); index += 3; return result; } @Override public void remove() { throw new Error("Not supported"); } @Override public boolean hasPrevious() { return index > 0; } @Override public Statement previous() { index -= 3; Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); return result; } @Override public int nextIndex() { return index/3; } @Override public int previousIndex() { return index/3-1; } @Override public void set(Statement e) { throw new UnsupportedOperationException(); } @Override public void add(Statement e) { throw new UnsupportedOperationException(); } }; @Override public Iterator iterator() { return new IteratorImpl(0); } @Override public int size() { return sizeInternal() / 3; } @Override public Object[] toArray() { Object[] result = new Object[sizeInternal() / 3]; for(int i=0,j=0;j c) { throw new UnsupportedOperationException(); } @Override public Statement get(int index) { index += 3; if(index < 0 || index >= sizeInternal()) throw new IndexOutOfBoundsException(); return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); } @Override public Statement set(int index, Statement element) { throw new UnsupportedOperationException(); } @Override public void add(int index, Statement element) { throw new UnsupportedOperationException(); } @Override public Statement remove(int index) { throw new UnsupportedOperationException(); } @Override public int indexOf(Object obj) { if(!(obj instanceof InternalStatement)) return -1; InternalStatement statement = (InternalStatement)obj; int s = statement.s; int p = statement.p; int o = statement.o; for(int i=0;i=0;i-=3) if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2)) return i/3; return -1; } @Override public ListIterator listIterator() { return new IteratorImpl(0); } @Override public ListIterator listIterator(int index) { return new IteratorImpl(index*3); } @Override public List subList(int fromIndex, int toIndex) { if(fromIndex < 0 || toIndex*3 >= sizeInternal() || fromIndex > toIndex) throw new IndexOutOfBoundsException(); return new RandomAccessSubList(this, fromIndex, toIndex-fromIndex); } } @Override final public Collection getStatements(final Resource subject, final Resource relation) throws ManyObjectsForFunctionalRelationException, ServiceException { assert (subject != null); assert (relation != null); try { StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport()); processor.forEachStatement(this, subject, relation, procedure); procedure.checkAndThrow(); return procedure; } catch (DatabaseException e) { System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation); StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport()); processor.forEachStatement(this, subject, relation, procedure); return Collections.emptyList(); // throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e); } } @Override final public Collection getAssertedStatements(final Resource subject, final Resource relation) throws ManyObjectsForFunctionalRelationException, ServiceException { assert (subject != null); assert (relation != null); try { return syncRequest(new ForEachAssertedStatement(subject, relation)); } catch (ManyObjectsForFunctionalRelationException e) { throw new ManyObjectsForFunctionalRelationException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Collection getPredicates(final Resource subject) throws ServiceException { assert (subject != null); try { return processor.getPredicates(this, subject); // AsyncMultiReadProcedure procedure = new AsyncMultiReadProcedure(); // processor.forEachPredicate(this, subject, procedure); // procedure.checkAndThrow(); // return procedure; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } catch (Throwable e) { throw new ServiceException(e); } } @Override final public Collection getPrincipalTypes(final Resource subject) throws ServiceException { assert (subject != null); try { AsyncMultiReadProcedure procedure = new AsyncMultiReadProcedure(); processor.forEachPrincipalType(this, subject, procedure); procedure.checkAndThrow(); return procedure; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Set getTypes(final Resource subject) throws ServiceException { assert (subject != null); try { return processor.getTypes(this, subject); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } catch (Throwable e) { throw new ServiceException(e); } } @Override final public Set getSupertypes(final Resource subject) throws ServiceException { assert (subject != null); try { SyncReadProcedure> procedure = new SyncReadProcedure>(); processor.forSupertypes(this, subject, procedure); procedure.checkAndThrow(); return procedure.result; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Set getSuperrelations(final Resource subject) throws ServiceException { assert (subject != null); try { SyncReadProcedure> procedure = new SyncReadProcedure>(); processor.forSuperrelations(this, subject, procedure); procedure.checkAndThrow(); return procedure.result; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override public Resource getPossibleSuperrelation(Resource subject) throws ServiceException { try { SyncReadProcedure procedure = new SyncReadProcedure(); processor.forPossibleSuperrelation(this, subject, procedure); procedure.checkAndThrow(); return procedure.result; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Collection getObjects(final Resource subject, final Resource relation) throws ServiceException { assert (subject != null); assert (relation != null); if(Development.DEVELOPMENT) { if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) { counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1); } //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace(); } try { AsyncMultiReadProcedure procedure = new AsyncMultiReadProcedure(); processor.forEachObject(this, subject, relation, procedure); procedure.checkAndThrow(); return procedure; } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Collection getAssertedObjects( final Resource subject, final Resource relation) throws ManyObjectsForFunctionalRelationException, ServiceException { if (subject == null) throw new ArgumentException("Subject must not be null."); if (relation == null) throw new ArgumentException("Relation must not be null. Subject=" + subject); try { return syncRequest(new ForEachAssertedObject(subject, relation)); } catch (ManyObjectsForFunctionalRelationException e) { throw new ManyObjectsForFunctionalRelationException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException { assert (relation != null); try { return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf())); } catch (NoSingleResultException e) { throw new NoInverseException(e); } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException { if( subject == null) throw new IllegalArgumentException("subject can not be null"); if( relation == null) throw new IllegalArgumentException("relation can not be null"); try { int single = processor.getSingleObject(this, subject, 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) { throw e; } catch (DatabaseException e) { throw new ServiceException(e); } } @Override final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException { assert (subject != null); assert (relation != null); try { Collection statements = getStatements(subject, relation); 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 { assert (subject != null); try { ArrayList principalTypes = (ArrayList)getPrincipalTypes(subject); 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 final public Resource getSingleType(final Resource subject, final Resource baseType) throws NoSingleResultException, ServiceException { assert (subject != null); assert (baseType != null); try { return syncRequest(new SingleType(subject, baseType)); } catch (DatabaseException e) { throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e); } } @Override final public T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException { assert (subject != null); try { Layer0 L0 = processor.getL0(this); int object = processor.getSingleObject(this, subject, L0.HasDataType); if(object == 0) throw new DoesNotContainValueException("No data type for " + subject); if(processor.isImmutable(object)) { Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.instance()); return getValue(subject, binding); } else { byte[] dt = processor.getValue(this, object); if(dt == null) throw new ServiceException("No data type for " + subject); Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt); Binding binding = Bindings.getBinding(datatype); return getValue(subject, binding); } } catch (IOException e) { throw new ServiceException(e); } catch (DoesNotContainValueException e) { throw new DoesNotContainValueException(e, subject); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException { assert (subject != null); try { Layer0 L0 = processor.getL0(this); int object = processor.getSingleObject(this, subject, L0.HasDataType); if(object == 0) throw new DoesNotContainValueException("No data type for " + subject); if(processor.isImmutable(object)) { Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.instance()); return new Variant(binding, getValue(subject, binding)); } else { byte[] dt = processor.getValue(this, object); if(dt == null) throw new ServiceException("No data type for " + subject); Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt); Binding binding = Bindings.getBinding(datatype); return new Variant(binding, getValue(subject, binding)); } } catch (IOException e) { throw new ServiceException(e); } catch (DoesNotContainValueException e) { throw new DoesNotContainValueException(e, subject); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } static final IdentityHashMap serializers = new IdentityHashMap(); static { serializers.put(Bindings.STRING, Bindings.STRING.serializer()); } final protected Serializer getSerializer(Binding binding) { return binding.serializer(); } @Override final public T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException, ServiceException { assert (subject != null); try { byte[] bytes = processor.getValue(this, subject); if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject); Serializer serializer = getSerializer(binding); return (T)serializer.deserialize(bytes); } catch (DoesNotContainValueException e) { 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); } } @Override final public T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException, DoesNotContainValueException, ServiceException { assert (subject != null); assert (relation != null); try { Resource object = getSingleObject(subject, relation); return getValue(object); } catch (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.Value)) { 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)", e); } } else { 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 final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException, DoesNotContainValueException, ServiceException { assert (subject != null); assert (relation != null); try { Resource object = getSingleObject(subject, relation); return getVariantValue(object); } catch (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.Value)) { 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)", e); } } else { 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 final public T getRelatedValue(final Resource subject, final Resource relation, final Binding binding) throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException { assert (subject != null); 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, e.getResultCount(), e); } catch (DoesNotContainValueException e) { throw new DoesNotContainValueException(e); } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public T adapt(final Resource resource, final Class clazz) throws AdaptionException, ValidationException, ServiceException { assert (resource != null); assert (clazz != null); try { return syncRequest(new Adapter(resource, clazz)); } catch (AdaptionException e) { throw new AdaptionException(e); } catch (ValidationException e) { throw new ValidationException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public T adaptContextual(final Resource resource, final C context, final Class contextClass, final Class clazz) throws AdaptionException, ValidationException, ServiceException { assert (resource != null); assert (context != null); class ContextualAdapter implements AsyncRead { final private Resource resource; final private C context; final private Class clazz; @Override public int hashCode() { return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode()); } @Override final public int threadHash() { return resource.getThreadHash(); } @Override public boolean equals(Object object) { if (this == object) return true; else if (object == null) return false; else if (getClass() != object.getClass()) return false; ContextualAdapter r = (ContextualAdapter)object; return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz); } @Override public int getFlags() { return 0; } public ContextualAdapter(Resource resource, C context, Class clazz) { this.resource = resource; this.context = context; this.clazz = clazz; } @Override public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { final AdaptionService service = getSession().peekService(AdaptionService.class); if (service == null) procedure.exception(graph, new ServiceException("No AdaptionService available")); else service.adapt(graph, resource, context, contextClass, clazz, false, procedure); } @Override public String toString() { return "Adapter for (" + resource + "," + context + ") as " + clazz.getName(); } } try { return syncRequest(new ContextualAdapter(resource, context, clazz)); } catch (AdaptionException e) { throw new AdaptionException(e); } catch (ValidationException e) { throw new ValidationException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public T adaptRelated(final Resource resource, final Resource relation, final Class clazz) throws AdaptionException, NoSingleResultException, ValidationException, ServiceException { assert (resource != null); assert (clazz != null); Statement stm = getSingleStatement(resource, relation); return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz); } @Override final public T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class clazz) throws ValidationException, ServiceException { try { return adaptRelated(resource, relation, clazz); } catch (DatabaseException e) { return null; } } @Override final public T getPossibleContextualAdapter(final Resource resource, final C context, final Class contextClass, final Class clazz) throws ValidationException, ServiceException { assert (resource != null); assert (context != null); class PossibleContextualAdapter implements AsyncRead { final private Resource resource; final private C context; final private Class clazz; @Override public int hashCode() { return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode()); } @Override final public int threadHash() { return resource.getThreadHash(); } @Override public boolean equals(Object object) { if (this == object) return true; else if (object == null) return false; else if (getClass() != object.getClass()) return false; PossibleContextualAdapter r = (PossibleContextualAdapter)object; return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz); } @Override public int getFlags() { return 0; } public PossibleContextualAdapter(Resource resource, C context, Class clazz) { this.resource = resource; this.context = context; this.clazz = clazz; } @Override public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { final AdaptionService service = getSession().peekService(AdaptionService.class); if (service == null) procedure.exception(graph, new ServiceException("No AdaptionService available")); else service.adapt(graph, resource, context, contextClass, clazz, true, procedure); } @Override public String toString() { return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName(); } } try { return syncRequest(new PossibleContextualAdapter(resource, context, clazz)); } catch (ValidationException e) { throw new ValidationException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public T adaptUnique(final Resource resource, final Class clazz) throws AdaptionException, ValidationException, ServiceException { assert (resource != null); assert (clazz != null); try { return syncRequest(new UniqueAdapter(resource, clazz)); } catch (AdaptionException e) { throw new AdaptionException(e); } catch (ValidationException e) { throw new ValidationException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public Resource getPossibleInverse(final Resource relation) throws ServiceException { assert (relation != null); try { return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf())); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override public Resource getPossibleObject(final Resource subject, final Resource relation) throws ManyObjectsForFunctionalRelationException, ServiceException { assert (subject != null); assert (relation != null); try { int result = processor.getSingleObject(this, subject, relation); if(result == 0) return null; return processor.querySupport.getResource(result); } catch (ManyObjectsForFunctionalRelationException e) { throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e); } catch (DatabaseException e) { throw new ServiceException(e); } } @Override final public Statement getPossibleStatement(final Resource subject, final Resource relation) throws ManyObjectsForFunctionalRelationException, ServiceException { assert (subject != null); assert (relation != null); try { Collection statements = getStatements(subject, relation); if(statements.size() == 1) return statements.iterator().next(); else return null; } catch (ManyObjectsForFunctionalRelationException e) { throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation); } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException { assert (subject != null); assert (baseType != null); try { AsyncReadProcedure procedure = new AsyncReadProcedure(); forPossibleType(subject, baseType, procedure); procedure.checkAndThrow(); return procedure.result; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public T getPossibleValue(final Resource subject) throws ServiceException { assert (subject != null); try { int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType); if(object == 0) return null; if(processor.isImmutable(object)) { Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.instance()); return getPossibleValue(subject, binding); } else { byte[] dt = processor.getValue(this, object); if(dt == null) return null; Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt); Binding binding = Bindings.getBinding(datatype); return getPossibleValue(subject, binding); } } catch (IOException e) { throw new ServiceException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException { assert (subject != null); assert (binding != null); try { byte[] dt = processor.getValue(this, subject); if(dt == null) return null; Serializer serializer = getSerializer(binding); return (T)serializer.deserialize(dt); } catch (IOException e) { throw new ServiceException(e); } catch (BindingException e) { throw new BindingException(e); } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { e.printStackTrace(); throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override public T getPossibleRelatedValue(final Resource subject, final Resource relation) throws ManyObjectsForFunctionalRelationException, ServiceException { assert (subject != null); assert (relation != null); try { Resource object = getPossibleObject(subject, relation); if(object == null) return null; else return getPossibleValue(object); } catch (ManyObjectsForFunctionalRelationException e) { throw new ManyObjectsForFunctionalRelationException(e); } catch (ServiceException e) { throw new ServiceException(e); } } @Override public T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding) throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException { assert (subject != null); assert (relation != null); assert (binding != null); try { Resource object = getPossibleObject(subject, relation); if(object == null) return null; else return getPossibleValue(object, binding); } catch (ManyObjectsForFunctionalRelationException e) { throw new ManyObjectsForFunctionalRelationException(e); } catch (BindingException e) { throw new BindingException(e); } catch (ServiceException e) { throw new ServiceException(e); } } @Override public T getPossibleAdapter(Resource resource, Class clazz) throws ValidationException, ServiceException { assert (resource != null); assert (clazz != null); try { return syncRequest(new PossibleAdapter(resource, clazz)); } catch (ValidationException e) { throw new ValidationException(e); } catch (AdaptionException e) { return null; } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override public T getPossibleUniqueAdapter(Resource resource, Class clazz) throws ValidationException, ServiceException { assert (resource != null); assert (clazz != null); try { return syncRequest(new PossibleUniqueAdapter(resource, clazz)); } catch (AdaptionException e) { return null; } catch (ValidationException e) { throw new ValidationException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException { assert (resource != null); assert (type != null); Set resources = getTypes(resource); // This check was necessary because some of the callers of this method got stuck when the NPE was thrown from here. if (null == resources) return false; if(EMPTY_RESOURCE_CHECK) { if (resources.isEmpty()) { if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource)); } } return resources.contains(type); } @Override final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException { assert (resource != null); assert (type != null); try { if(resource.equals(type)) return true; return getSupertypes(resource).contains(type); } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException { assert (resource != null); assert (type != null); try { if(resource.equals(type)) return true; return getSuperrelations(resource).contains(type); } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public boolean hasStatement(final Resource subject) throws ServiceException { assert (subject != null); try { SyncReadProcedure procedure = new SyncReadProcedure(); processor.forHasStatement(this, subject, procedure); procedure.checkAndThrow(); return procedure.result; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } @Override final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException { assert (subject != null); assert (relation != null); try { Collection objects = getObjects(subject, relation); return !objects.isEmpty(); } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException { assert (subject != null); assert (relation != null); assert (object != null); try { for(Resource o : getObjects(subject, relation)) { if(object.equals(o)) return true; } return false; } catch (ServiceException e) { throw new ServiceException(e); } } @Override final public boolean hasValue(final Resource subject) throws ServiceException { assert (subject != null); try { SyncReadProcedure procedure = new SyncReadProcedure(); processor.forHasValue(this, subject, procedure); procedure.checkAndThrow(); return procedure.result; } catch (ServiceException e) { throw new ServiceException(e); } catch (DatabaseException e) { throw new ServiceException(INTERNAL_ERROR_STRING, e); } } final AsyncProcedure NONE = new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Object result) { } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { } }; /* * Implementation of the interface RequestProcessor */ @Override public T syncRequest(final Read request) throws DatabaseException { assert (request != null); return QueryCache.resultReadEntry(this, request, parent, null, null); } @Override public T syncRequest(Read request, SyncListener procedure) throws DatabaseException { return syncRequest(request, new SyncToAsyncListener(procedure)); } @Override public T syncRequest(Read request, final Listener procedure) throws DatabaseException { return syncRequest(request, new NoneToAsyncListener(procedure)); } @Override public T syncRequest(final Read request, final AsyncProcedure procedure) throws DatabaseException { assert (request != null); ListenerBase listener = procedure != null ? getListenerBase(procedure) : null; return QueryCache.resultReadEntry(this, request, parent, listener, procedure); } @Override public T syncRequest(final Read request, final SyncProcedure procedure) throws DatabaseException { return syncRequest(request, new SyncToAsyncProcedure(procedure)); } @Override public T syncRequest(Read request, Procedure procedure) throws DatabaseException { return syncRequest(request, new NoneToAsyncProcedure(procedure)); } static class AsyncReadProcedure implements AsyncProcedure { private static Throwable DONE = new Throwable(); T result = null; Throwable exception = null; @Override public void execute(AsyncReadGraph graph, T t) { result = t; exception = DONE; } @Override public void exception(AsyncReadGraph graph, Throwable t) { exception = t; } public void checkAndThrow() throws DatabaseException { if(exception != DONE) { if (exception instanceof DatabaseException) throw (DatabaseException) exception; else throw new DatabaseException( "Unexpected exception in ReadGraph.syncRequest(AsyncRead)", exception); } } public boolean done() { return exception != null; } } @Override public T syncRequest(final AsyncRead request) throws DatabaseException { assert (request != null); asyncBarrier = new AsyncBarrierImpl(null); BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(this, null, request); syncRequest(request, ap); return ap.get(); } @Override public T syncRequest(AsyncRead request, AsyncListener procedure) throws DatabaseException { return syncRequest(request, (AsyncProcedure) procedure); } @Override public T syncRequest(AsyncRead request, SyncListener procedure) throws DatabaseException { return syncRequest(request, new SyncToAsyncListener(procedure)); } @Override public T syncRequest(AsyncRead request, Listener procedure) throws DatabaseException { return syncRequest(request, new NoneToAsyncListener(procedure)); } @Override final public T syncRequest(final AsyncRead request, final AsyncProcedure procedure) throws DatabaseException { assert (request != null); ListenerBase listener = getListenerBase(procedure); BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(this, procedure, request); QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true); return ap.get(); } final private void syncRequest(final AsyncRead request, final AsyncReadProcedure procedure) throws DatabaseException { assert (request != null); ListenerBase listener = getListenerBase(procedure); assert(listener == null); BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(this, procedure, request); QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true); ap.get(); } @Override public T syncRequest(AsyncRead request, final SyncProcedure procedure) throws DatabaseException { return syncRequest(request, new SyncToAsyncProcedure(procedure)); } @Override final public T syncRequest(final AsyncRead request, final Procedure procedure) throws DatabaseException { return syncRequest(request, new NoneToAsyncProcedure(procedure)); } @Override public Collection syncRequest(final MultiRead request) throws DatabaseException { assert (request != null); final ArrayList result = new ArrayList(); final DataContainer exception = new DataContainer(); syncRequest(request, new SyncMultiProcedure() { @Override public void execute(ReadGraph graph, T t) { synchronized (result) { result.add(t); } } @Override public void finished(ReadGraph graph) { } @Override public void exception(ReadGraph graph, Throwable t) { exception.set(t); } @Override public String toString() { return "syncRequest(MultiRead) -> " + request; } }); 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); } return result; } @Override public Collection syncRequest(MultiRead request, SyncMultiListener procedure) { return syncRequest(request, (SyncMultiProcedure)procedure); } @Override public Collection syncRequest(MultiRead request, MultiListener procedure) { return syncRequest(request, new NoneToSyncMultiListener(procedure)); } @Override public Collection syncRequest(MultiRead request, SyncMultiProcedure procedure) { assert (request != null); ListenerBase listener = getListenerBase(procedure); final ResultCallWrappedSyncQueryProcedure wrapper = new ResultCallWrappedSyncQueryProcedure(procedure); if (parent != null || listener != null) { // Object syncParent = request; // final ReadGraphImpl newGraph = newSync(); processor.query(this, request, parent, wrapper, listener); // newGraph.waitAsync(syncParent); } else { // Object syncParent = request; // final ReadGraphImpl newGraph = newSync(); try { request.perform(this, wrapper); } catch (Throwable t) { wrapper.exception(this, t); } } return wrapper.get(); } @Override public Collection syncRequest(MultiRead request, MultiProcedure procedure) { return syncRequest(request, new NoneToSyncMultiProcedure(procedure)); } static class AsyncMultiReadProcedure extends ArrayList implements AsyncMultiProcedure { private static Throwable DONE = new Throwable(); private static final long serialVersionUID = -6494230465108115812L; Throwable exception = null; @Override public synchronized void execute(AsyncReadGraph graph, T t) { add(t); } @Override public void finished(AsyncReadGraph graph) { exception = DONE; } @Override public void exception(AsyncReadGraph graph, Throwable t) { exception = t; } public void checkAndThrow() throws DatabaseException { if(exception != DONE) { if (exception instanceof DatabaseException) throw (DatabaseException) exception; else throw new DatabaseException( "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)", exception); } } public boolean done() { return exception != null; } } @Override final public Collection syncRequest(AsyncMultiRead request) throws DatabaseException { assert (request != null); final AsyncMultiReadProcedure procedure = new AsyncMultiReadProcedure(); syncRequest(request, procedure); procedure.checkAndThrow(); return procedure; } @Override public Collection syncRequest(AsyncMultiRead request, AsyncMultiListener procedure) { return syncRequest(request, (AsyncMultiProcedure) procedure); } @Override public Collection syncRequest(AsyncMultiRead request, SyncMultiListener procedure) { return syncRequest(request, new SyncToAsyncMultiListener(procedure)); } @Override public Collection syncRequest(AsyncMultiRead request, MultiListener procedure) { return syncRequest(request, new NoneToAsyncMultiListener(procedure)); } final private void syncRequest(final AsyncMultiRead request, final AsyncMultiReadProcedure procedure) { assert (request != null); assert (procedure != null); ListenerBase listener = getListenerBase(procedure); if (parent != null || listener != null) { // Object syncParent = request; // final ReadGraphImpl newGraph = newSync(); processor.query(this, request, parent, procedure, listener); // newGraph.waitAsync(syncParent); waitAsyncProcedure(procedure); } else { // Object syncParent = callerThread == Integer.MIN_VALUE ? null // : request; // // final ReadGraphImpl newGraph = newSyncAsync(syncParent); try { // inc(); // ReadGraphImpl sync = newSync(); request.perform(this, procedure); // sync.waitAsync(null); waitAsyncProcedure(procedure); // dec(); } catch (Throwable t) { waitAsyncProcedure(procedure); // dec(); } } } @Override final public Collection syncRequest(final AsyncMultiRead request, final AsyncMultiProcedure procedure) { assert (request != null); assert (procedure != null); ListenerBase listener = getListenerBase(procedure); if (parent != null || listener != null) { // Object syncParent = request; // final ReadGraphImpl newGraph = newSync(); processor.query(this, request, parent, procedure, listener); // newGraph.waitAsync(syncParent); } else { // Object syncParent = request; // final ReadGraphImpl newGraph = newSync(); try { request.perform(this, new AsyncMultiProcedure() { @Override public void execute(AsyncReadGraph graph, T result) { procedure.execute(graph, result); } @Override public void finished(AsyncReadGraph graph) { procedure.finished(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { procedure.exception(graph, t); } @Override public String toString() { return "syncRequest(AsyncMultiRead) -> " + procedure; } }); } catch (Throwable t) { } } // TODO!! return null; } @Override public Collection syncRequest(AsyncMultiRead request, final SyncMultiProcedure procedure) { return syncRequest(request, new SyncToAsyncMultiProcedure(procedure)); } @Override final public Collection syncRequest(final AsyncMultiRead request, final MultiProcedure procedure) { return syncRequest(request, new NoneToAsyncMultiProcedure(procedure)); } @Override public T syncRequest(final ExternalRead request) throws DatabaseException { assert (request != null); return syncRequest(request, new Procedure() { @Override public void execute(T t) { } @Override public void exception(Throwable t) { } @Override public String toString() { return "syncRequest(AsyncRead) -> " + request; } }); } @Override public T syncRequest(ExternalRead request, Listener procedure) throws DatabaseException { return syncRequest(request, (Procedure) procedure); } @Override final public T syncRequest(final ExternalRead request, final Procedure procedure) throws DatabaseException { assert (request != null); ListenerBase listener = procedure != null ? getListenerBase(procedure) : null; return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure); } @Override public void syncRequest(final Write request) throws DatabaseException { assert (request != null); throw new DatabaseException( "Write operations are not supported during read transactions!"); } @Override public T syncRequest(final WriteResult request) throws DatabaseException { assert (request != null); throw new DatabaseException( "Write operations are not supported during read transactions!"); } @Override public void syncRequest(final DelayedWrite request) throws DatabaseException { assert (request != null); throw new DatabaseException( "Write operations are not supported during read transactions!"); } @Override public T syncRequest(final DelayedWriteResult request) throws DatabaseException { assert (request != null); throw new DatabaseException( "Write operations are not supported during read transactions!"); } @Override public void syncRequest(final WriteOnly request) throws DatabaseException { assert (request != null); throw new DatabaseException( "Write operations are not supported during read transactions!"); } @Override public T syncRequest(final WriteOnlyResult request) throws DatabaseException { assert (request != null); throw new DatabaseException( "Write operations are not supported during read transactions!"); } @Override public void async(ReadInterface r, AsyncProcedure procedure) { r.request(this, procedure); } @Override public void async(ReadInterface r, Procedure procedure) { r.request(this, procedure); } @Override public void async(ReadInterface r, SyncProcedure procedure) { r.request(this, procedure); } @Override public void async(ReadInterface r, AsyncListener procedure) { r.request(this, procedure); } @Override public void async(ReadInterface r, Listener procedure) { r.request(this, procedure); } @Override public void async(ReadInterface r, SyncListener procedure) { r.request(this, procedure); } @Override public T sync(ReadInterface r) throws DatabaseException { return r.request(this); } @Override public T sync(WriteInterface r) throws DatabaseException { return r.request(this); } @Override public void async(WriteInterface r, Procedure procedure) { r.request(this, procedure); } @Override public void async(WriteInterface r) { r.request(this, new ProcedureAdapter()); } /* * Implementation of the interface AsyncReadGraph */ @Override public void forURI(Resource resource, AsyncListener listener) { asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource), listener); } @Override public void forURI(Resource resource, SyncListener listener) { asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource), listener); } @Override public void forURI(Resource resource, Listener listener) { asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource), listener); } @Override final public void forURI(final Resource resource, final AsyncProcedure procedure) { assert (resource != null); assert (procedure != null); asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource), procedure); } @Override public void forURI(Resource resource, SyncProcedure procedure) { forURI(resource, new SyncToAsyncProcedure(procedure)); } @Override public void forURI(Resource resource, Procedure procedure) { forURI(resource, new NoneToAsyncProcedure(procedure)); } @Override public void forResource(String id, AsyncListener listener) { asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id), listener); } @Override public void forResource(String id, SyncListener listener) { asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id), listener); } @Override public void forResource(String id, Listener listener) { asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id), listener); } @Override final public void forResource(final String id, final AsyncProcedure procedure) { assert (id != null); assert (procedure != null); processor.forResource(this, id, procedure); } @Override public void forResource(String id, SyncProcedure procedure) { forResource(id, new SyncToAsyncProcedure(procedure)); } @Override public void forResource(String id, Procedure procedure) { forResource(id, new NoneToAsyncProcedure(procedure)); } @Override public void forBuiltin(String id, AsyncListener listener) { asyncRequest(new Builtin(id), listener); } @Override public void forBuiltin(String id, SyncListener listener) { asyncRequest(new Builtin(id), listener); } @Override public void forBuiltin(String id, Listener listener) { asyncRequest(new Builtin(id), listener); } @Override final public void forBuiltin(final String id, final AsyncProcedure procedure) { assert (id != null); assert (procedure != null); processor.forBuiltin(this, id, procedure); } @Override public void forBuiltin(String id, SyncProcedure procedure) { forBuiltin(id, new SyncToAsyncProcedure(procedure)); } @Override public void forBuiltin(String id, Procedure procedure) { forBuiltin(id, new NoneToAsyncProcedure(procedure)); } @Override final public void forEachStatement(Resource subject, Resource relation, AsyncMultiProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachStatement(this, subject, relation, procedure); } @Override public void forEachStatement(Resource subject, Resource relation, SyncMultiProcedure procedure) { forEachStatement(subject, relation, new SyncToAsyncMultiProcedure(procedure)); } @Override final public void forEachStatement(Resource subject, Resource relation, MultiProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachStatement(this, subject, relation, procedure); } @Override final public void forStatementSet(Resource subject, Resource relation, AsyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forStatementSet(this, subject, relation, procedure); } @Override final public void forStatementSet(Resource subject, Resource relation, SyncSetListener procedure) { forStatementSet(subject, relation, new SyncToAsyncSetProcedure(procedure)); } @Override public void forStatementSet(Resource subject, Resource relation, SetListener listener) { forStatementSet(subject, relation, new NoneToAsyncSetProcedure(listener)); } @Override final public void forEachAssertedStatement(final Resource subject, final Resource relation, final AsyncMultiProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachAssertedStatement(this, subject, relation, procedure); } @Override public void forEachAssertedStatement(Resource subject, Resource relation, SyncMultiProcedure procedure) { forEachAssertedStatement(subject, relation, new SyncToAsyncMultiProcedure(procedure)); } @Override public void forEachAssertedStatement(Resource subject, Resource relation, MultiProcedure procedure) { forEachAssertedStatement(subject, relation, new NoneToAsyncMultiProcedure(procedure)); } @Override public void forAssertedStatementSet(Resource subject, Resource relation, AsyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forAssertedStatementSet(this, subject, relation, procedure); } @Override public void forAssertedStatementSet(Resource subject, Resource relation, SyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forAssertedStatementSet(subject, relation, new SyncToAsyncSetProcedure(procedure)); } @Override public void forAssertedStatementSet(Resource subject, Resource relation, SetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forAssertedStatementSet(subject, relation, new NoneToAsyncSetProcedure(procedure)); } @Override final public void forEachPredicate(final Resource subject, final AsyncMultiProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forEachPredicate(this, subject, procedure); } @Override public void forEachPredicate(Resource subject, SyncMultiProcedure procedure) { forEachPredicate(subject, new SyncToAsyncMultiProcedure( procedure)); } @Override final public void forEachPredicate(final Resource subject, final MultiProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forEachPredicate(this, subject, procedure); } @Override final public void forPredicateSet(final Resource subject, final AsyncSetListener procedure) { assert (subject != null); assert (procedure != null); processor.forPredicateSet(this, subject, procedure); } @Override final public void forPredicateSet(final Resource subject, final SyncSetListener procedure) { assert (subject != null); assert (procedure != null); forPredicateSet(subject, new SyncToAsyncSetProcedure( procedure)); } @Override final public void forPredicateSet(final Resource subject, final SetListener procedure) { assert (subject != null); assert (procedure != null); forPredicateSet(subject, new NoneToAsyncSetProcedure( procedure)); } @Override final public void forEachPrincipalType(final Resource subject, final AsyncMultiProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forEachPrincipalType(this, subject, procedure); } @Override public void forEachPrincipalType(Resource subject, SyncMultiProcedure procedure) { forEachPrincipalType(subject, new SyncToAsyncMultiProcedure( procedure)); } @Override final public void forEachPrincipalType(final Resource subject, final MultiProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forEachPrincipalType(this, subject, procedure); } @Override final public void forPrincipalTypeSet(final Resource subject, final AsyncSetListener procedure) { assert (subject != null); assert (procedure != null); processor.forPrincipalTypeSet(this, subject, procedure); } @Override final public void forPrincipalTypeSet(final Resource subject, final SyncSetListener procedure) { assert (subject != null); assert (procedure != null); forPrincipalTypeSet(subject, new SyncToAsyncSetProcedure( procedure)); } @Override final public void forPrincipalTypeSet(final Resource subject, final SetListener procedure) { assert (subject != null); assert (procedure != null); forPrincipalTypeSet(subject, new NoneToAsyncSetProcedure( procedure)); } @Override public void forTypes(Resource subject, AsyncListener> listener) { asyncRequest(new Types(subject), listener); } @Override public void forTypes(Resource subject, SyncListener> listener) { asyncRequest(new Types(subject), listener); } @Override public void forTypes(Resource subject, Listener> listener) { asyncRequest(new Types(subject), listener); } @Override final public void forTypes(final Resource subject, final AsyncProcedure> procedure) { assert (subject != null); assert (procedure != null); processor.forTypes(this, subject, procedure); } @Override public void forTypes(Resource subject, SyncProcedure> procedure) { forTypes(subject, new SyncToAsyncProcedure>(procedure)); } @Override public void forTypes(Resource subject, Procedure> procedure) { forTypes(subject, new NoneToAsyncProcedure>(procedure)); } @Override public void forSupertypes(Resource subject, AsyncListener> listener) { asyncRequest(new Types(subject), listener); } @Override public void forSupertypes(Resource subject, SyncListener> listener) { asyncRequest(new Types(subject), listener); } @Override public void forSupertypes(Resource subject, Listener> listener) { asyncRequest(new Types(subject), listener); } @Override final public void forSupertypes(final Resource subject, final AsyncProcedure> procedure) { assert (subject != null); assert (procedure != null); processor.forSupertypes(this, subject, procedure); } @Override public void forSupertypes(Resource subject, SyncProcedure> procedure) { forSupertypes(subject, new SyncToAsyncProcedure>( procedure)); } @Override public void forSupertypes(Resource subject, Procedure> procedure) { forSupertypes(subject, new NoneToAsyncProcedure>( procedure)); } @Override public void forDirectSuperrelations(Resource subject, AsyncMultiProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forDirectSuperrelations(this, subject, procedure); } @Override public void forPossibleSuperrelation(Resource subject, AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forPossibleSuperrelation(this, subject, procedure); } @Override public void forSuperrelations(Resource subject, AsyncListener> listener) { asyncRequest(new Types(subject), listener); } @Override public void forSuperrelations(Resource subject, SyncListener> listener) { asyncRequest(new Types(subject), listener); } @Override public void forSuperrelations(Resource subject, Listener> listener) { asyncRequest(new Types(subject), listener); } @Override final public void forSuperrelations(final Resource subject, final AsyncProcedure> procedure) { assert (subject != null); assert (procedure != null); processor.forSuperrelations(this, subject, procedure); } @Override public void forSuperrelations(Resource subject, SyncProcedure> procedure) { forSuperrelations(subject, new SyncToAsyncProcedure>( procedure)); } @Override public void forSuperrelations(Resource subject, Procedure> procedure) { forSuperrelations(subject, new NoneToAsyncProcedure>( procedure)); } @Override final public void forEachObject(final Resource subject, final Resource relation, final AsyncMultiProcedure procedure) { processor.forEachObject(this, subject, relation, procedure); } @Override public void forEachObject(Resource subject, Resource relation, SyncMultiProcedure procedure) { forEachObject(subject, relation, new SyncToAsyncMultiProcedure(procedure)); } @Override public void forEachObject(Resource subject, Resource relation, MultiProcedure procedure) { processor.forEachObject(this, subject, relation, procedure); } @Override final public void forEachDirectPredicate(final Resource subject, final AsyncProcedure> procedure) { processor.forEachDirectPredicate(this, subject, procedure); } @Override final public void forEachDirectPredicate(final Resource subject, final SyncProcedure> procedure) { forEachDirectPredicate(subject, new SyncToAsyncProcedure>(procedure)); } @Override public void forEachDirectPredicate(Resource subject, Procedure> procedure) { forEachDirectPredicate(subject, new NoneToAsyncProcedure>(procedure)); } @Override final public void forObjectSet(final Resource subject, final Resource relation, final AsyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forObjectSet(this, subject, relation, procedure); } @Override final public void forObjectSet(final Resource subject, final Resource relation, final SyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forObjectSet(subject, relation, new SyncToAsyncSetProcedure( procedure)); } @Override final public void forObjectSet(final Resource subject, final Resource relation, final SetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forObjectSet(subject, relation, new NoneToAsyncSetProcedure( procedure)); } @Override final public void forEachAssertedObject(final Resource subject, final Resource relation, final AsyncMultiProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachAssertedObject(this, subject, relation, procedure); } @Override public void forEachAssertedObject(Resource subject, Resource relation, SyncMultiProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forEachAssertedObject(subject, relation, new SyncToAsyncMultiProcedure(procedure)); } @Override public void forEachAssertedObject(Resource subject, Resource relation, MultiProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forEachAssertedObject(subject, relation, new NoneToAsyncMultiProcedure(procedure)); } @Override public void forAssertedObjectSet(Resource subject, Resource relation, AsyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forAssertedObjectSet(this, subject, relation, procedure); } @Override public void forAssertedObjectSet(Resource subject, Resource relation, SyncSetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forAssertedObjectSet(subject, relation, new SyncToAsyncSetProcedure(procedure)); } @Override public void forAssertedObjectSet(Resource subject, Resource relation, SetListener procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); forAssertedObjectSet(subject, relation, new NoneToAsyncSetProcedure(procedure)); } @Override public void forInverse(Resource relation, AsyncListener listener) { asyncRequest(new Inverse(relation), listener); } @Override public void forInverse(Resource relation, SyncListener listener) { asyncRequest(new Inverse(relation), listener); } @Override public void forInverse(Resource relation, Listener listener) { asyncRequest(new Inverse(relation), listener); } @Override final public void forInverse(final Resource relation, final AsyncProcedure procedure) { assert (relation != null); assert (procedure != null); processor.forInverse(this, relation, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Resource result) { if (result != null) procedure.execute(graph, result); else { procedure.exception(graph, new NoInverseException(relation .toString())); } } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } @Override public String toString() { return "forInverse -> " + procedure; } }); } @Override public void forInverse(Resource relation, SyncProcedure procedure) { forInverse(relation, new SyncToAsyncProcedure(procedure)); } @Override public void forInverse(Resource relation, Procedure procedure) { forInverse(relation, new NoneToAsyncProcedure(procedure)); } @Override public void forSingleObject(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new SingleObject(subject, relation), listener); } @Override public void forSingleObject(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new SingleObject(subject, relation), listener); } @Override public void forSingleObject(Resource subject, Resource relation, Listener listener) { asyncRequest(new SingleObject(subject, relation), listener); } @Override final public void forSingleObject(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachObject(this, subject, relation, new SingleOrErrorProcedure(procedure)); } @Override public void forSingleObject(Resource subject, Resource relation, SyncProcedure procedure) { forSingleObject(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forSingleObject(Resource subject, Resource relation, Procedure procedure) { forSingleObject(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forSingleStatement(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new SingleStatement(subject, relation), listener); } @Override public void forSingleStatement(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new SingleStatement(subject, relation), listener); } @Override public void forSingleStatement(Resource subject, Resource relation, Listener listener) { asyncRequest(new SingleStatement(subject, relation), listener); } @Override final public void forSingleStatement(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachStatement(this, subject, relation, new SingleOrErrorProcedure(procedure)); } @Override public void forSingleStatement(Resource subject, Resource relation, SyncProcedure procedure) { forSingleStatement(subject, relation, new SyncToAsyncProcedure(procedure)); } @Override public void forSingleStatement(Resource subject, Resource relation, Procedure procedure) { forSingleStatement(subject, relation, new NoneToAsyncProcedure(procedure)); } @Override public void forSingleType(Resource subject, AsyncListener listener) { asyncRequest(new SingleTypeAny(subject), listener); } @Override public void forSingleType(Resource subject, SyncListener listener) { asyncRequest(new SingleTypeAny(subject), listener); } @Override public void forSingleType(Resource subject, Listener listener) { asyncRequest(new SingleTypeAny(subject), listener); } @Override final public void forSingleType(final Resource subject, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); final DeepSingleOrErrorProcedure checkedProcedure = new DeepSingleOrErrorProcedure(procedure); processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, final Resource principalType) { checkedProcedure.offer(graph, principalType); } @Override public void finished(AsyncReadGraph graph) { checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); } @Override public String toString() { return "forSingleType -> " + procedure; } }); } @Override public void forSingleType(Resource subject, SyncProcedure procedure) { forSingleType(subject, new SyncToAsyncProcedure( procedure)); } @Override public void forSingleType(Resource subject, Procedure procedure) { forSingleType(subject, new NoneToAsyncProcedure( procedure)); } @Override public void forSingleType(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new SingleType(subject, relation), listener); } @Override public void forSingleType(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new SingleType(subject, relation), listener); } @Override public void forSingleType(Resource subject, Resource relation, Listener listener) { asyncRequest(new SingleType(subject, relation), listener); } @Override final public void forSingleType(final Resource subject, final Resource baseType, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); final DeepSingleOrErrorProcedure checkedProcedure = new DeepSingleOrErrorProcedure(procedure); processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, final Resource principalType) { checkedProcedure.inc(); if(baseType == null) { checkedProcedure.offer(graph, principalType); checkedProcedure.dec(graph); } else if(principalType.equals(baseType)) { checkedProcedure.offer(graph, principalType); checkedProcedure.dec(graph); } else { processor.forSupertypes((ReadGraphImpl)graph, principalType, new AsyncProcedure>() { @Override public void execute( AsyncReadGraph graph, Set result) { if (result.contains(baseType)) checkedProcedure.offer(graph, principalType); checkedProcedure.dec(graph); } @Override public void exception( AsyncReadGraph graph, Throwable t) { checkedProcedure .exception(graph, t); } }); } } @Override public void finished(AsyncReadGraph graph) { checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); } @Override public String toString() { return "forSingleType -> " + procedure; } }); } @Override public void forSingleType(Resource subject, Resource relation, SyncProcedure procedure) { forSingleType(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forSingleType(Resource subject, Resource relation, Procedure procedure) { forSingleType(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forValue(Resource subject, Binding binding, AsyncListener listener) { asyncRequest(new Value(subject, binding), listener); } @Override public void forValue(Resource subject, Binding binding, SyncListener listener) { asyncRequest(new Value(subject, binding), listener); } @Override public void forValue(Resource subject, Binding binding, Listener listener) { asyncRequest(new Value(subject, binding), listener); } @Override public void forValue(final Resource resource, final Binding binding, final AsyncProcedure procedure) { assert (resource != null); assert (binding != null); assert (procedure != null); processor.forValue(this, resource, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, byte[] result) { try { if (result == null) { procedure.exception(graph, new DoesNotContainValueException( "No value for resource " + resource)); return; } Serializer serializer = binding.serializer(); // Serializer serializer = Bindings.getSerializer( binding ); Object obj = serializer.deserialize(result); // if (!binding.isInstance(obj)) // procedure.exception(graph, new ClassCastException( // "Cannot get value " + obj + " with 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); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forValue -> " + procedure; } }); } @Override public void forValue(Resource subject, Binding binding, SyncProcedure procedure) { forValue(subject, binding, new SyncToAsyncProcedure(procedure)); } @Override public void forValue(Resource subject, Binding binding, Procedure procedure) { forValue(subject, binding, new NoneToAsyncProcedure(procedure)); } @Override public void forValue(Resource subject, AsyncListener listener) { asyncRequest(new ValueImplied(subject), listener); } @Override public void forValue(Resource subject, SyncListener listener) { asyncRequest(new ValueImplied(subject), listener); } @Override public void forValue(Resource subject, Listener listener) { asyncRequest(new ValueImplied(subject), listener); } @Override final public void forValue(final Resource subject, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); forRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Datatype type) { // TODO: consider trying Bindings.getBeanBinding(type); Binding binding = Bindings.getBinding(type); graph.forValue(subject, binding, procedure); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, new DoesNotContainValueException("Invalid data type", throwable)); } }); } @Override public void forValue(Resource subject, SyncProcedure procedure) { forValue(subject, new SyncToAsyncProcedure(procedure)); } @Override public void forValue(Resource subject, Procedure procedure) { forValue(subject, new NoneToAsyncProcedure(procedure)); } @Override public void forRelatedValue(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new RelatedValueImplied(subject, relation), listener); } @Override public void forRelatedValue(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new RelatedValueImplied(subject, relation), listener); } @Override public void forRelatedValue(Resource subject, Resource relation, Listener listener) { asyncRequest(new RelatedValueImplied(subject, relation), listener); } @Override final public void forRelatedValue(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); final DeepSingleOrErrorProcedure checkedProcedure = new DeepSingleOrErrorProcedure(procedure); processor.forEachObject(this, subject, relation, new AsyncMultiProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, final Resource object) { checkedProcedure.inc(); graph.forValue(object, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Object result) { checkedProcedure.offer(graph, (T) result); checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); } @Override public String toString() { return "forRelatedValue -> " + procedure; } }); } @Override public void finished(AsyncReadGraph graph) { checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); } }); } @Override public void forRelatedValue(Resource subject, Resource relation, SyncProcedure procedure) { forRelatedValue(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forRelatedValue(Resource subject, Resource relation, Procedure procedure) { forRelatedValue(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forRelatedValue(Resource subject, Resource relation, Binding binding, AsyncListener listener) { asyncRequest(new RelatedValue(subject, relation, binding), listener); } @Override public void forRelatedValue(Resource subject, Resource relation, Binding binding, SyncListener listener) { asyncRequest(new RelatedValue(subject, relation, binding), listener); } @Override public void forRelatedValue(Resource subject, Resource relation, Binding binding, Listener listener) { asyncRequest(new RelatedValue(subject, relation, binding), listener); } @Override final public void forRelatedValue(final Resource subject, final Resource relation, final Binding binding, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (binding != null); assert (procedure != null); final DeepSingleOrErrorProcedure checkedProcedure = new DeepSingleOrErrorProcedure(procedure); processor.forEachObject(this, subject, relation, new AsyncMultiProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, final Resource object) { checkedProcedure.inc(); graph.forValue(object, binding, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Object result) { checkedProcedure.offer(graph, (T) result); checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); } @Override public String toString() { return "forRelatedValue -> " + procedure; } }); } @Override public void finished(AsyncReadGraph graph) { checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); } }); } @Override public void forRelatedValue(Resource subject, Resource relation, Binding binding, SyncProcedure procedure) { forRelatedValue(subject, relation, binding, new SyncToAsyncProcedure(procedure)); } @Override public void forRelatedValue(Resource subject, Resource relation, Binding binding, Procedure procedure) { forRelatedValue(subject, relation, binding, new NoneToAsyncProcedure(procedure)); } @Override public void forAdapted(Resource resource, Class clazz, AsyncListener listener) { asyncRequest(new Adapter(resource, clazz), listener); } @Override public void forAdapted(Resource resource, Class clazz, SyncListener listener) { asyncRequest(new Adapter(resource, clazz), listener); } @Override public void forAdapted(Resource resource, Class clazz, Listener listener) { asyncRequest(new Adapter(resource, clazz), listener); } @Override final public void forAdapted(final Resource resource, final Class clazz, final AsyncProcedure procedure) { assert (resource != null); assert (clazz != null); assert (procedure != null); final AdaptionService service = getSession().peekService(AdaptionService.class); if (service == null) procedure.exception(this, new ServiceException("No AdaptionService available")); else service.adapt(this, resource, resource, Resource.class, clazz, false, procedure); } @Override public void forAdapted(Resource resource, Class clazz, SyncProcedure procedure) { forAdapted(resource, clazz, new SyncToAsyncProcedure(procedure)); } @Override public void forAdapted(Resource resource, Class clazz, Procedure procedure) { forAdapted(resource, clazz, new NoneToAsyncProcedure(procedure)); } @Override public void forUniqueAdapted(Resource resource, Class clazz, AsyncListener listener) { asyncRequest(new UniqueAdapter(resource, clazz), listener); } @Override public void forUniqueAdapted(Resource resource, Class clazz, SyncListener listener) { asyncRequest(new UniqueAdapter(resource, clazz), listener); } @Override public void forUniqueAdapted(Resource resource, Class clazz, Listener listener) { asyncRequest(new UniqueAdapter(resource, clazz), listener); } @Override final public void forUniqueAdapted(final Resource resource, final Class clazz, final AsyncProcedure procedure) { assert (resource != null); assert (clazz != null); assert (procedure != null); final AdaptionService service = getSession().peekService(AdaptionService.class); if (service == null) procedure.exception(this, new ServiceException("No AdaptionService available")); else service.adaptNew(this, resource, clazz, false, procedure); } @Override public void forUniqueAdapted(Resource resource, Class clazz, SyncProcedure procedure) { forUniqueAdapted(resource, clazz, new SyncToAsyncProcedure(procedure)); } @Override public void forUniqueAdapted(Resource resource, Class clazz, Procedure procedure) { forUniqueAdapted(resource, clazz, new NoneToAsyncProcedure(procedure)); } @Override public void forPossibleInverse(Resource subject, AsyncListener listener) { asyncRequest(new PossibleInverse(subject), listener); } @Override public void forPossibleInverse(Resource subject, SyncListener listener) { asyncRequest(new PossibleInverse(subject), listener); } @Override public void forPossibleInverse(Resource subject, Listener listener) { asyncRequest(new PossibleInverse(subject), listener); } @Override final public void forPossibleInverse(final Resource relation, final AsyncProcedure procedure) { assert (relation != null); assert (procedure != null); processor.forInverse(this, relation, new ExceptionToNullProcedure(procedure)); } @Override public void forPossibleInverse(Resource subject, SyncProcedure procedure) { forPossibleInverse(subject, new SyncToAsyncProcedure( procedure)); } @Override public void forPossibleInverse(Resource subject, Procedure procedure) { forPossibleInverse(subject, new NoneToAsyncProcedure( procedure)); } @Override public void forPossibleObject(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new PossibleObject(subject, relation), listener); } @Override public void forPossibleObject(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new PossibleObject(subject, relation), listener); } @Override public void forPossibleObject(Resource subject, Resource relation, Listener listener) { asyncRequest(new PossibleObject(subject, relation), listener); } @Override final public void forPossibleObject(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachObject(this, subject, relation, new SingleOrNullProcedure(procedure)); } @Override public void forPossibleObject(Resource subject, Resource relation, SyncProcedure procedure) { forPossibleObject(subject, relation, new SyncToAsyncProcedure(procedure)); } @Override public void forPossibleObject(Resource subject, Resource relation, Procedure procedure) { forPossibleObject(subject, relation, new NoneToAsyncProcedure(procedure)); } @Override public void forPossibleStatement(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new PossibleStatement(subject, relation), listener); } @Override public void forPossibleStatement(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new PossibleStatement(subject, relation), listener); } @Override public void forPossibleStatement(Resource subject, Resource relation, Listener listener) { asyncRequest(new PossibleStatement(subject, relation), listener); } @Override final public void forPossibleStatement(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forEachStatement(this, subject, relation, new SingleFunctionalOrNullProcedure( "forPossibleStatement", procedure)); } @Override public void forPossibleStatement(Resource subject, Resource relation, SyncProcedure procedure) { forPossibleStatement(subject, relation, new SyncToAsyncProcedure(procedure)); } @Override public void forPossibleStatement(Resource subject, Resource relation, Procedure procedure) { forPossibleStatement(subject, relation, new NoneToAsyncProcedure(procedure)); } @Override public void forPossibleType(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new PossibleType(subject, relation), listener); } @Override public void forPossibleType(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new PossibleType(subject, relation), listener); } @Override public void forPossibleType(Resource subject, Resource relation, Listener listener) { asyncRequest(new PossibleType(subject, relation), listener); } @Override final public void forPossibleType(final Resource subject, final Resource baseType, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); final NullSingleOrNullProcedure checkedProcedure = new NullSingleOrNullProcedure(procedure); processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, final Resource principalType) { if (baseType == null) { checkedProcedure.offer(graph, principalType); } else if (principalType.equals(baseType)) { checkedProcedure.offer(graph, principalType); } else { checkedProcedure.inc(); processor.forSupertypes((ReadGraphImpl)graph, principalType, new AsyncProcedure>() { @Override public void execute( AsyncReadGraph graph, Set result) { if (result.contains(baseType)) { checkedProcedure.offer(graph, principalType); } checkedProcedure.dec(graph); } @Override public void exception( AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); checkedProcedure.dec(graph); } @Override public String toString() { return "forPossibleType -> " + procedure; } }); } } @Override public void finished(AsyncReadGraph graph) { checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); checkedProcedure.dec(graph); } }); } @Override public void forPossibleType(Resource subject, Resource relation, SyncProcedure procedure) { forPossibleType(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forPossibleType(Resource subject, Resource relation, Procedure procedure) { forPossibleType(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forPossibleValue(Resource subject, AsyncListener listener) { asyncRequest(new PossibleValueImplied(subject), listener); } @Override public void forPossibleValue(Resource subject, SyncListener listener) { asyncRequest(new PossibleValueImplied(subject), listener); } @Override public void forPossibleValue(Resource subject, Listener listener) { asyncRequest(new PossibleValueImplied(subject), listener); } @Override final public void forPossibleValue(final Resource subject, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); forPossibleRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, final Datatype type) { if (type == null) { procedure.execute(graph, null); } else { try { // TODO: consider trying Bindings.getBeanBinding(type); Binding binding = Bindings.getBinding(type); graph.forPossibleValue(subject, binding, procedure); } catch (RuntimeBindingConstructionException e) { procedure.exception(graph, e); } } } @Override public void exception(AsyncReadGraph graph, Throwable t) { procedure.exception(graph, t); } @Override public String toString() { return "forPossibleValue -> " + procedure; } }); } @Override public void forPossibleValue(Resource subject, SyncProcedure procedure) { forPossibleValue(subject, new SyncToAsyncProcedure(procedure)); } @Override public void forPossibleValue(Resource subject, Procedure procedure) { forPossibleValue(subject, new NoneToAsyncProcedure(procedure)); } @Override public void forPossibleValue(Resource subject, Binding binding, AsyncListener listener) { asyncRequest(new PossibleValue(subject, binding), listener); } @Override public void forPossibleValue(Resource subject, Binding binding, SyncListener listener) { asyncRequest(new PossibleValue(subject, binding), listener); } @Override public void forPossibleValue(Resource subject, Binding binding, Listener listener) { asyncRequest(new PossibleValue(subject, binding), listener); } @Override final public void forPossibleValue(final Resource resource, final Binding binding, final AsyncProcedure procedure) { assert (resource != null); assert (binding != null); assert (procedure != null); processor.forValue(this, resource, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, byte[] result) { try { if (result == null) { procedure.execute(graph, null); return; } Serializer serializer = Bindings.getSerializer( binding ); Object obj = serializer.deserialize(result); if (!binding.isInstance(obj)) procedure.exception(graph, new ClassCastException( "Cannot get value " + obj + " with 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); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forPossibleValue -> " + procedure; } }); } @Override public void forPossibleValue(Resource subject, Binding binding, SyncProcedure procedure) { forPossibleValue(subject, binding, new SyncToAsyncProcedure( procedure)); } @Override public void forPossibleValue(Resource subject, Binding binding, Procedure procedure) { forPossibleValue(subject, binding, new NoneToAsyncProcedure( procedure)); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new PossibleRelatedValueImplied(subject, relation), listener); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new PossibleRelatedValueImplied(subject, relation), listener); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Listener listener) { asyncRequest(new PossibleRelatedValueImplied(subject, relation), listener); } @Override final public void forPossibleRelatedValue(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); final DeepSingleOrNullProcedure checkedProcedure = new DeepSingleOrNullProcedure(procedure); processor.forEachObject(this, subject, relation, new AsyncMultiProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, final Resource object) { checkedProcedure.inc(); graph.forValue(object, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Object result) { checkedProcedure.offer(graph, (T) result); checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); checkedProcedure.dec(graph); } }); } @Override public void finished(AsyncReadGraph graph) { checkedProcedure.dec(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { checkedProcedure.exception(graph, t); checkedProcedure.dec(graph); } @Override public String toString() { return "forPossibleRelatedValue -> " + procedure; } }); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, SyncProcedure procedure) { forPossibleRelatedValue(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Procedure procedure) { forPossibleRelatedValue(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Binding binding, AsyncListener listener) { asyncRequest(new PossibleRelatedValue(subject, relation, binding), listener); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Binding binding, SyncListener listener) { asyncRequest(new PossibleRelatedValue(subject, relation, binding), listener); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Binding binding, Listener listener) { asyncRequest(new PossibleRelatedValue(subject, relation, binding), listener); } final public void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forPossibleObject(this, subject, relation, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Resource object) { if(object == null) { procedure.execute(graph, null); return; } processor.forPossibleValue((ReadGraphImpl)graph, object, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, byte[] bytes) { if(bytes != null) { try { Serializer serializer = binding.serializer(); Object obj = serializer.deserialize(bytes); if (!binding.isInstance(obj)) { procedure.exception(graph, new ClassCastException("Cannot get value " + obj + " with binding " + binding)); } else { procedure.execute(graph, (T) obj); } } catch (Throwable t) { procedure.exception(graph, t); } } else { procedure.execute(graph, null); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { procedure.exception(graph, t); } }); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { throwable.printStackTrace(); procedure.exception(graph, throwable); } }); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Binding binding, SyncProcedure procedure) { forPossibleRelatedValue(subject, relation, binding, new SyncToAsyncProcedure(procedure)); } @Override public void forPossibleRelatedValue(Resource subject, Resource relation, Binding binding, Procedure procedure) { forPossibleRelatedValue(subject, relation, binding, new NoneToAsyncProcedure(procedure)); } @Override public void forIsInstanceOf(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new IsInstanceOf(subject, relation), listener); } @Override public void forIsInstanceOf(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new IsInstanceOf(subject, relation), listener); } @Override public void forIsInstanceOf(Resource subject, Resource relation, Listener listener) { asyncRequest(new IsInstanceOf(subject, relation), listener); } @Override final public void forIsInstanceOf(final Resource resource, final Resource type, final AsyncProcedure procedure) { assert (resource != null); assert (type != null); assert (procedure != null); forTypes(resource, new AsyncProcedure>() { @Override public void execute(AsyncReadGraph graph, Set result) { try { if (result.contains(type)) procedure.execute(graph, true); else procedure.execute(graph, false); } catch (Throwable t) { Logger.defaultLogError(t); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forIsInstanceOf -> " + procedure; } }); } @Override public void forIsInstanceOf(Resource subject, Resource relation, SyncProcedure procedure) { forIsInstanceOf(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forIsInstanceOf(Resource subject, Resource relation, Procedure procedure) { forIsInstanceOf(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forIsInheritedFrom(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new IsInheritedFrom(subject, relation), listener); } @Override public void forIsInheritedFrom(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new IsInheritedFrom(subject, relation), listener); } @Override public void forIsInheritedFrom(Resource subject, Resource relation, Listener listener) { asyncRequest(new IsInheritedFrom(subject, relation), listener); } @Override final public void forIsInheritedFrom(final Resource resource, final Resource type, final AsyncProcedure procedure) { assert (resource != null); assert (type != null); assert (procedure != null); if (resource.equals(type)) { try { procedure.execute(this, true); } catch (Throwable t) { Logger.defaultLogError(t); } return; } forSupertypes(resource, new AsyncProcedure>() { @Override public void execute(AsyncReadGraph graph, Set result) { try { if (result.contains(type)) procedure.execute(graph, true); else procedure.execute(graph, false); } catch (Throwable t) { Logger.defaultLogError(t); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forIsInheritedFrom -> " + procedure; } }); } @Override public void forIsInheritedFrom(Resource subject, Resource relation, SyncProcedure procedure) { forIsInheritedFrom(subject, relation, new SyncToAsyncProcedure(procedure)); } @Override public void forIsInheritedFrom(Resource subject, Resource relation, Procedure procedure) { forIsInheritedFrom(subject, relation, new NoneToAsyncProcedure(procedure)); } @Override public void forIsSubrelationOf(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new IsSubrelationOf(subject, relation), listener); } @Override public void forIsSubrelationOf(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new IsSubrelationOf(subject, relation), listener); } @Override public void forIsSubrelationOf(Resource subject, Resource relation, Listener listener) { asyncRequest(new IsSubrelationOf(subject, relation), listener); } @Override final public void forIsSubrelationOf(final Resource resource, final Resource relation, final AsyncProcedure procedure) { assert (resource != null); assert (relation != null); assert (procedure != null); if (resource.equals(relation)) { procedure.execute(this, true); return; } forSuperrelations(resource, new AsyncProcedure>() { @Override public void execute(AsyncReadGraph graph, Set result) { try { if (result.contains(relation)) procedure.execute(graph, true); else procedure.execute(graph, false); } catch (Throwable t) { Logger.defaultLogError(t); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forIsSubrelationOf -> " + procedure; } }); } @Override public void forIsSubrelationOf(Resource subject, Resource relation, SyncProcedure procedure) { forIsSubrelationOf(subject, relation, new SyncToAsyncProcedure(procedure)); } @Override public void forIsSubrelationOf(Resource subject, Resource relation, Procedure procedure) { forIsSubrelationOf(subject, relation, new NoneToAsyncProcedure(procedure)); } @Override public void forHasStatement(Resource subject, AsyncListener listener) { asyncRequest(new HasStatementSubject(subject), listener); } @Override public void forHasStatement(Resource subject, SyncListener listener) { asyncRequest(new HasStatementSubject(subject), listener); } @Override public void forHasStatement(Resource subject, Listener listener) { asyncRequest(new HasStatementSubject(subject), listener); } @Override final public void forHasStatement(final Resource subject, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forHasStatement(this, subject, procedure); } @Override public void forHasStatement(Resource subject, SyncProcedure procedure) { forHasStatement(subject, new SyncToAsyncProcedure(procedure)); } @Override public void forHasStatement(Resource subject, Procedure procedure) { forHasStatement(subject, new NoneToAsyncProcedure(procedure)); } @Override public void forHasStatement(Resource subject, Resource relation, AsyncListener listener) { asyncRequest(new HasStatement(subject, relation), listener); } @Override public void forHasStatement(Resource subject, Resource relation, SyncListener listener) { asyncRequest(new HasStatement(subject, relation), listener); } @Override public void forHasStatement(Resource subject, Resource relation, Listener listener) { asyncRequest(new HasStatement(subject, relation), listener); } @Override final public void forHasStatement(final Resource subject, final Resource relation, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (procedure != null); processor.forHasStatement(this, subject, relation, procedure); } @Override public void forHasStatement(Resource subject, Resource relation, SyncProcedure procedure) { forHasStatement(subject, relation, new SyncToAsyncProcedure( procedure)); } @Override public void forHasStatement(Resource subject, Resource relation, Procedure procedure) { forHasStatement(subject, relation, new NoneToAsyncProcedure( procedure)); } @Override public void forHasStatement(Resource subject, Resource relation, Resource object, AsyncListener listener) { asyncRequest(new HasStatementSubjectObject(subject, relation, object), listener); } @Override public void forHasStatement(Resource subject, Resource relation, Resource object, SyncListener listener) { asyncRequest(new HasStatementSubjectObject(subject, relation, object), listener); } @Override public void forHasStatement(Resource subject, Resource relation, Resource object, Listener listener) { asyncRequest(new HasStatementSubjectObject(subject, relation, object), listener); } @Override final public void forHasStatement(final Resource subject, final Resource relation, final Resource object, final AsyncProcedure procedure) { assert (subject != null); assert (relation != null); assert (object != null); assert (procedure != null); processor.forHasStatement(this, subject, relation, object, procedure); } @Override public void forHasStatement(Resource subject, Resource relation, Resource object, SyncProcedure procedure) { forHasStatement(subject, relation, object, new SyncToAsyncProcedure(procedure)); } @Override public void forHasStatement(Resource subject, Resource relation, Resource object, Procedure procedure) { forHasStatement(subject, relation, object, new NoneToAsyncProcedure(procedure)); } @Override public void forHasValue(Resource subject, AsyncListener listener) { asyncRequest(new HasValue(subject), listener); } @Override public void forHasValue(Resource subject, SyncListener listener) { asyncRequest(new HasValue(subject), listener); } @Override public void forHasValue(Resource subject, Listener listener) { asyncRequest(new HasValue(subject), listener); } @Override final public void forHasValue(final Resource subject, final AsyncProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forValue(this, subject, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, byte[] result) { try { if (result == null) procedure.execute(graph, false); else procedure.execute(graph, true); } catch (Throwable t) { Logger.defaultLogError(t); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forHasValue -> " + procedure; } }); } @Override public void forHasValue(Resource subject, SyncProcedure procedure) { forHasValue(subject, new SyncToAsyncProcedure(procedure)); } @Override public void forHasValue(Resource subject, Procedure procedure) { forHasValue(subject, new NoneToAsyncProcedure(procedure)); } @Override public void forOrderedSet(Resource subject, AsyncMultiListener listener) { asyncRequest(new OrderedSet(subject), listener); } @Override public void forOrderedSet(Resource subject, SyncMultiListener listener) { asyncRequest(new OrderedSet(subject), listener); } @Override public void forOrderedSet(Resource subject, MultiListener listener) { asyncRequest(new OrderedSet(subject), listener); } @Override final public void forOrderedSet(final Resource subject, final AsyncMultiProcedure procedure) { assert (subject != null); assert (procedure != null); processor.forOrderedSet(this, subject, new AsyncMultiProcedure() { @Override public void finished(AsyncReadGraph graph) { try { procedure.finished(graph); } catch (Throwable t) { Logger.defaultLogError(t); } } @Override public void execute(AsyncReadGraph graph, Resource result) { try { procedure.execute(graph, result); } catch (Throwable t) { Logger.defaultLogError(t); } } @Override public void exception(AsyncReadGraph graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public String toString() { return "forOrderedSet -> " + procedure; } }); } @Override public void forOrderedSet(Resource subject, SyncMultiProcedure procedure) { forOrderedSet(subject, new SyncToAsyncMultiProcedure( procedure)); } @Override public void forOrderedSet(Resource subject, MultiProcedure procedure) { forOrderedSet(subject, new NoneToAsyncMultiProcedure( procedure)); } @Override public void forPossibleAdapted(Resource resource, Class clazz, AsyncListener listener) { asyncRequest(new PossibleAdapter(resource, clazz), listener); } @Override public void forPossibleAdapted(Resource resource, Class clazz, SyncListener listener) { asyncRequest(new PossibleAdapter(resource, clazz), listener); } @Override public void forPossibleAdapted(Resource resource, Class clazz, Listener listener) { asyncRequest(new PossibleAdapter(resource, clazz), listener); } @Override final public void forPossibleAdapted(final Resource resource, final Class clazz, final AsyncProcedure procedure) { assert (resource != null); assert (clazz != null); assert (procedure != null); final AdaptionService service = getSession().peekService(AdaptionService.class); if (service == null) procedure.exception(this, new ServiceException("No AdaptionService available")); else service.adapt(this, resource, resource, Resource.class, clazz, true, procedure); } @Override public void forPossibleAdapted(Resource resource, Class clazz, SyncProcedure procedure) { forPossibleAdapted(resource, clazz, new SyncToAsyncProcedure( procedure)); } @Override public void forPossibleAdapted(Resource resource, Class clazz, Procedure procedure) { forPossibleAdapted(resource, clazz, new NoneToAsyncProcedure( procedure)); } @Override public void forPossibleUniqueAdapted(Resource resource, Class clazz, AsyncListener listener) { asyncRequest(new PossibleUniqueAdapter(resource, clazz), listener); } @Override public void forPossibleUniqueAdapted(Resource resource, Class clazz, SyncListener listener) { asyncRequest(new PossibleUniqueAdapter(resource, clazz), listener); } @Override public void forPossibleUniqueAdapted(Resource resource, Class clazz, Listener listener) { asyncRequest(new PossibleUniqueAdapter(resource, clazz), listener); } @Override final public void forPossibleUniqueAdapted(final Resource resource, final Class clazz, final AsyncProcedure procedure) { assert (resource != null); assert (clazz != null); assert (procedure != null); final AdaptionService service = getSession().peekService(AdaptionService.class); if (service == null) procedure.exception(this, new ServiceException("No AdaptionService available")); else service.adaptNew(this, resource, clazz, true, procedure); } @Override public void forPossibleUniqueAdapted(Resource resource, Class clazz, SyncProcedure procedure) { forPossibleUniqueAdapted(resource, clazz, new SyncToAsyncProcedure( procedure)); } @Override public void forPossibleUniqueAdapted(Resource resource, Class clazz, Procedure procedure) { forPossibleUniqueAdapted(resource, clazz, new NoneToAsyncProcedure( procedure)); } /* * Implementation of the interface AsyncRequestProcessor */ @Override final public Session getSession() { return processor.getSession(); } @Override public void asyncRequest(final Read request) { asyncRequest(request, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, T result) { } @Override public void exception(AsyncReadGraph graph, Throwable t) { Logger.defaultLogError(t); } @Override public String toString() { return "asyncRequest(Read) -> " + request; } }); } @Override public void asyncRequest(Read request, AsyncListener procedure) { asyncRequest(request, (AsyncProcedure) procedure); } @Override public void asyncRequest(Read request, final SyncListener procedure) { asyncRequest(request, new SyncToAsyncListener(procedure)); } @Override public void asyncRequest(Read request, final Listener procedure) { asyncRequest(request, new NoneToAsyncListener(procedure)); } @Override public void asyncRequest(final Read request, final AsyncProcedure procedure) { assert (request != null); assert (procedure != null); processor.schedule(new SessionTask(false) { @Override public void run(int thread) { try { final ListenerBase listener = getListenerBase(procedure); QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false); } catch (DatabaseException e) { Logger.defaultLogError(e); } } }); } public static ReadGraphImpl createAsync(QueryProcessor support) { return new ReadGraphImpl(null, support); } @Override public void asyncRequest(Read request, SyncProcedure procedure) { asyncRequest(request, new SyncToAsyncProcedure(procedure)); } @Override public void asyncRequest(Read request, final Procedure procedure) { asyncRequest(request, new NoneToAsyncProcedure(procedure)); } @Override final public void asyncRequest(final AsyncRead request) { assert (request != null); asyncRequest(request, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, T result) { } @Override public void exception(AsyncReadGraph graph, Throwable t) { Logger.defaultLogError(t); } @Override public String toString() { return "asyncRequest(AsyncRead) -> " + request; } }); } @Override public void asyncRequest(AsyncRead request, AsyncListener procedure) { asyncRequest(request, (AsyncProcedure) procedure); } @Override final public void asyncRequest(AsyncRead request, final SyncListener procedure) { asyncRequest(request, new SyncToAsyncListener(procedure)); } @Override final public void asyncRequest(AsyncRead request, final Listener procedure) { asyncRequest(request, new NoneToAsyncListener(procedure)); } @Override final public void asyncRequest(final AsyncRead request, final AsyncProcedure procedure) { assert (request != null); assert (procedure != null); processor.schedule(new SessionTask(false) { @Override public void run(int thread) { try { final ListenerBase listener = getListenerBase(procedure); QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false); } catch (DatabaseException e) { Logger.defaultLogError(e); } } }); } @Override public void asyncRequest(AsyncRead request, SyncProcedure procedure) { asyncRequest(request, new SyncToAsyncProcedure(procedure)); } @Override final public void asyncRequest(final AsyncRead request, final Procedure procedure) { asyncRequest(request, new NoneToAsyncProcedure(procedure)); } @Override public void asyncRequest(final MultiRead request) { assert (request != null); asyncRequest(request, new SyncMultiProcedureAdapter() { @Override public void exception(ReadGraph graph, Throwable t) { Logger.defaultLogError(t); } @Override public String toString() { return "asyncRequest(MultiRead) -> " + request; } }); } @Override public void asyncRequest(MultiRead request, SyncMultiListener procedure) { asyncRequest(request, (SyncMultiProcedure)procedure); } @Override public void asyncRequest(MultiRead request, MultiListener procedure) { asyncRequest(request, new NoneToSyncMultiListener(procedure)); } @Override public void asyncRequest(final MultiRead request, final SyncMultiProcedure procedure) { assert (request != null); assert (procedure != null); final ListenerBase listener = getListenerBase(procedure); if (parent != null || listener != null) { // final ReadGraphImpl newGraph = newSync(); processor.query(this, request, parent, procedure,listener); } else { // final ReadGraphImpl newGraph = newSync(); try { request.perform(this, procedure); } catch (Throwable t) { try { procedure.exception(this, t); } catch (DatabaseException e) { LOGGER.error("Unexpected exception while handling exception", e); } } } } @Override public void asyncRequest(MultiRead request, MultiProcedure procedure) { asyncRequest(request, new NoneToSyncMultiProcedure(procedure)); } @Override final public void asyncRequest(final AsyncMultiRead request) { assert (request != null); asyncRequest(request, new AsyncMultiProcedureAdapter() { @Override public void exception(AsyncReadGraph graph, Throwable t) { Logger.defaultLogError(t); } @Override public String toString() { return "asyncRequest(AsyncMultiRead) -> " + request; } }); } @Override public void asyncRequest(AsyncMultiRead request, AsyncMultiListener procedure) { asyncRequest(request, (AsyncMultiProcedure) procedure); } @Override public void asyncRequest(AsyncMultiRead request, SyncMultiListener procedure) { asyncRequest(request, new SyncToAsyncMultiListener(procedure)); } @Override public void asyncRequest(AsyncMultiRead request, MultiListener procedure) { asyncRequest(request, new NoneToAsyncMultiListener(procedure)); } @Override final public void asyncRequest(AsyncMultiRead request, final AsyncMultiProcedure procedure) { assert (request != null); assert (procedure != null); ListenerBase listener = getListenerBase(procedure); if (parent != null || listener != null) { processor.query(this, request, parent, procedure, listener); } else { try { request.perform(this, new AsyncMultiProcedure() { @Override public void execute(AsyncReadGraph graph, T result) { procedure.execute(graph, result); } @Override public void finished(AsyncReadGraph graph) { procedure.finished(graph); } @Override public void exception(AsyncReadGraph graph, Throwable t) { procedure.exception(graph, t); } @Override public String toString() { return "asyncRequest(AsyncMultiRead) -> " + procedure; } }); } catch (Throwable t) { procedure.exception(this, new DatabaseException(t)); } } } @Override public void asyncRequest(AsyncMultiRead request, SyncMultiProcedure procedure) { asyncRequest(request, new SyncToAsyncMultiProcedure(procedure)); } @Override final public void asyncRequest(AsyncMultiRead request, final MultiProcedure procedure) { asyncRequest(request, new NoneToAsyncMultiProcedure(procedure)); } @Override final public void asyncRequest(final ExternalRead request) { assert (request != null); asyncRequest(request, new Procedure() { @Override public void execute(T result) { } @Override public void exception(Throwable t) { Logger.defaultLogError(t); } @Override public String toString() { return "asyncRequest(PrimitiveRead) -> " + request; } }); } @Override public void asyncRequest(ExternalRead request, final Listener procedure) { asyncRequest(request, (Procedure) procedure); } @Override final public void asyncRequest(final ExternalRead request, final Procedure procedure) { assert (request != null); assert (procedure != null); final ListenerBase listener = getListenerBase(procedure); if (parent != null || listener != null) { 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 } } else { request.register(this, new Listener() { @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; } @Override public boolean isDisposed() { return true; } }); } } @Override public void asyncRequest(final Write request) { assert (request != null); getSession().asyncRequest(request); // processor.asyncWrite(request); } @Override public void asyncRequest(final WriteResult request, Procedure procedure) { throw new Error("Not implemented."); } @Override public void asyncRequest(Write request, Consumer callback) { assert (request != null); getSession().asyncRequest(request, callback); } @Override public void asyncRequest(final DelayedWrite request) { assert (request != null); getSession().asyncRequest(request); } @Override public void asyncRequest(final DelayedWriteResult request, Procedure procedure) { throw new Error("Not implemented."); } @Override public void asyncRequest(DelayedWrite r, Consumer callback) { throw new Error("Not implemented."); } @Override public void asyncRequest(final WriteOnly request) { assert (request != null); getSession().asyncRequest(request); } @Override public void asyncRequest(final WriteOnlyResult request, Procedure procedure) { throw new Error("Not implemented."); } @Override public void asyncRequest(WriteOnly r, Consumer callback) { throw new Error("Not implemented."); } /* * Implementation of the interface ServiceLocator */ @Override public T getService(Class api) { if(WriteSupport.class == api) { if(this instanceof WriteGraphImpl) { WriteGraphImpl impl = (WriteGraphImpl)this; return (T)impl.writeSupport; } } return getSession().getService(api); } @Override public T peekService(Class api) { return getSession().peekService(api); } @Override public boolean hasService(Class api) { return getSession().hasService(api); } @Override public void registerService(Class api, T service) { getSession().registerService(api, service); } @Override public boolean isImmutable(Resource resource) throws DatabaseException { ResourceImpl impl = (ResourceImpl)resource; return processor.isImmutable(impl.id); } /* * Internal routines */ 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; } ReadGraphImpl(ReadGraphImpl graph) { this(graph.parent, graph.processor); } ReadGraphImpl(CacheEntry parent, QueryProcessor support) { this.parent = parent; this.processor = support; } public static ReadGraphImpl create(QueryProcessor support) { return new ReadGraphImpl(null, support); } public static ReadGraphImpl newAsync(ReadGraphImpl parent) { ReadGraphImpl result = new ReadGraphImpl(parent); result.asyncBarrier = new AsyncBarrierImpl(parent.asyncBarrier); return result; } public ReadGraphImpl newRestart(ReadGraphImpl impl) { WriteGraphImpl write = processor.getSession().getService( WriteGraphImpl.class); return write; } 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; else return null; } public void waitAsyncProcedure(AsyncMultiReadProcedure procedure) { assert(procedure.done()); } public void waitAsyncProcedure(AsyncReadProcedure procedure) { assert(procedure.done()); } public boolean resumeTasks() { return processor.resumeTasks(this); } Class singleClass(Set types) { Class result = null; for (Resource type : types) { Class clazz = processor.getBuiltinValue(type); if (clazz != null) { if (result != null) return null; else result = clazz; } } return result; } private String debugString(Resource r) { String name = null; try { name = getPossibleRelatedValue(r, processor.getL0(this).HasName); } catch (ManyObjectsForFunctionalRelationException e) { Logger.defaultLogError(e); } catch (ServiceException e) { Logger.defaultLogError(e); } return "[" + name + " - " + r + "]"; } @Override public String toString() { return "ReadGraphImpl[thread=" + Thread.currentThread() + "]"; } @Override final public int thread() { return 0; } static class MultiTripleIntProcedure implements TripleIntProcedure { final private AsyncMultiProcedure procedure; final private ReadGraphImpl impl; final private QuerySupport support; public MultiTripleIntProcedure(AsyncMultiProcedure procedure, ReadGraphImpl impl, QuerySupport support) { this.procedure = procedure; this.impl = impl; this.support = support; } @Override public void execute(ReadGraphImpl graph, int s, int p, int o) { try { procedure.execute(graph, support.getStatement(s, p, o)); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public void finished(ReadGraphImpl graph) { try { procedure.finished(graph); // impl.state.barrier.dec("ReadGraphSupportImpl.516"); } catch (Throwable t2) { Logger.defaultLogError(t2); } } @Override public void exception(ReadGraphImpl graph, Throwable t) { try { procedure.exception(graph, t); } catch (Throwable t2) { Logger.defaultLogError(t2); } // impl.state.barrier.dec("ReadGraphSupportImpl.516"); } @Override public String toString() { return "forEachObject with " + procedure; } } // private AsyncMultiProcedure cacheKey = null; // private MultiIntProcedure cacheResult = null; // // final IntProcedure forMultiProcedure(final AsyncMultiProcedure procedure) { // // if(procedure == cacheKey) return cacheResult; // // cacheResult = new MultiIntProcedure(procedure, this, processor.support); // cacheKey = procedure; // // return cacheResult; // // } // // private AsyncMultiProcedure cacheKey2 = null; // private MultiTripleIntProcedure cacheResult2 = null; // // final synchronized TripleIntProcedure forMultiProcedure(final AsyncMultiProcedure procedure) { // // if(procedure == cacheKey2) return cacheResult2; // // cacheResult2 = new MultiTripleIntProcedure(procedure, this, processor.support); // cacheKey2 = procedure; // // return cacheResult2; // // } @Override public Datatype getDataType(Resource subject) throws DatabaseException { for(Resource dataTypeResource : getObjects(subject, processor.getL0(this).HasDataType)) return getValue(dataTypeResource, Bindings.getBindingUnchecked(Datatype.class)); throw new DoesNotContainValueException("The literal has no data type."); } protected T getAccessor4File(Resource subject) throws DatabaseException { return null; /* byte[] bytes = processor.support.getValue(g, subject); if (null == bytes) return null; try { BinaryVariant va = (BinaryVariant) Accessors.getAccessor(bytes, Datatypes.VARIANT); Accessor ca = va.getContentAccessor(); return (T)ca; } catch (AccessorConstructionException e) { throw new DatabaseException(e); } */ /* if (null == bytes) return null; Binding datatype_binding = Bindings.getBindingUnchecked(DataType.class); Serializer datatype_serializer = datatype_binding.serializer(); DataType datatype; try { BinaryMemory in = new BinaryMemory(ByteBuffer.wrap(bytes)); datatype = (DataType)datatype_serializer.deserialize(in); Binding data_binding = Bindings.getBinding(datatype); Serializer data_serializer = data_binding.serializer(BinarySerializationFormat.INSTANCE); Object o = data_serializer.deserialize(in); try { return (T)Accessors.getAccessor(data_binding, o); } catch(AccessorConstructionException e) { return null; } } catch (Exception e) { throw new DatabaseException(e); }*/ } @SuppressWarnings("unchecked") @Override public T getAccessor(Resource subject) throws DatabaseException { RandomAccessBinary rab = getRandomAccessBinary(subject); try { return (T)Accessors.getAccessor(rab, getDataType(subject)); } catch(AccessorConstructionException e) { throw new DatabaseException(e); } } @SuppressWarnings("unchecked") protected T createAccessor(Resource resource, Datatype datatype, Object intialValue) throws DatabaseException { RandomAccessBinary rab = createRandomAccessBinary(resource, datatype, intialValue); try { return (T)Accessors.getAccessor(rab, datatype); } catch(AccessorConstructionException e) { throw new DatabaseException(e); } } @Override public RandomAccessBinary getRandomAccessBinary(Resource subject) throws DatabaseException { RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class); ResourceData rd = ravs.get(subject); if (null != rd) return rd; try { ExternalValueSupport evs = getService(ExternalValueSupport.class); long size = evs.getValueSize(this, subject); // Throws DatabaseException if no old external value. try { File platform = Platform.getLocation().toFile(); File tempFiles = new File(platform, "tempFiles"); File dbDir = new File(tempFiles, "db"); dbDir.mkdirs(); File file = new File(dbDir, "ResourceFile" + subject.getResourceId()); rd = new ResourceData(new BinaryFile(file), true); // Old external value. final int N = 1<<20; long left = size; long offset = 0; while (left > 0) { int length = N < left ? N : (int)left; byte[] bytes = evs.readValue(this, subject, offset, length); offset += bytes.length; left -= bytes.length; rd.binaryFile.write(bytes); } ravs.put(subject, rd); return rd; } catch (Exception e) { throw new DatabaseException("Resource " + subject + " have value but there was problem with accessing value data.", e); } } catch (Exception e) { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) { e.printStackTrace(); } } } Datatype datatype = getDataType(subject); Object value = getPossibleValue(subject, Bindings.getBinding(datatype)); return createRandomAccessBinary(subject, datatype, value); } public RandomAccessBinary createRandomAccessBinary(Resource resource, Datatype datatype, Object initialValue) throws DatabaseException { RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class); try { File platform = Platform.getLocation().toFile(); File tempFiles = new File(platform, "tempFiles"); File dbDir = new File(tempFiles, "db"); dbDir.mkdirs(); File file = new File(dbDir, "ResourceFile" + resource.getResourceId()); ResourceData rd = new ResourceData(new BinaryFile(file), false); Binding binding = Bindings.getBinding(datatype); if (null == initialValue) { initialValue = binding.createDefault(); } Serializer serializer = binding.serializer(); byte[] bytes = serializer.serialize(initialValue); rd.binaryFile.write(bytes); ravs.put(resource, rd); return rd; } catch (Exception e) { if (e instanceof DatabaseException) throw (DatabaseException)e; else throw new DatabaseException(e); } } // static class ExternalValueRequest extends ResourceRead { // // public ExternalValueRequest(Resource resource) { // super(resource); // } // // @SuppressWarnings("unchecked") // @Override // public T perform(ReadGraph graph) throws DatabaseException { // try { // // String uri = graph.getURI(resource); // if(Layer0.URIs.Functions_functionApplication.equals(uri)) return (T)functionApplication; // // return (T)ReflectionUtils.getValue(uri).getValue(); // // } catch(ValueNotFoundException e) { // throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e); // } catch(ClassCastException e) { // throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e); // } // } // // } @SuppressWarnings("unchecked") @Override public T getValue2(Resource r, Object context) throws DatabaseException { Layer0 L0 = processor.getL0(this); Set types = getTypes(r); if(types.contains(L0.Literal)) { if(isImmutable(r)) { return syncRequest(new ValueImplied(r)); } else { return getValue(r); } } else if(types.contains(L0.ExternalValue)) { return (T)syncRequest(new AdaptValue(r), TransientCacheListener.instance()); } else { Function3 function = requestValueFunction(r); if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r); try { return function.apply(this, r, context); } catch(RuntimeException e) { DatabaseException dte = findPossibleRootException(e); if(dte != null) throw dte; else throw new DatabaseException(e); } } } @Override public Variant getVariantValue2(Resource r, Object context) throws DatabaseException { Layer0 L0 = processor.getL0(this); Set types = getTypes(r); if(types.contains(L0.Literal)) { if(isImmutable(r)) { return syncRequest(new VariantValueImplied(r)); } else { return getVariantValue(r); } } else if(types.contains(L0.ExternalValue)) { Object value = syncRequest(new AdaptValue(r), TransientCacheListener.instance()); try { return new Variant(Bindings.OBJECT.getContentBinding(value), value); } catch ( org.simantics.databoard.binding.error.BindingException e ) { throw new BindingException( "No binding found for class " + value.getClass().getName(), e ); } } else { Function3 function = requestValueFunction(r); if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r); try { Object value = function.apply(this, r, context); try { return new Variant(Bindings.OBJECT.getContentBinding(value), value); } catch ( org.simantics.databoard.binding.error.BindingException e ) { throw new BindingException( "No binding found for class " + value.getClass().getName(), e ); } } catch(RuntimeException e) { DatabaseException dte = findPossibleRootException(e); if(dte != null) throw dte; else throw new DatabaseException(e); } } } @Override public T getPossibleValue2(Resource subject, Object context) throws DatabaseException { try { return getValue2(subject, context); } catch (DatabaseException e) { return null; } } static class PossibleConverterFunction extends ResourceRead> { public PossibleConverterFunction(Resource resource) { super(resource); } @Override public Function3 perform(ReadGraph graph) throws DatabaseException { return compute(graph, resource); } @SuppressWarnings("unchecked") public static Function3 compute(ReadGraph graph, Resource resource) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(Resource converter : graph.getObjects(resource, L0.ConvertsToValueWith)) { try { if(L0.Functions_functionApplication.equals(converter)) { return (Function3)graph.syncRequest(new AdaptValue(resource)); } else { return graph.getValue2(converter, resource); } } catch(RuntimeException e) { DatabaseException dte = findPossibleRootException(e); if(dte != null) throw dte; else throw new DatabaseException(e); } } return null; } } Function3 requestValueFunction(Resource r) throws DatabaseException { if(isImmutable(r)) return syncRequest(new PossibleConverterFunction(r), TransientCacheAsyncListener.>instance()); else return syncRequest(new PossibleConverterFunction(r)); } /** * Get a value associated with a graph {@link Resource}, using a possible context object and * a desired value binding. The following methods are tried in order to retreive the value: *
    *
  1. If the given resource is a {@code L0.Literal}, the value of the literal is returned, using the binding specified by {@code binding}.
  2. *
  3. If the resource is a {@code L0.ExternalValue}, the value is acquired using * {@link ReflectionUtils#getValue(String)}.
  4. *
  5. If the resource is associated with a suitable value converter with relation {@code L0.ConvertsToValueWith} * (see {@link #requestValueFunction(Resource)}), the value function is called with the graph, the resource * and the context object.
  6. * * * @param r A graph resource with which the value is associated * @param context A context object that is used for acquiring the value (only applied in case 3) * @param binding A binding for the value type (only applied in case 1) * @return The value of the graph node. * @throws DoesNotContainValueException No value is associated with the graph node. * @throws DatabaseException Other errors, such as an error in casting the value to the return type or * a runtime error in the value function. */ @SuppressWarnings("unchecked") @Override public T getValue2(Resource r, Object context, Binding binding) throws DatabaseException { if (binding instanceof ObjectVariantBinding) return getValue2(r, context); Layer0 L0 = processor.getL0(this); Set types = getTypes(r); if(types.contains(L0.Literal)) { if(isImmutable(r)) { return syncRequest(new Value(r, binding)); } else { 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); } } else { Function3 function = requestValueFunction(r); if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function."); try { Object value = function.apply(this, r, context); if(binding.isInstance(value)) return (T)value; Binding srcBinding = Bindings.OBJECT.getContentBinding(value); return (T)Bindings.adapt(value, srcBinding, binding); } catch(RuntimeException e) { DatabaseException dte = findPossibleRootException(e); if(dte != null) throw dte; else throw new DatabaseException(e); } catch (AdaptException e) { throw new DatabaseException(e); } catch (org.simantics.databoard.binding.error.BindingException e) { throw new DatabaseException(e); } } } @Override public T getPossibleValue2(Resource subject, Object context, Binding binding) throws DatabaseException { try { return getValue2(subject, context, binding); } catch (DatabaseException e) { return null; } } private static DatabaseException findPossibleRootException(Throwable t) { if(t == null) return null; if(t instanceof DatabaseException) return (DatabaseException)t; if(t instanceof RuntimeException || t instanceof InvocationTargetException) { return findPossibleRootException(t.getCause()); } return null; } @Override public T getRelatedValue2(Resource subject, Resource relation) throws DatabaseException { return getRelatedValue2(subject, relation, subject); } @Override public Variant getRelatedVariantValue2(Resource subject, Resource relation) throws DatabaseException { return getRelatedVariantValue2(subject, relation, subject); } @Override public T getPossibleRelatedValue2(Resource subject, Resource relation) throws DatabaseException { try { Resource object = getPossibleObject(subject, relation); if(object == null) return null; else return getValue2(object, subject); } catch (DatabaseException e) { return null; } } @Override public 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(); } } 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(); } } return getVariantValue2(getSingleObject(subject, relation), context); } @Override public T getPossibleRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException { try { Resource object = getPossibleObject(subject, relation); if(object == null) return null; else return getValue2(object, context); } catch (DatabaseException e) { return null; } } @Override public T getRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException { return getRelatedValue2(subject, relation, subject, binding); } @Override public T getPossibleRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException { try { Resource object = getPossibleObject(subject, relation); if(object == null) return null; return getValue2(object, subject, binding); } catch (DatabaseException e) { return null; } } @Override public T getRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException { return getValue2(getSingleObject(subject, relation), context, binding); } @Override public T getPossibleRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException { try { Resource object = getPossibleObject(subject, relation); if(object == null) return null; else return getValue2(object, context, binding); } catch (DatabaseException e) { return null; } } @Override public Type getRelatedValueType(Resource subject, Resource relation) throws DatabaseException { Layer0 L0 = processor.getL0(this); Resource property = getSingleObject(subject, relation); String typeText = (String)getRelatedValue(property, L0.HasValueType, Bindings.STRING); try { return org.simantics.scl.compiler.types.Types.parseType(typeText); } catch (SCLTypeParseException e) { throw new DatabaseException(e); } } private static ThreadLocal syncGraph = new ThreadLocal() { protected Boolean initialValue() { return true; } }; @Override public boolean setSynchronous(boolean value) { boolean old = getSynchronous(); syncGraph.set(value); return old; } @Override public boolean getSynchronous() { return syncGraph.get(); } public void ensureLoaded(int resource) { processor.querySupport.ensureLoaded(this, resource); } public void ensureLoaded(int resource, int predicate) { processor.querySupport.ensureLoaded(this, resource, predicate); } public byte[] getValue(int resource) { return processor.querySupport.getValue(this, resource); } public int thread(int resource) { return (resource >>> 16) & processor.THREAD_MASK; } public int thread(Resource resource) { return (((ResourceImpl)resource).id >>> 16) & processor.THREAD_MASK; } public ResourceSupport getResourceSupport() { return processor.getResourceSupport(); } @Override public Object getModificationCounter() { return processor.getSession().getModificationCounter(); } @Override public boolean performPending() { return processor.performPending(processor.thread.get()); } }