1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.impl.graph;
14 import java.io.BufferedOutputStream;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.io.PrintStream;
19 import java.lang.reflect.Array;
20 import java.lang.reflect.InvocationTargetException;
21 import java.nio.BufferUnderflowException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.IdentityHashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
30 import java.util.function.Consumer;
32 import org.eclipse.core.runtime.Platform;
33 import org.simantics.databoard.Accessors;
34 import org.simantics.databoard.Bindings;
35 import org.simantics.databoard.accessor.Accessor;
36 import org.simantics.databoard.accessor.error.AccessorConstructionException;
37 import org.simantics.databoard.adapter.AdaptException;
38 import org.simantics.databoard.binding.Binding;
39 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;
40 import org.simantics.databoard.binding.impl.ObjectVariantBinding;
41 import org.simantics.databoard.binding.mutable.Variant;
42 import org.simantics.databoard.serialization.Serializer;
43 import org.simantics.databoard.type.Datatype;
44 import org.simantics.databoard.util.binary.BinaryFile;
45 import org.simantics.databoard.util.binary.RandomAccessBinary;
46 import org.simantics.db.AsyncReadGraph;
47 import org.simantics.db.DevelopmentKeys;
48 import org.simantics.db.ExternalValueSupport;
49 import org.simantics.db.ReadGraph;
50 import org.simantics.db.RelationContext;
51 import org.simantics.db.Resource;
52 import org.simantics.db.Session;
53 import org.simantics.db.Statement;
54 import org.simantics.db.adaption.AdaptionService;
55 import org.simantics.db.common.primitiverequest.Adapter;
56 import org.simantics.db.common.primitiverequest.Builtin;
57 import org.simantics.db.common.primitiverequest.DatatypeBinding;
58 import org.simantics.db.common.primitiverequest.ForEachAssertedObject;
59 import org.simantics.db.common.primitiverequest.ForEachAssertedStatement;
60 import org.simantics.db.common.primitiverequest.HasStatement;
61 import org.simantics.db.common.primitiverequest.HasStatementSubject;
62 import org.simantics.db.common.primitiverequest.HasStatementSubjectObject;
63 import org.simantics.db.common.primitiverequest.HasValue;
64 import org.simantics.db.common.primitiverequest.Inverse;
65 import org.simantics.db.common.primitiverequest.IsInheritedFrom;
66 import org.simantics.db.common.primitiverequest.IsInstanceOf;
67 import org.simantics.db.common.primitiverequest.IsSubrelationOf;
68 import org.simantics.db.common.primitiverequest.OrderedSet;
69 import org.simantics.db.common.primitiverequest.PossibleAdapter;
70 import org.simantics.db.common.primitiverequest.PossibleInverse;
71 import org.simantics.db.common.primitiverequest.PossibleObject;
72 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
73 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied;
74 import org.simantics.db.common.primitiverequest.PossibleStatement;
75 import org.simantics.db.common.primitiverequest.PossibleType;
76 import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter;
77 import org.simantics.db.common.primitiverequest.PossibleValue;
78 import org.simantics.db.common.primitiverequest.PossibleValueImplied;
79 import org.simantics.db.common.primitiverequest.RelatedValue;
80 import org.simantics.db.common.primitiverequest.RelatedValueImplied;
81 import org.simantics.db.common.primitiverequest.SingleObject;
82 import org.simantics.db.common.primitiverequest.SingleStatement;
83 import org.simantics.db.common.primitiverequest.SingleType;
84 import org.simantics.db.common.primitiverequest.SingleTypeAny;
85 import org.simantics.db.common.primitiverequest.Types;
86 import org.simantics.db.common.primitiverequest.UniqueAdapter;
87 import org.simantics.db.common.primitiverequest.Value;
88 import org.simantics.db.common.primitiverequest.ValueImplied;
89 import org.simantics.db.common.primitiverequest.VariantValueImplied;
90 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
91 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
92 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
93 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
94 import org.simantics.db.common.procedure.single.SyncReadProcedure;
95 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrErrorProcedure;
96 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure;
97 import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure;
98 import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure;
99 import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure;
100 import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure;
101 import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure;
102 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
103 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
104 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
105 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
106 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
107 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
108 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
109 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
110 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
111 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
112 import org.simantics.db.common.request.AdaptValue;
113 import org.simantics.db.common.request.ResourceRead;
114 import org.simantics.db.common.utils.Logger;
115 import org.simantics.db.common.utils.NameUtils;
116 import org.simantics.db.common.validation.L0Validations;
117 import org.simantics.db.exception.AdaptionException;
118 import org.simantics.db.exception.ArgumentException;
119 import org.simantics.db.exception.AssumptionException;
120 import org.simantics.db.exception.BindingException;
121 import org.simantics.db.exception.DatabaseException;
122 import org.simantics.db.exception.DoesNotContainValueException;
123 import org.simantics.db.exception.EmptyResourceException;
124 import org.simantics.db.exception.InternalException;
125 import org.simantics.db.exception.InvalidLiteralException;
126 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
127 import org.simantics.db.exception.NoInverseException;
128 import org.simantics.db.exception.NoSingleResultException;
129 import org.simantics.db.exception.ResourceNotFoundException;
130 import org.simantics.db.exception.ServiceException;
131 import org.simantics.db.exception.ValidationException;
132 import org.simantics.db.impl.RelationContextImpl;
133 import org.simantics.db.impl.ResourceImpl;
134 import org.simantics.db.impl.internal.RandomAccessValueSupport;
135 import org.simantics.db.impl.internal.ResourceData;
136 import org.simantics.db.impl.procedure.CallWrappedSingleQueryProcedure4;
137 import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4;
138 import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4;
139 import org.simantics.db.impl.query.CacheEntry;
140 import org.simantics.db.impl.query.QueryProcessor;
141 import org.simantics.db.impl.query.QuerySupport;
142 import org.simantics.db.impl.query.TripleIntProcedure;
143 import org.simantics.db.impl.support.ResourceSupport;
144 import org.simantics.db.procedure.AsyncListener;
145 import org.simantics.db.procedure.AsyncMultiListener;
146 import org.simantics.db.procedure.AsyncMultiProcedure;
147 import org.simantics.db.procedure.AsyncProcedure;
148 import org.simantics.db.procedure.AsyncSetListener;
149 import org.simantics.db.procedure.Listener;
150 import org.simantics.db.procedure.ListenerBase;
151 import org.simantics.db.procedure.MultiListener;
152 import org.simantics.db.procedure.MultiProcedure;
153 import org.simantics.db.procedure.Procedure;
154 import org.simantics.db.procedure.SetListener;
155 import org.simantics.db.procedure.StatementProcedure;
156 import org.simantics.db.procedure.SyncListener;
157 import org.simantics.db.procedure.SyncMultiListener;
158 import org.simantics.db.procedure.SyncMultiProcedure;
159 import org.simantics.db.procedure.SyncProcedure;
160 import org.simantics.db.procedure.SyncSetListener;
161 import org.simantics.db.request.AsyncMultiRead;
162 import org.simantics.db.request.AsyncRead;
163 import org.simantics.db.request.DelayedWrite;
164 import org.simantics.db.request.DelayedWriteResult;
165 import org.simantics.db.request.ExternalRead;
166 import org.simantics.db.request.MultiRead;
167 import org.simantics.db.request.Read;
168 import org.simantics.db.request.ReadInterface;
169 import org.simantics.db.request.RequestFlags;
170 import org.simantics.db.request.Write;
171 import org.simantics.db.request.WriteInterface;
172 import org.simantics.db.request.WriteOnly;
173 import org.simantics.db.request.WriteOnlyResult;
174 import org.simantics.db.request.WriteResult;
175 import org.simantics.layer0.Layer0;
176 import org.simantics.scl.compiler.types.Type;
177 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
178 import org.simantics.scl.reflection.ReflectionUtils;
179 import org.simantics.scl.reflection.ValueNotFoundException;
180 import org.simantics.scl.runtime.function.Function3;
181 import org.simantics.utils.DataContainer;
182 import org.simantics.utils.Development;
183 import org.simantics.utils.datastructures.Pair;
184 import org.simantics.utils.datastructures.collections.CollectionUtils;
186 import gnu.trove.map.hash.TObjectIntHashMap;
188 public class ReadGraphImpl implements ReadGraph {
190 final static boolean EMPTY_RESOURCE_CHECK = false;
192 final public CacheEntry parent;
193 final public QueryProcessor processor;
195 final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
196 final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
198 final public static TObjectIntHashMap<String> counters = new TObjectIntHashMap<String>();
200 public static void resetCounters() {
204 public static String listCounters(File file) throws IOException {
206 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
208 for(Pair<String,Integer> p : CollectionUtils.valueSortedEntries(counters)) {
209 b.print(-p.second + " " + p.first + "\n");
214 return "Dumped " + counters.size() + " queries.";
219 * Implementation of the interface ReadGraph
221 final public String getURI(final Resource resource) throws AssumptionException, ValidationException, ServiceException {
223 assert (resource != null);
227 return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource));
229 } catch (AssumptionException e) {
231 throw new AssumptionException(e);
233 } catch (ValidationException e) {
235 throw new ValidationException(e);
237 } catch (ServiceException e) {
239 throw new ServiceException(e);
241 } catch (DatabaseException e) {
243 throw new ServiceException(INTERNAL_ERROR_STRING, e);
249 final public String getPossibleURI(final Resource resource) throws ValidationException, ServiceException {
251 assert (resource != null);
255 return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource));
257 } catch (ValidationException e) {
259 throw new ValidationException(e);
261 } catch (ServiceException e) {
263 throw new ServiceException(e);
265 } catch (DatabaseException e) {
267 throw new ServiceException(INTERNAL_ERROR_STRING, e);
273 final public Resource getResource(final String id)
274 throws ResourceNotFoundException, ValidationException,
281 return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
284 } catch (ResourceNotFoundException e) {
286 throw new ResourceNotFoundException(id, e);
288 } catch (ValidationException e) {
290 throw new ValidationException(e);
292 } catch (ServiceException e) {
294 throw new ServiceException(e);
296 } catch (DatabaseException e) {
298 throw new ServiceException(INTERNAL_ERROR_STRING, e);
304 final public Resource getPossibleResource(final String id)
305 throws ResourceNotFoundException, ValidationException,
312 return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
315 } catch (ResourceNotFoundException e) {
319 } catch (ValidationException e) {
321 throw new ValidationException(e);
323 } catch (ServiceException e) {
325 throw new ServiceException(e);
327 } catch (DatabaseException e) {
329 throw new ServiceException(INTERNAL_ERROR_STRING, e);
335 final public Resource getRootLibrary() {
336 return processor.getRootLibraryResource();
339 final public Resource getBuiltin(final String id)
340 throws ResourceNotFoundException, ServiceException {
346 return syncRequest(new Builtin(id));
348 } catch (ResourceNotFoundException e) {
350 throw new ResourceNotFoundException(id, e);
352 } catch (ServiceException e) {
354 throw new ServiceException(e);
356 } catch (DatabaseException e) {
358 throw new ServiceException(INTERNAL_ERROR_STRING, e);
364 static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure {
366 private static Throwable DONE = new Throwable();
368 Throwable exception = null;
370 final ResourceSupport support;
372 public StatementReadProcedure(ResourceSupport support) {
373 this.support = support;
377 public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) {
384 public void finished(AsyncReadGraph graph) {
389 public void exception(AsyncReadGraph graph, Throwable t) {
393 public void checkAndThrow() throws DatabaseException {
394 if(exception != DONE) {
395 if (exception instanceof DatabaseException)
396 throw (DatabaseException) exception;
398 throw new DatabaseException(
399 "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
404 public boolean done() {
405 return exception != null;
409 public boolean contains(Object obj) {
410 if(!(obj instanceof InternalStatement))
412 InternalStatement statement = (InternalStatement)obj;
416 for(int i=0;i<sizeInternal();i+=3)
417 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
422 @SuppressWarnings("unchecked")
424 public <T> T[] toArray(T[] a) {
425 int length = sizeInternal() / 3;
426 if(length > a.length) {
427 Class<?> arrayType = a.getClass();
428 a = (arrayType == Object[].class)
429 ? (T[]) new Object[length]
430 : (T[]) Array.newInstance(arrayType.getComponentType(), length);
433 for(int i=length;i<a.length;++i)
436 for(int i=0,j=0;i<sizeInternal();i+=3,++j)
437 a[j] = (T)new InternalStatement(support, getQuick(i), getQuick(i+1), getQuick(i+2));
442 public boolean add(Statement e) {
443 throw new UnsupportedOperationException();
447 public boolean remove(Object o) {
448 throw new UnsupportedOperationException();
452 public boolean addAll(Collection<? extends Statement> c) {
453 throw new UnsupportedOperationException();
456 class IteratorImpl implements ListIterator<Statement> {
460 public IteratorImpl(int index) {
465 public boolean hasNext() {
466 return index < sizeInternal();
470 public Statement next() {
471 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
477 public void remove() {
478 throw new Error("Not supported");
482 public boolean hasPrevious() {
487 public Statement previous() {
489 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
494 public int nextIndex() {
499 public int previousIndex() {
504 public void set(Statement e) {
505 throw new UnsupportedOperationException();
509 public void add(Statement e) {
510 throw new UnsupportedOperationException();
516 public Iterator<Statement> iterator() {
517 return new IteratorImpl(0);
522 return sizeInternal() / 3;
526 public Object[] toArray() {
527 Object[] result = new Object[sizeInternal() / 3];
528 for(int i=0,j=0;j<sizeInternal();i++,j+=3)
529 result[i] = new InternalStatement(support, getQuick(j), getQuick(j+1), getQuick(j+2));
534 public boolean addAll(int index, Collection<? extends Statement> c) {
535 throw new UnsupportedOperationException();
539 public Statement get(int index) {
541 if(index < 0 || index >= sizeInternal())
542 throw new IndexOutOfBoundsException();
543 return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
547 public Statement set(int index, Statement element) {
548 throw new UnsupportedOperationException();
552 public void add(int index, Statement element) {
553 throw new UnsupportedOperationException();
557 public Statement remove(int index) {
558 throw new UnsupportedOperationException();
562 public int indexOf(Object obj) {
563 if(!(obj instanceof InternalStatement))
565 InternalStatement statement = (InternalStatement)obj;
569 for(int i=0;i<sizeInternal();i+=3)
570 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
576 public int lastIndexOf(Object obj) {
577 if(!(obj instanceof InternalStatement))
579 InternalStatement statement = (InternalStatement)obj;
583 for(int i=sizeInternal()-3;i>=0;i-=3)
584 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
590 public ListIterator<Statement> listIterator() {
591 return new IteratorImpl(0);
595 public ListIterator<Statement> listIterator(int index) {
596 return new IteratorImpl(index*3);
600 public List<Statement> subList(int fromIndex, int toIndex) {
601 if(fromIndex < 0 || toIndex*3 >= sizeInternal() || fromIndex > toIndex)
602 throw new IndexOutOfBoundsException();
603 return new RandomAccessSubList<Statement>(this, fromIndex, toIndex-fromIndex);
608 final public Collection<Statement> getStatements(final Resource subject,
609 final Resource relation)
610 throws ManyObjectsForFunctionalRelationException, ServiceException {
612 assert (subject != null);
613 assert (relation != null);
617 StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
618 processor.forEachStatement(this, subject, relation, procedure);
619 procedure.checkAndThrow();
622 } catch (DatabaseException e) {
624 System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation);
626 StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
627 processor.forEachStatement(this, subject, relation, procedure);
629 return Collections.emptyList();
631 // throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e);
638 final public Collection<Statement> getAssertedStatements(final Resource subject, final Resource relation)
639 throws ManyObjectsForFunctionalRelationException, ServiceException {
641 assert (subject != null);
642 assert (relation != null);
646 return syncRequest(new ForEachAssertedStatement(subject, relation));
648 } catch (ManyObjectsForFunctionalRelationException e) {
650 throw new ManyObjectsForFunctionalRelationException(e);
652 } catch (ServiceException e) {
654 throw new ServiceException(e);
656 } catch (DatabaseException e) {
658 throw new ServiceException(INTERNAL_ERROR_STRING, e);
665 final public Collection<Resource> getPredicates(final Resource subject) throws ServiceException {
667 assert (subject != null);
671 return processor.getPredicates(this, subject);
673 // AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
674 // processor.forEachPredicate(this, subject, procedure);
675 // procedure.checkAndThrow();
678 } catch (ServiceException e) {
680 throw new ServiceException(e);
682 } catch (DatabaseException e) {
684 throw new ServiceException(INTERNAL_ERROR_STRING, e);
686 } catch (Throwable e) {
688 throw new ServiceException(e);
695 final public Collection<Resource> getPrincipalTypes(final Resource subject)
696 throws ServiceException {
698 assert (subject != null);
702 AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
703 processor.forEachPrincipalType(this, subject, procedure);
704 procedure.checkAndThrow();
707 } catch (ServiceException e) {
709 throw new ServiceException(e);
711 } catch (DatabaseException e) {
713 throw new ServiceException(INTERNAL_ERROR_STRING, e);
720 final public Set<Resource> getTypes(final Resource subject) throws ServiceException {
722 assert (subject != null);
726 return processor.getTypes(this, subject);
728 } catch (ServiceException e) {
730 throw new ServiceException(e);
732 } catch (DatabaseException e) {
734 throw new ServiceException(INTERNAL_ERROR_STRING, e);
736 } catch (Throwable e) {
738 throw new ServiceException(e);
745 final public Set<Resource> getSupertypes(final Resource subject)
746 throws ServiceException {
748 assert (subject != null);
752 SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
753 processor.forSupertypes(this, subject, procedure);
754 procedure.checkAndThrow();
755 return procedure.result;
757 } catch (ServiceException e) {
759 throw new ServiceException(e);
761 } catch (DatabaseException e) {
763 throw new ServiceException(INTERNAL_ERROR_STRING, e);
770 final public Set<Resource> getSuperrelations(final Resource subject)
771 throws ServiceException {
773 assert (subject != null);
777 SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
778 processor.forSuperrelations(this, subject, procedure);
779 procedure.checkAndThrow();
780 return procedure.result;
782 } catch (ServiceException e) {
784 throw new ServiceException(e);
786 } catch (DatabaseException e) {
788 throw new ServiceException(INTERNAL_ERROR_STRING, e);
795 public Resource getPossibleSuperrelation(Resource subject) throws ServiceException {
799 SyncReadProcedure<Resource> procedure = new SyncReadProcedure<Resource>();
800 processor.forPossibleSuperrelation(this, subject, procedure);
801 procedure.checkAndThrow();
802 return procedure.result;
804 } catch (ServiceException e) {
806 throw new ServiceException(e);
808 } catch (DatabaseException e) {
810 throw new ServiceException(INTERNAL_ERROR_STRING, e);
817 final public Collection<Resource> getObjects(final Resource subject, final Resource relation)
818 throws ServiceException {
820 assert (subject != null);
821 assert (relation != null);
823 if(Development.DEVELOPMENT) {
824 if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) {
825 counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1);
827 //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace();
832 AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
833 processor.forEachObject(this, subject, relation, procedure);
834 procedure.checkAndThrow();
837 } catch (DatabaseException e) {
839 throw new ServiceException(INTERNAL_ERROR_STRING, e);
846 final public Collection<Resource> getAssertedObjects(
847 final Resource subject, final Resource relation)
848 throws ManyObjectsForFunctionalRelationException, ServiceException {
851 throw new ArgumentException("Subject must not be null.");
852 if (relation == null)
853 throw new ArgumentException("Relation must not be null. Subject=" + subject);
857 return syncRequest(new ForEachAssertedObject(subject, relation));
859 } catch (ManyObjectsForFunctionalRelationException e) {
861 throw new ManyObjectsForFunctionalRelationException(e);
863 } catch (ServiceException e) {
865 throw new ServiceException(e);
867 } catch (DatabaseException e) {
869 throw new ServiceException(INTERNAL_ERROR_STRING, e);
876 final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException {
878 assert (relation != null);
882 return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
884 } catch (NoSingleResultException e) {
886 throw new NoInverseException(e);
888 } catch (ServiceException e) {
890 throw new ServiceException(e);
897 final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException {
899 if( subject == null) throw new IllegalArgumentException("subject can not be null");
900 if( relation == null) throw new IllegalArgumentException("relation can not be null");
903 int single = processor.getSingleObject(this, subject, relation);
905 if (EMPTY_RESOURCE_CHECK) {
906 if (!hasStatement(subject)) {
907 throw new EmptyResourceException("Resource " + debugString(subject));
910 throw new NoSingleResultException("No single object for subject " + debugString(subject)
911 + " and relation " + debugString(relation), single);
913 return processor.querySupport.getResource(single);
914 } catch (NoSingleResultException e) {
916 } catch (DatabaseException e) {
917 throw new ServiceException(e);
922 final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
923 assert (subject != null);
924 assert (relation != null);
926 Collection<Statement> statements = getStatements(subject, relation);
927 if (statements.size() == 1) {
928 return statements.iterator().next();
930 if (EMPTY_RESOURCE_CHECK)
931 if (!hasStatement(subject))
932 throw new EmptyResourceException("Resource " + debugString(subject));
933 throw new NoSingleResultException("No single statement for subject " + debugString(subject)
934 + " and relation " + debugString(relation), statements.size());
936 } catch (ServiceException e) {
937 throw new ServiceException(e);
942 final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
943 assert (subject != null);
945 ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
946 if (principalTypes.size() == 1) {
947 return principalTypes.get(0);
949 throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
951 } catch (ServiceException e) {
952 throw new ServiceException(e);
957 final public Resource getSingleType(final Resource subject,
958 final Resource baseType) throws NoSingleResultException,
961 assert (subject != null);
962 assert (baseType != null);
965 return syncRequest(new SingleType(subject, baseType));
966 } catch (DatabaseException e) {
967 throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
972 final public <T> T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
974 assert (subject != null);
978 Layer0 L0 = processor.getL0(this);
979 int object = processor.getSingleObject(this, subject, L0.HasDataType);
980 if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
982 if(processor.isImmutable(object)) {
983 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance());
984 return getValue(subject, binding);
986 byte[] dt = processor.getValue(this, object);
987 if(dt == null) throw new ServiceException("No data type for " + subject);
988 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
989 Binding binding = Bindings.getBinding(datatype);
990 return getValue(subject, binding);
993 } catch (IOException e) {
995 throw new ServiceException(e);
997 } catch (DoesNotContainValueException e) {
999 throw new DoesNotContainValueException(e, subject);
1001 } catch (ServiceException e) {
1003 throw new ServiceException(e);
1005 } catch (DatabaseException e) {
1007 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1014 final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1016 assert (subject != null);
1020 Layer0 L0 = processor.getL0(this);
1021 int object = processor.getSingleObject(this, subject, L0.HasDataType);
1022 if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1024 if(processor.isImmutable(object)) {
1025 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance());
1026 return new Variant(binding, getValue(subject, binding));
1028 byte[] dt = processor.getValue(this, object);
1029 if(dt == null) throw new ServiceException("No data type for " + subject);
1030 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1031 Binding binding = Bindings.getBinding(datatype);
1032 return new Variant(binding, getValue(subject, binding));
1035 } catch (IOException e) {
1037 throw new ServiceException(e);
1039 } catch (DoesNotContainValueException e) {
1041 throw new DoesNotContainValueException(e, subject);
1043 } catch (ServiceException e) {
1045 throw new ServiceException(e);
1047 } catch (DatabaseException e) {
1049 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1054 static final IdentityHashMap<Binding,Serializer> serializers = new IdentityHashMap<Binding,Serializer>();
1057 serializers.put(Bindings.STRING, Bindings.STRING.serializer());
1060 final protected Serializer getSerializer(Binding binding) {
1061 return binding.serializer();
1065 final public <T> T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException,
1068 assert (subject != null);
1072 byte[] bytes = processor.getValue(this, subject);
1073 if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
1075 Serializer serializer = getSerializer(binding);
1076 return (T)serializer.deserialize(bytes);
1078 } catch (DoesNotContainValueException e) {
1080 throw new DoesNotContainValueException(e);
1082 } catch (IOException e) {
1084 throw new ServiceException(e);
1086 } catch (DatabaseException e) {
1088 throw new ServiceException(e);
1090 } catch (BufferUnderflowException e) {
1091 // This is sometimes thrown when deserialize fails because wrong format.
1092 // For callers of this method this is just an service exception.
1093 throw new ServiceException(e);
1099 final public <T> T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1100 DoesNotContainValueException, ServiceException {
1102 assert (subject != null);
1103 assert (relation != null);
1106 Resource object = getSingleObject(subject, relation);
1107 return getValue(object);
1108 } catch (NoSingleResultException e) {
1109 throw new NoSingleResultException("No single value found for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1110 } catch (DoesNotContainValueException e) {
1112 Layer0 L0 = processor.getL0(this);
1113 Resource object = getPossibleObject(subject, relation);
1114 if(isInstanceOf(object, L0.Value)) {
1115 if(isInstanceOf(object, L0.Literal)) {
1116 throw new DoesNotContainValueException(e);
1118 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1121 throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1123 } catch (DoesNotContainValueException e2) {
1125 } catch (DatabaseException e2) {
1126 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1128 } catch (ServiceException e) {
1129 throw new ServiceException(e);
1134 final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1135 DoesNotContainValueException, ServiceException {
1137 assert (subject != null);
1138 assert (relation != null);
1141 Resource object = getSingleObject(subject, relation);
1142 return getVariantValue(object);
1143 } catch (NoSingleResultException e) {
1144 throw new NoSingleResultException("No single object for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1145 } catch (DoesNotContainValueException e) {
1147 Layer0 L0 = processor.getL0(this);
1148 Resource object = getPossibleObject(subject, relation);
1149 if(isInstanceOf(object, L0.Value)) {
1150 if(isInstanceOf(object, L0.Literal)) {
1151 throw new DoesNotContainValueException(e);
1153 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1156 throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1158 } catch (DoesNotContainValueException e2) {
1160 } catch (DatabaseException e2) {
1161 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1163 } catch (ServiceException e) {
1164 throw new ServiceException(e);
1169 final public <T> T getRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1170 throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException {
1172 assert (subject != null);
1173 assert (relation != null);
1176 Resource object = getSingleObject(subject, relation);
1177 return getValue(object, binding);
1178 } catch (NoSingleResultException e) {
1179 String message = "";
1181 String subjectName = NameUtils.getSafeName(this, subject, true);
1182 String relationName = NameUtils.getSafeName(this, relation, true);
1183 message = "Subject: " + subjectName + ", Relation: " + relationName;
1184 } catch (DatabaseException e2) {
1187 throw new NoSingleResultException(message, e.getResultCount(), e);
1188 } catch (DoesNotContainValueException e) {
1189 throw new DoesNotContainValueException(e);
1190 } catch (ServiceException e) {
1191 throw new ServiceException(e);
1196 final public <T> T adapt(final Resource resource, final Class<T> clazz)
1197 throws AdaptionException, ValidationException, ServiceException {
1199 assert (resource != null);
1200 assert (clazz != null);
1204 return syncRequest(new Adapter<T>(resource, clazz));
1206 } catch (AdaptionException e) {
1208 throw new AdaptionException(e);
1210 } catch (ValidationException e) {
1212 throw new ValidationException(e);
1214 } catch (ServiceException e) {
1216 throw new ServiceException(e);
1218 } catch (DatabaseException e) {
1220 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1227 final public <T,C> T adaptContextual(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1228 throws AdaptionException, ValidationException, ServiceException {
1230 assert (resource != null);
1231 assert (context != null);
1233 class ContextualAdapter implements AsyncRead<T> {
1235 final private Resource resource;
1236 final private C context;
1237 final private Class<T> clazz;
1240 public int hashCode() {
1241 return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1245 final public int threadHash() {
1246 return resource.getThreadHash();
1250 public boolean equals(Object object) {
1253 else if (object == null)
1255 else if (getClass() != object.getClass())
1257 ContextualAdapter r = (ContextualAdapter)object;
1258 return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1262 public int getFlags() {
1266 public ContextualAdapter(Resource resource, C context, Class<T> clazz) {
1267 this.resource = resource;
1268 this.context = context;
1273 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1275 final AdaptionService service = getSession().peekService(AdaptionService.class);
1276 if (service == null)
1277 procedure.exception(graph, new ServiceException("No AdaptionService available"));
1279 service.adapt(graph, resource, context, contextClass, clazz, false, procedure);
1284 public String toString() {
1285 return "Adapter for (" + resource + "," + context + ") as " + clazz.getName();
1292 return syncRequest(new ContextualAdapter(resource, context, clazz));
1294 } catch (AdaptionException e) {
1296 throw new AdaptionException(e);
1298 } catch (ValidationException e) {
1300 throw new ValidationException(e);
1302 } catch (ServiceException e) {
1304 throw new ServiceException(e);
1306 } catch (DatabaseException e) {
1308 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1315 final public <T> T adaptRelated(final Resource resource, final Resource relation, final Class<T> clazz)
1316 throws AdaptionException, NoSingleResultException, ValidationException, ServiceException {
1318 assert (resource != null);
1319 assert (clazz != null);
1321 Statement stm = getSingleStatement(resource, relation);
1323 return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz);
1328 final public <T> T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class<T> clazz)
1329 throws ValidationException, ServiceException {
1332 return adaptRelated(resource, relation, clazz);
1333 } catch (DatabaseException e) {
1340 final public <T,C> T getPossibleContextualAdapter(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1341 throws ValidationException, ServiceException {
1343 assert (resource != null);
1344 assert (context != null);
1346 class PossibleContextualAdapter implements AsyncRead<T> {
1348 final private Resource resource;
1349 final private C context;
1350 final private Class<T> clazz;
1353 public int hashCode() {
1354 return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1358 final public int threadHash() {
1359 return resource.getThreadHash();
1363 public boolean equals(Object object) {
1366 else if (object == null)
1368 else if (getClass() != object.getClass())
1370 PossibleContextualAdapter r = (PossibleContextualAdapter)object;
1371 return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1375 public int getFlags() {
1379 public PossibleContextualAdapter(Resource resource, C context, Class<T> clazz) {
1380 this.resource = resource;
1381 this.context = context;
1386 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1388 final AdaptionService service = getSession().peekService(AdaptionService.class);
1389 if (service == null)
1390 procedure.exception(graph, new ServiceException("No AdaptionService available"));
1392 service.adapt(graph, resource, context, contextClass, clazz, true, procedure);
1397 public String toString() {
1398 return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName();
1405 return syncRequest(new PossibleContextualAdapter(resource, context, clazz));
1407 } catch (ValidationException e) {
1409 throw new ValidationException(e);
1411 } catch (ServiceException e) {
1413 throw new ServiceException(e);
1415 } catch (DatabaseException e) {
1417 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1424 final public <T> T adaptUnique(final Resource resource, final Class<T> clazz)
1425 throws AdaptionException, ValidationException, ServiceException {
1427 assert (resource != null);
1428 assert (clazz != null);
1432 return syncRequest(new UniqueAdapter<T>(resource, clazz));
1434 } catch (AdaptionException e) {
1436 throw new AdaptionException(e);
1438 } catch (ValidationException e) {
1440 throw new ValidationException(e);
1442 } catch (ServiceException e) {
1444 throw new ServiceException(e);
1446 } catch (DatabaseException e) {
1448 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1455 final public Resource getPossibleInverse(final Resource relation)
1456 throws ServiceException {
1458 assert (relation != null);
1462 return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
1464 } catch (ServiceException e) {
1466 throw new ServiceException(e);
1468 } catch (DatabaseException e) {
1470 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1477 public Resource getPossibleObject(final Resource subject, final Resource relation)
1478 throws ManyObjectsForFunctionalRelationException, ServiceException {
1480 assert (subject != null);
1481 assert (relation != null);
1485 int result = processor.getSingleObject(this, subject, relation);
1486 if(result == 0) return null;
1488 return processor.querySupport.getResource(result);
1490 } catch (ManyObjectsForFunctionalRelationException e) {
1492 throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
1494 } catch (DatabaseException e) {
1496 throw new ServiceException(e);
1503 final public Statement getPossibleStatement(final Resource subject, final Resource relation)
1504 throws ManyObjectsForFunctionalRelationException, ServiceException {
1506 assert (subject != null);
1507 assert (relation != null);
1511 Collection<Statement> statements = getStatements(subject, relation);
1512 if(statements.size() == 1) return statements.iterator().next();
1515 } catch (ManyObjectsForFunctionalRelationException e) {
1517 throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
1519 } catch (ServiceException e) {
1521 throw new ServiceException(e);
1528 final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException {
1530 assert (subject != null);
1531 assert (baseType != null);
1535 AsyncReadProcedure<Resource> procedure = new AsyncReadProcedure<Resource>();
1536 forPossibleType(subject, baseType, procedure);
1537 procedure.checkAndThrow();
1538 return procedure.result;
1540 } catch (ServiceException e) {
1542 throw new ServiceException(e);
1544 } catch (DatabaseException e) {
1546 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1553 final public <T> T getPossibleValue(final Resource subject) throws ServiceException {
1555 assert (subject != null);
1559 int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType);
1560 if(object == 0) return null;
1562 if(processor.isImmutable(object)) {
1563 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance());
1564 return getPossibleValue(subject, binding);
1566 byte[] dt = processor.getValue(this, object);
1567 if(dt == null) return null;
1568 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1569 Binding binding = Bindings.getBinding(datatype);
1570 return getPossibleValue(subject, binding);
1573 } catch (IOException e) {
1575 throw new ServiceException(e);
1577 } catch (ServiceException e) {
1579 throw new ServiceException(e);
1581 } catch (DatabaseException e) {
1583 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1590 final public <T> T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException {
1592 assert (subject != null);
1593 assert (binding != null);
1597 byte[] dt = processor.getValue(this, subject);
1598 if(dt == null) return null;
1599 Serializer serializer = getSerializer(binding);
1600 return (T)serializer.deserialize(dt);
1602 } catch (IOException e) {
1604 throw new ServiceException(e);
1606 } catch (BindingException e) {
1608 throw new BindingException(e);
1610 } catch (ServiceException e) {
1612 throw new ServiceException(e);
1614 } catch (DatabaseException e) {
1615 e.printStackTrace();
1616 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1622 public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation)
1623 throws ManyObjectsForFunctionalRelationException, ServiceException {
1625 assert (subject != null);
1626 assert (relation != null);
1630 Resource object = getPossibleObject(subject, relation);
1631 if(object == null) return null;
1632 else return getPossibleValue(object);
1634 } catch (ManyObjectsForFunctionalRelationException e) {
1636 throw new ManyObjectsForFunctionalRelationException(e);
1638 } catch (ServiceException e) {
1640 throw new ServiceException(e);
1647 public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1648 throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
1650 assert (subject != null);
1651 assert (relation != null);
1652 assert (binding != null);
1656 Resource object = getPossibleObject(subject, relation);
1657 if(object == null) return null;
1658 else return getPossibleValue(object, binding);
1660 } catch (ManyObjectsForFunctionalRelationException e) {
1662 throw new ManyObjectsForFunctionalRelationException(e);
1664 } catch (BindingException e) {
1666 throw new BindingException(e);
1668 } catch (ServiceException e) {
1670 throw new ServiceException(e);
1677 public <T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1679 assert (resource != null);
1680 assert (clazz != null);
1684 return syncRequest(new PossibleAdapter<T>(resource, clazz));
1686 } catch (ValidationException e) {
1688 throw new ValidationException(e);
1690 } catch (AdaptionException e) {
1694 } catch (DatabaseException e) {
1696 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1702 public <T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1704 assert (resource != null);
1705 assert (clazz != null);
1709 return syncRequest(new PossibleUniqueAdapter<T>(resource, clazz));
1711 } catch (AdaptionException e) {
1715 } catch (ValidationException e) {
1717 throw new ValidationException(e);
1719 } catch (DatabaseException e) {
1721 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1728 final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException {
1730 assert (resource != null);
1731 assert (type != null);
1733 Set<Resource> resources = getTypes(resource);
1734 // This check was necessary because some of the callers of this method got stuck when the NPE was thrown from here.
1735 if (null == resources)
1738 if(EMPTY_RESOURCE_CHECK) {
1739 if (resources.isEmpty()) {
1740 if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource));
1744 return resources.contains(type);
1749 final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException {
1751 assert (resource != null);
1752 assert (type != null);
1756 if(resource.equals(type)) return true;
1758 return getSupertypes(resource).contains(type);
1760 } catch (ServiceException e) {
1762 throw new ServiceException(e);
1769 final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException {
1771 assert (resource != null);
1772 assert (type != null);
1776 if(resource.equals(type)) return true;
1778 return getSuperrelations(resource).contains(type);
1780 } catch (ServiceException e) {
1782 throw new ServiceException(e);
1789 final public boolean hasStatement(final Resource subject) throws ServiceException {
1791 assert (subject != null);
1795 SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1796 processor.forHasStatement(this, subject, procedure);
1797 procedure.checkAndThrow();
1798 return procedure.result;
1800 } catch (ServiceException e) {
1802 throw new ServiceException(e);
1804 } catch (DatabaseException e) {
1806 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1813 final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException {
1815 assert (subject != null);
1816 assert (relation != null);
1820 Collection<Resource> objects = getObjects(subject, relation);
1821 return !objects.isEmpty();
1823 } catch (ServiceException e) {
1825 throw new ServiceException(e);
1832 final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1834 assert (subject != null);
1835 assert (relation != null);
1836 assert (object != null);
1840 for(Resource o : getObjects(subject, relation)) {
1841 if(object.equals(o)) return true;
1846 } catch (ServiceException e) {
1848 throw new ServiceException(e);
1855 final public boolean hasValue(final Resource subject) throws ServiceException {
1857 assert (subject != null);
1861 SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1862 processor.forHasValue(this, subject, procedure);
1863 procedure.checkAndThrow();
1864 return procedure.result;
1866 } catch (ServiceException e) {
1868 throw new ServiceException(e);
1870 } catch (DatabaseException e) {
1872 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1878 final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1881 public void execute(AsyncReadGraph graph, Object result) {
1885 public void exception(AsyncReadGraph graph, Throwable throwable) {
1891 * Implementation of the interface RequestProcessor
1895 public <T> T syncRequest(final Read<T> request) throws DatabaseException {
1897 assert (request != null);
1899 if (parent != null) {
1902 return processor.queryRead(this, request, parent, null, null);
1903 } catch (Throwable e) {
1904 if(e instanceof DatabaseException) throw (DatabaseException)e;
1905 else throw new DatabaseException(e);
1912 return processor.tryQuery(this, request);
1914 } catch (Throwable throwable) {
1916 //Logger.defaultLogError("Internal read request failure", throwable);
1918 if (throwable instanceof DatabaseException)
1919 throw (DatabaseException) throwable;
1921 throw new DatabaseException(
1922 "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
1932 public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1933 throws DatabaseException {
1934 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1938 public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1939 throws DatabaseException {
1940 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1944 public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1946 assert (request != null);
1948 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1950 if (parent != null || listener != null) {
1953 return processor.queryRead(this, request, parent, procedure, listener);
1954 } catch (Throwable e) {
1955 if(e instanceof DatabaseException) throw (DatabaseException)e;
1956 else throw new DatabaseException(e);
1963 T t = processor.tryQuery(this, request);
1964 if(procedure != null)
1965 procedure.execute(this, t);
1969 } catch (Throwable throwable) {
1971 Logger.defaultLogError("Internal read request failure", throwable);
1973 if(procedure != null)
1974 procedure.exception(this, throwable);
1976 if (throwable instanceof DatabaseException)
1977 throw (DatabaseException) throwable;
1979 throw new DatabaseException(
1980 "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
1990 public <T> T syncRequest(final Read<T> request,
1991 final SyncProcedure<T> procedure) throws DatabaseException {
1992 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
1996 public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
1997 throws DatabaseException {
1998 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2001 static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
2003 private static Throwable DONE = new Throwable();
2006 Throwable exception = null;
2009 public void execute(AsyncReadGraph graph, T t) {
2015 public void exception(AsyncReadGraph graph, Throwable t) {
2019 public void checkAndThrow() throws DatabaseException {
2020 if(exception != DONE) {
2021 if (exception instanceof DatabaseException)
2022 throw (DatabaseException) exception;
2024 throw new DatabaseException(
2025 "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2030 public boolean done() {
2031 return exception != null;
2037 public <T> T syncRequest(final AsyncRead<T> request)
2038 throws DatabaseException {
2040 assert (request != null);
2041 AsyncReadProcedure<T> procedure = new AsyncReadProcedure<T>();
2042 syncRequest(request, procedure);
2043 procedure.checkAndThrow();
2044 return procedure.result;
2046 // return syncRequest(request, new AsyncProcedureAdapter<T>());
2051 public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2052 throws DatabaseException {
2053 return syncRequest(request, (AsyncProcedure<T>) procedure);
2057 public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2058 throws DatabaseException {
2059 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2063 public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2064 throws DatabaseException {
2065 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2069 final public <T> T syncRequest(final AsyncRead<T> request,
2070 final AsyncProcedure<T> procedure) throws DatabaseException {
2072 assert (request != null);
2074 // System.out.println("syncRequest " + request + " syncParent=" +
2077 ListenerBase listener = getListenerBase(procedure);
2079 if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
2081 // Object syncParent = request;
2083 // final ReadGraphImpl newGraph = newSync();
2085 final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
2086 procedure, request);
2088 processor.query(this, request, parent, wrapper, listener);
2090 // newGraph.waitAsync(syncParent);
2092 Throwable e = wrapper.getException();
2094 // The request was async - produce meaningful stack trace by
2096 if (e instanceof DatabaseException)
2097 throw (DatabaseException) e;
2099 throw new DatabaseException(e);
2102 return wrapper.getResult();
2106 // System.out.println("direct call " + request );
2108 // Do not set the sync state.parent for external threads
2109 // Object syncParent = request;
2111 // final ReadGraphImpl newGraph = newSync();
2113 final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
2114 procedure, request);
2118 processor.tryQuery(this, request, wrapper);
2120 } catch (Throwable t) {
2122 wrapper.exception(this, t);
2126 Throwable e = wrapper.getException();
2128 // The request was async - produce meaningful stack trace by
2130 if (e instanceof DatabaseException)
2131 throw (DatabaseException) e;
2133 throw new DatabaseException(e);
2136 return wrapper.getResult();
2142 final private <T> void syncRequest(final AsyncRead<T> request, final AsyncReadProcedure<T> procedure) throws DatabaseException {
2144 assert (request != null);
2146 // System.out.println("syncRequest " + request + " syncParent=" +
2149 ListenerBase listener = getListenerBase(procedure);
2151 if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
2153 // final ReadGraphImpl newGraph = newSync();
2155 final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
2156 procedure, request);
2158 processor.query(this, request, parent, wrapper, listener);
2164 // final ReadGraphImpl newGraph = newSync();
2165 processor.tryQuery(this, request, procedure);
2166 // newGraph.waitAsync(null);
2167 waitAsyncProcedure(procedure);
2169 } catch (Throwable t) {
2170 if(Development.DEVELOPMENT) {
2171 if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
2172 t.printStackTrace();
2175 procedure.exception(this, t);
2176 waitAsyncProcedure(procedure);
2184 public <T> T syncRequest(AsyncRead<T> request,
2185 final SyncProcedure<T> procedure) throws DatabaseException {
2186 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2190 final public <T> T syncRequest(final AsyncRead<T> request,
2191 final Procedure<T> procedure) throws DatabaseException {
2192 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2196 public <T> Collection<T> syncRequest(final MultiRead<T> request)
2197 throws DatabaseException {
2199 assert (request != null);
2201 final ArrayList<T> result = new ArrayList<T>();
2202 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2204 syncRequest(request, new AsyncMultiProcedure<T>() {
2207 public void execute(AsyncReadGraph graph, T t) {
2208 synchronized (result) {
2214 public void finished(AsyncReadGraph graph) {
2218 public void exception(AsyncReadGraph graph, Throwable t) {
2223 public String toString() {
2224 return "syncRequest(MultiRead) -> " + request;
2229 Throwable t = exception.get();
2231 if (t instanceof DatabaseException)
2232 throw (DatabaseException) t;
2234 throw new DatabaseException(
2235 "Unexpected exception in ReadGraph.syncRequest(Read)",
2244 public <T> Collection<T> syncRequest(MultiRead<T> request,
2245 AsyncMultiListener<T> procedure) {
2246 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2250 public <T> Collection<T> syncRequest(MultiRead<T> request,
2251 SyncMultiListener<T> procedure) {
2252 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2256 public <T> Collection<T> syncRequest(MultiRead<T> request,
2257 MultiListener<T> procedure) {
2258 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2262 public <T> Collection<T> syncRequest(MultiRead<T> request,
2263 AsyncMultiProcedure<T> procedure) {
2265 assert (request != null);
2267 ListenerBase listener = getListenerBase(procedure);
2269 if (parent != null || listener != null) {
2271 // Object syncParent = request;
2273 // final ReadGraphImpl newGraph = newSync();
2275 processor.query(this, request, parent, procedure, listener);
2277 // newGraph.waitAsync(syncParent);
2281 // Object syncParent = request;
2283 // final ReadGraphImpl newGraph = newSync();
2285 final ResultCallWrappedQueryProcedure4<T> wrapper = new ResultCallWrappedQueryProcedure4<T>(procedure);
2289 request.perform(this, wrapper);
2291 } catch (Throwable t) {
2293 wrapper.exception(this, t);
2294 // newGraph.waitAsync(syncParent);
2306 public <T> Collection<T> syncRequest(MultiRead<T> request,
2307 SyncMultiProcedure<T> procedure) {
2308 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2312 public <T> Collection<T> syncRequest(MultiRead<T> request,
2313 MultiProcedure<T> procedure) {
2314 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2317 static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2319 private static Throwable DONE = new Throwable();
2321 private static final long serialVersionUID = -6494230465108115812L;
2323 Throwable exception = null;
2326 public synchronized void execute(AsyncReadGraph graph, T t) {
2331 public void finished(AsyncReadGraph graph) {
2336 public void exception(AsyncReadGraph graph, Throwable t) {
2340 public void checkAndThrow() throws DatabaseException {
2341 if(exception != DONE) {
2342 if (exception instanceof DatabaseException)
2343 throw (DatabaseException) exception;
2345 throw new DatabaseException(
2346 "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2351 public boolean done() {
2352 return exception != null;
2358 final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2359 throws DatabaseException {
2361 assert (request != null);
2363 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2365 syncRequest(request, procedure);
2367 procedure.checkAndThrow();
2373 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2374 AsyncMultiListener<T> procedure) {
2375 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2379 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2380 SyncMultiListener<T> procedure) {
2381 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2385 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2386 MultiListener<T> procedure) {
2387 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2390 final private <T> void syncRequest(final AsyncMultiRead<T> request,
2391 final AsyncMultiReadProcedure<T> procedure) {
2393 assert (request != null);
2394 assert (procedure != null);
2396 ListenerBase listener = getListenerBase(procedure);
2398 if (parent != null || listener != null) {
2400 // Object syncParent = request;
2402 // final ReadGraphImpl newGraph = newSync();
2404 processor.query(this, request, parent, procedure, listener);
2406 // newGraph.waitAsync(syncParent);
2407 waitAsyncProcedure(procedure);
2411 // Object syncParent = callerThread == Integer.MIN_VALUE ? null
2414 // final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2419 // ReadGraphImpl sync = newSync();
2420 request.perform(this, procedure);
2421 // sync.waitAsync(null);
2422 waitAsyncProcedure(procedure);
2425 } catch (Throwable t) {
2427 waitAsyncProcedure(procedure);
2438 final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2439 final AsyncMultiProcedure<T> procedure) {
2441 assert (request != null);
2442 assert (procedure != null);
2444 ListenerBase listener = getListenerBase(procedure);
2446 if (parent != null || listener != null) {
2448 // Object syncParent = request;
2450 // final ReadGraphImpl newGraph = newSync();
2452 processor.query(this, request, parent, procedure, listener);
2454 // newGraph.waitAsync(syncParent);
2458 // Object syncParent = request;
2460 // final ReadGraphImpl newGraph = newSync();
2464 request.perform(this, new AsyncMultiProcedure<T>() {
2467 public void execute(AsyncReadGraph graph, T result) {
2468 procedure.execute(graph, result);
2472 public void finished(AsyncReadGraph graph) {
2473 procedure.finished(graph);
2477 public void exception(AsyncReadGraph graph, Throwable t) {
2478 procedure.exception(graph, t);
2482 public String toString() {
2483 return "syncRequest(AsyncMultiRead) -> " + procedure;
2488 } catch (Throwable t) {
2500 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2501 final SyncMultiProcedure<T> procedure) {
2502 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2506 final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2507 final MultiProcedure<T> procedure) {
2508 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2512 public <T> T syncRequest(final ExternalRead<T> request)
2513 throws DatabaseException {
2515 assert (request != null);
2517 return syncRequest(request, new Procedure<T>() {
2520 public void execute(T t) {
2524 public void exception(Throwable t) {
2528 public String toString() {
2529 return "syncRequest(AsyncRead) -> " + request;
2537 public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2538 return syncRequest(request, (Procedure<T>) procedure);
2542 final public <T> T syncRequest(final ExternalRead<T> request,
2543 final Procedure<T> procedure) throws DatabaseException {
2545 assert (request != null);
2547 ListenerBase listener = getListenerBase(procedure);
2549 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2550 final DataContainer<T> result = new DataContainer<T>();
2552 if (parent != null || listener != null) {
2554 // final ReadGraphImpl newGraph = newSync();
2556 processor.query(this, request, parent, new Procedure<T>() {
2559 public void exception(Throwable throwable) {
2560 exception.set(throwable);
2561 procedure.exception(throwable);
2565 public void execute(T t) {
2567 procedure.execute(t);
2572 // newGraph.waitAsync(request);
2578 T t = processor.tryQuery(this, request);
2580 procedure.execute(t);
2582 } catch (Throwable t) {
2584 if (t instanceof DatabaseException) {
2585 exception.set((DatabaseException)t);
2586 procedure.exception(exception.get());
2588 exception.set(new DatabaseException(
2589 "Unexpected exception in ReadGraph.syncRequest(Read)",
2591 procedure.exception(exception.get());
2598 Throwable t = exception.get();
2600 if (t instanceof DatabaseException)
2601 throw (DatabaseException) t;
2603 throw new DatabaseException(
2604 "Unexpected exception in ReadGraph.syncRequest(Read)",
2608 return result.get();
2613 public void syncRequest(final Write request) throws DatabaseException {
2615 assert (request != null);
2617 throw new DatabaseException(
2618 "Write operations are not supported during read transactions!");
2623 public <T> T syncRequest(final WriteResult<T> request) throws DatabaseException {
2625 assert (request != null);
2627 throw new DatabaseException(
2628 "Write operations are not supported during read transactions!");
2633 public void syncRequest(final DelayedWrite request)
2634 throws DatabaseException {
2636 assert (request != null);
2638 throw new DatabaseException(
2639 "Write operations are not supported during read transactions!");
2644 public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {