1 /*******************************************************************************
2 * Copyright (c) 2007, 2018 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.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.IdentityHashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
31 import java.util.function.Consumer;
33 import org.eclipse.core.runtime.Platform;
34 import org.simantics.databoard.Accessors;
35 import org.simantics.databoard.Bindings;
36 import org.simantics.databoard.accessor.Accessor;
37 import org.simantics.databoard.accessor.error.AccessorConstructionException;
38 import org.simantics.databoard.adapter.AdaptException;
39 import org.simantics.databoard.binding.Binding;
40 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;
41 import org.simantics.databoard.binding.impl.ObjectVariantBinding;
42 import org.simantics.databoard.binding.mutable.Variant;
43 import org.simantics.databoard.serialization.Serializer;
44 import org.simantics.databoard.type.Datatype;
45 import org.simantics.databoard.util.binary.BinaryFile;
46 import org.simantics.databoard.util.binary.RandomAccessBinary;
47 import org.simantics.db.AsyncReadGraph;
48 import org.simantics.db.ComputationalValue;
49 import org.simantics.db.DevelopmentKeys;
50 import org.simantics.db.ExternalValueSupport;
51 import org.simantics.db.ReadGraph;
52 import org.simantics.db.RelationContext;
53 import org.simantics.db.Resource;
54 import org.simantics.db.Session;
55 import org.simantics.db.Statement;
56 import org.simantics.db.adaption.AdaptionService;
57 import org.simantics.db.common.primitiverequest.Adapter;
58 import org.simantics.db.common.primitiverequest.Builtin;
59 import org.simantics.db.common.primitiverequest.DatatypeBinding;
60 import org.simantics.db.common.primitiverequest.ForEachAssertedObject;
61 import org.simantics.db.common.primitiverequest.ForEachAssertedStatement;
62 import org.simantics.db.common.primitiverequest.HasStatement;
63 import org.simantics.db.common.primitiverequest.HasStatementSubject;
64 import org.simantics.db.common.primitiverequest.HasStatementSubjectObject;
65 import org.simantics.db.common.primitiverequest.HasValue;
66 import org.simantics.db.common.primitiverequest.Inverse;
67 import org.simantics.db.common.primitiverequest.IsInheritedFrom;
68 import org.simantics.db.common.primitiverequest.IsInstanceOf;
69 import org.simantics.db.common.primitiverequest.IsSubrelationOf;
70 import org.simantics.db.common.primitiverequest.OrderedSet;
71 import org.simantics.db.common.primitiverequest.PossibleAdapter;
72 import org.simantics.db.common.primitiverequest.PossibleInverse;
73 import org.simantics.db.common.primitiverequest.PossibleObject;
74 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
75 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied;
76 import org.simantics.db.common.primitiverequest.PossibleStatement;
77 import org.simantics.db.common.primitiverequest.PossibleType;
78 import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter;
79 import org.simantics.db.common.primitiverequest.PossibleValue;
80 import org.simantics.db.common.primitiverequest.PossibleValueImplied;
81 import org.simantics.db.common.primitiverequest.RelatedValue;
82 import org.simantics.db.common.primitiverequest.RelatedValueImplied;
83 import org.simantics.db.common.primitiverequest.SingleObject;
84 import org.simantics.db.common.primitiverequest.SingleStatement;
85 import org.simantics.db.common.primitiverequest.SingleType;
86 import org.simantics.db.common.primitiverequest.SingleTypeAny;
87 import org.simantics.db.common.primitiverequest.Types;
88 import org.simantics.db.common.primitiverequest.UniqueAdapter;
89 import org.simantics.db.common.primitiverequest.Value;
90 import org.simantics.db.common.primitiverequest.ValueImplied;
91 import org.simantics.db.common.primitiverequest.VariantValueImplied;
92 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
93 import org.simantics.db.common.procedure.adapter.AsyncProcedureAdapter;
94 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
95 import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
96 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
97 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
98 import org.simantics.db.common.procedure.single.SyncReadProcedure;
99 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrErrorProcedure;
100 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure;
101 import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure;
102 import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure;
103 import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure;
104 import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure;
105 import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure;
106 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
107 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
108 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
109 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
110 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
111 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
112 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
113 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
114 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
115 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
116 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
117 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
118 import org.simantics.db.common.request.AdaptValue;
119 import org.simantics.db.common.request.ResourceRead;
120 import org.simantics.db.common.utils.Logger;
121 import org.simantics.db.common.utils.NameUtils;
122 import org.simantics.db.common.validation.L0Validations;
123 import org.simantics.db.exception.AdaptionException;
124 import org.simantics.db.exception.ArgumentException;
125 import org.simantics.db.exception.AssumptionException;
126 import org.simantics.db.exception.BindingException;
127 import org.simantics.db.exception.DatabaseException;
128 import org.simantics.db.exception.DoesNotContainValueException;
129 import org.simantics.db.exception.EmptyResourceException;
130 import org.simantics.db.exception.InternalException;
131 import org.simantics.db.exception.InvalidLiteralException;
132 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
133 import org.simantics.db.exception.NoInverseException;
134 import org.simantics.db.exception.NoSingleResultException;
135 import org.simantics.db.exception.ResourceNotFoundException;
136 import org.simantics.db.exception.ServiceException;
137 import org.simantics.db.exception.ValidationException;
138 import org.simantics.db.impl.RelationContextImpl;
139 import org.simantics.db.impl.ResourceImpl;
140 import org.simantics.db.impl.internal.RandomAccessValueSupport;
141 import org.simantics.db.impl.internal.ResourceData;
142 import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
143 import org.simantics.db.impl.query.CacheEntry;
144 import org.simantics.db.impl.query.QueryCache;
145 import org.simantics.db.impl.query.QueryCacheBase;
146 import org.simantics.db.impl.query.QueryProcessor;
147 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
148 import org.simantics.db.impl.query.QuerySupport;
149 import org.simantics.db.impl.query.TripleIntProcedure;
150 import org.simantics.db.impl.support.ResourceSupport;
151 import org.simantics.db.procedure.AsyncListener;
152 import org.simantics.db.procedure.AsyncMultiListener;
153 import org.simantics.db.procedure.AsyncMultiProcedure;
154 import org.simantics.db.procedure.AsyncProcedure;
155 import org.simantics.db.procedure.AsyncSetListener;
156 import org.simantics.db.procedure.Listener;
157 import org.simantics.db.procedure.ListenerBase;
158 import org.simantics.db.procedure.MultiListener;
159 import org.simantics.db.procedure.MultiProcedure;
160 import org.simantics.db.procedure.Procedure;
161 import org.simantics.db.procedure.SetListener;
162 import org.simantics.db.procedure.StatementProcedure;
163 import org.simantics.db.procedure.SyncListener;
164 import org.simantics.db.procedure.SyncMultiListener;
165 import org.simantics.db.procedure.SyncMultiProcedure;
166 import org.simantics.db.procedure.SyncProcedure;
167 import org.simantics.db.procedure.SyncSetListener;
168 import org.simantics.db.request.AsyncMultiRead;
169 import org.simantics.db.request.AsyncRead;
170 import org.simantics.db.request.DelayedWrite;
171 import org.simantics.db.request.DelayedWriteResult;
172 import org.simantics.db.request.ExternalRead;
173 import org.simantics.db.request.MultiRead;
174 import org.simantics.db.request.Read;
175 import org.simantics.db.request.ReadInterface;
176 import org.simantics.db.request.Write;
177 import org.simantics.db.request.WriteInterface;
178 import org.simantics.db.request.WriteOnly;
179 import org.simantics.db.request.WriteOnlyResult;
180 import org.simantics.db.request.WriteResult;
181 import org.simantics.layer0.Layer0;
182 import org.simantics.scl.compiler.types.Type;
183 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
184 import org.simantics.scl.reflection.ReflectionUtils;
185 import org.simantics.scl.reflection.ValueNotFoundException;
186 import org.simantics.scl.runtime.function.Function3;
187 import org.simantics.utils.DataContainer;
188 import org.simantics.utils.Development;
189 import org.simantics.utils.datastructures.Pair;
190 import org.simantics.utils.datastructures.collections.CollectionUtils;
191 import org.slf4j.LoggerFactory;
193 import gnu.trove.map.hash.TObjectIntHashMap;
195 public class ReadGraphImpl implements AsyncReadGraph {
197 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
199 final static boolean EMPTY_RESOURCE_CHECK = false;
201 final public CacheEntry parent;
202 public final ReadGraphImpl parentGraph;
203 final public QueryProcessor processor;
205 public final AsyncBarrierImpl asyncBarrier;
207 final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
208 final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
210 final public static TObjectIntHashMap<String> counters = new TObjectIntHashMap<String>();
212 public static void resetCounters() {
216 public static String listCounters(File file) throws IOException {
218 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
220 for(Pair<String,Integer> p : CollectionUtils.valueSortedEntries(counters)) {
221 b.print(-p.second + " " + p.first + "\n");
226 return "Dumped " + counters.size() + " queries.";
231 * Implementation of the interface ReadGraph
233 final public String getURI(final Resource resource) throws AssumptionException, ValidationException, ServiceException {
235 assert (resource != null);
239 return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource));
241 } catch (AssumptionException e) {
243 throw new AssumptionException(e);
245 } catch (ValidationException e) {
247 throw new ValidationException(e);
249 } catch (ServiceException e) {
251 throw new ServiceException(e);
253 } catch (DatabaseException e) {
255 throw new ServiceException(INTERNAL_ERROR_STRING, e);
261 final public String getPossibleURI(final Resource resource) throws ValidationException, ServiceException {
263 assert (resource != null);
267 return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource));
269 } catch (ValidationException e) {
271 throw new ValidationException(e);
273 } catch (ServiceException e) {
275 throw new ServiceException(e);
277 } catch (DatabaseException e) {
279 throw new ServiceException(INTERNAL_ERROR_STRING, e);
285 final public Resource getResource(final String id)
286 throws ResourceNotFoundException, ValidationException,
293 Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
294 // FIXME: stupid to throw this here and catch and wrap it right away
295 if(rid == 0) throw new ResourceNotFoundException(id);
296 return processor.querySupport.getResource(rid);
298 } catch (ResourceNotFoundException e) {
300 throw new ResourceNotFoundException(id, e);
302 } catch (ValidationException e) {
304 throw new ValidationException(e);
306 } catch (ServiceException e) {
308 throw new ServiceException(e);
310 } catch (DatabaseException e) {
312 throw new ServiceException(INTERNAL_ERROR_STRING, e);
318 final public Resource getPossibleResource(final String id)
319 throws ResourceNotFoundException, ValidationException,
326 return getResource(id);
328 } catch (ResourceNotFoundException e) {
332 } catch (ValidationException e) {
334 throw new ValidationException(e);
336 } catch (ServiceException e) {
338 throw new ServiceException(e);
340 } catch (DatabaseException e) {
342 throw new ServiceException(INTERNAL_ERROR_STRING, e);
349 public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
351 assert (resource != null);
355 int rId = processor.querySupport.getId(resource);
356 return QueryCache.resultChildMap(this, rId, parent, null);
358 } catch (ValidationException e) {
360 throw new ValidationException(e);
362 } catch (ServiceException e) {
364 throw new ServiceException(e);
366 } catch (DatabaseException e) {
368 throw new ServiceException(INTERNAL_ERROR_STRING, e);
374 final public Resource getRootLibrary() {
375 return processor.getRootLibraryResource();
378 final public Resource getBuiltin(final String id)
379 throws ResourceNotFoundException, ServiceException {
385 return syncRequest(new Builtin(id));
387 } catch (ResourceNotFoundException e) {
389 throw new ResourceNotFoundException(id, e);
391 } catch (ServiceException e) {
393 throw new ServiceException(e);
395 } catch (DatabaseException e) {
397 throw new ServiceException(INTERNAL_ERROR_STRING, e);
403 static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure {
405 private static Throwable DONE = new Throwable();
407 Throwable exception = null;
409 final ResourceSupport support;
411 public StatementReadProcedure(ResourceSupport support) {
412 this.support = support;
416 public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) {
423 public void finished(AsyncReadGraph graph) {
428 public void exception(AsyncReadGraph graph, Throwable t) {
432 public void checkAndThrow() throws DatabaseException {
433 if(exception != DONE) {
434 if (exception instanceof DatabaseException)
435 throw (DatabaseException) exception;
437 throw new DatabaseException(
438 "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
443 public boolean done() {
444 return exception != null;
448 public boolean contains(Object obj) {
449 if(!(obj instanceof InternalStatement))
451 InternalStatement statement = (InternalStatement)obj;
455 for(int i=0;i<sizeInternal();i+=3)
456 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
461 @SuppressWarnings("unchecked")
463 public <T> T[] toArray(T[] a) {
464 int length = sizeInternal() / 3;
465 if(length > a.length) {
466 Class<?> arrayType = a.getClass();
467 a = (arrayType == Object[].class)
468 ? (T[]) new Object[length]
469 : (T[]) Array.newInstance(arrayType.getComponentType(), length);
472 for(int i=length;i<a.length;++i)
475 for(int i=0,j=0;i<sizeInternal();i+=3,++j)
476 a[j] = (T)new InternalStatement(support, getQuick(i), getQuick(i+1), getQuick(i+2));
481 public boolean add(Statement e) {
482 throw new UnsupportedOperationException();
486 public boolean remove(Object o) {
487 throw new UnsupportedOperationException();
491 public boolean addAll(Collection<? extends Statement> c) {
492 throw new UnsupportedOperationException();
495 class IteratorImpl implements ListIterator<Statement> {
499 public IteratorImpl(int index) {
504 public boolean hasNext() {
505 return index < sizeInternal();
509 public Statement next() {
510 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
516 public void remove() {
517 throw new Error("Not supported");
521 public boolean hasPrevious() {
526 public Statement previous() {
528 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
533 public int nextIndex() {
538 public int previousIndex() {
543 public void set(Statement e) {
544 throw new UnsupportedOperationException();
548 public void add(Statement e) {
549 throw new UnsupportedOperationException();
555 public Iterator<Statement> iterator() {
556 return new IteratorImpl(0);
561 return sizeInternal() / 3;
565 public Object[] toArray() {
566 Object[] result = new Object[sizeInternal() / 3];
567 for(int i=0,j=0;j<sizeInternal();i++,j+=3)
568 result[i] = new InternalStatement(support, getQuick(j), getQuick(j+1), getQuick(j+2));
573 public boolean addAll(int index, Collection<? extends Statement> c) {
574 throw new UnsupportedOperationException();
578 public Statement get(int index) {
580 if(index < 0 || index >= sizeInternal())
581 throw new IndexOutOfBoundsException();
582 return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
586 public Statement set(int index, Statement element) {
587 throw new UnsupportedOperationException();
591 public void add(int index, Statement element) {
592 throw new UnsupportedOperationException();
596 public Statement remove(int index) {
597 throw new UnsupportedOperationException();
601 public int indexOf(Object obj) {
602 if(!(obj instanceof InternalStatement))
604 InternalStatement statement = (InternalStatement)obj;
608 for(int i=0;i<sizeInternal();i+=3)
609 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
615 public int lastIndexOf(Object obj) {
616 if(!(obj instanceof InternalStatement))
618 InternalStatement statement = (InternalStatement)obj;
622 for(int i=sizeInternal()-3;i>=0;i-=3)
623 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
629 public ListIterator<Statement> listIterator() {
630 return new IteratorImpl(0);
634 public ListIterator<Statement> listIterator(int index) {
635 return new IteratorImpl(index*3);
639 public List<Statement> subList(int fromIndex, int toIndex) {
640 if(fromIndex < 0 || toIndex*3 >= sizeInternal() || fromIndex > toIndex)
641 throw new IndexOutOfBoundsException();
642 return new RandomAccessSubList<Statement>(this, fromIndex, toIndex-fromIndex);
647 final public Collection<Statement> getStatements(final Resource subject,
648 final Resource relation)
649 throws ManyObjectsForFunctionalRelationException, ServiceException {
651 assert (subject != null);
652 assert (relation != null);
656 StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
657 processor.forEachStatement(this, subject, relation, procedure);
658 procedure.checkAndThrow();
661 } catch (DatabaseException e) {
663 System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation);
665 StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
666 processor.forEachStatement(this, subject, relation, procedure);
668 return Collections.emptyList();
670 // throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e);
677 final public Collection<Statement> getAssertedStatements(final Resource subject, final Resource relation)
678 throws ManyObjectsForFunctionalRelationException, ServiceException {
680 assert (subject != null);
681 assert (relation != null);
685 return syncRequest(new ForEachAssertedStatement(subject, relation));
687 } catch (ManyObjectsForFunctionalRelationException e) {
689 throw new ManyObjectsForFunctionalRelationException(e);
691 } catch (ServiceException e) {
693 throw new ServiceException(e);
695 } catch (DatabaseException e) {
697 throw new ServiceException(INTERNAL_ERROR_STRING, e);
704 final public Collection<Resource> getPredicates(final Resource subject) throws ServiceException {
706 assert (subject != null);
710 return processor.getPredicates(this, subject);
712 // AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
713 // processor.forEachPredicate(this, subject, procedure);
714 // procedure.checkAndThrow();
717 } catch (ServiceException e) {
719 throw new ServiceException(e);
721 } catch (DatabaseException e) {
723 throw new ServiceException(INTERNAL_ERROR_STRING, e);
725 } catch (Throwable e) {
727 throw new ServiceException(e);
734 final public Collection<Resource> getPrincipalTypes(final Resource subject)
735 throws ServiceException {
737 assert (subject != null);
741 AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
742 processor.forEachPrincipalType(this, subject, procedure);
743 procedure.checkAndThrow();
746 } catch (ServiceException e) {
748 throw new ServiceException(e);
750 } catch (DatabaseException e) {
752 throw new ServiceException(INTERNAL_ERROR_STRING, e);
759 final public Set<Resource> getTypes(final Resource subject) throws ServiceException {
761 assert (subject != null);
765 return processor.getTypes(this, subject);
767 } catch (ServiceException e) {
769 throw new ServiceException(e);
771 } catch (DatabaseException e) {
773 throw new ServiceException(INTERNAL_ERROR_STRING, e);
775 } catch (Throwable e) {
777 throw new ServiceException(e);
784 final public Set<Resource> getSupertypes(final Resource subject)
785 throws ServiceException {
787 assert (subject != null);
791 SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
792 processor.forSupertypes(this, subject, procedure);
793 procedure.checkAndThrow();
794 return procedure.result;
796 } catch (ServiceException e) {
798 throw new ServiceException(e);
800 } catch (DatabaseException e) {
802 throw new ServiceException(INTERNAL_ERROR_STRING, e);
809 final public Set<Resource> getSuperrelations(final Resource subject)
810 throws ServiceException {
812 assert (subject != null);
816 SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
817 processor.forSuperrelations(this, subject, procedure);
818 procedure.checkAndThrow();
819 return procedure.result;
821 } catch (ServiceException e) {
823 throw new ServiceException(e);
825 } catch (DatabaseException e) {
827 throw new ServiceException(INTERNAL_ERROR_STRING, e);
834 public Resource getPossibleSuperrelation(Resource subject) throws ServiceException {
838 SyncReadProcedure<Resource> procedure = new SyncReadProcedure<Resource>();
839 processor.forPossibleSuperrelation(this, subject, procedure);
840 procedure.checkAndThrow();
841 return procedure.result;
843 } catch (ServiceException e) {
845 throw new ServiceException(e);
847 } catch (DatabaseException e) {
849 throw new ServiceException(INTERNAL_ERROR_STRING, e);
856 final public Collection<Resource> getObjects(final Resource subject, final Resource relation)
857 throws ServiceException {
859 assert (subject != null);
860 assert (relation != null);
862 if(Development.DEVELOPMENT) {
863 if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) {
864 counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1);
866 //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace();
871 AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
872 processor.forEachObject(this, subject, relation, procedure);
873 procedure.checkAndThrow();
876 } catch (DatabaseException e) {
878 throw new ServiceException(INTERNAL_ERROR_STRING, e);
885 final public Collection<Resource> getAssertedObjects(
886 final Resource subject, final Resource relation)
887 throws ManyObjectsForFunctionalRelationException, ServiceException {
890 throw new ArgumentException("Subject must not be null.");
891 if (relation == null)
892 throw new ArgumentException("Relation must not be null. Subject=" + subject);
896 return syncRequest(new ForEachAssertedObject(subject, relation));
898 } catch (ManyObjectsForFunctionalRelationException e) {
900 throw new ManyObjectsForFunctionalRelationException(e);
902 } catch (ServiceException e) {
904 throw new ServiceException(e);
906 } catch (DatabaseException e) {
908 throw new ServiceException(INTERNAL_ERROR_STRING, e);
915 final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException {
917 assert (relation != null);
921 return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
923 } catch (NoSingleResultException e) {
925 throw new NoInverseException(e);
927 } catch (ServiceException e) {
929 throw new ServiceException(e);
936 final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException {
938 if( subject == null) throw new IllegalArgumentException("subject can not be null");
939 if( relation == null) throw new IllegalArgumentException("relation can not be null");
942 int single = processor.getSingleObject(this, subject, relation);
944 if (EMPTY_RESOURCE_CHECK) {
945 if (!hasStatement(subject)) {
946 throw new EmptyResourceException("Resource " + debugString(subject));
949 throw new NoSingleResultException("No single object for subject " + debugString(subject)
950 + " and relation " + debugString(relation), single);
952 return processor.querySupport.getResource(single);
953 } catch (NoSingleResultException e) {
955 } catch (DatabaseException e) {
956 throw new ServiceException(e);
961 final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
962 assert (subject != null);
963 assert (relation != null);
965 Collection<Statement> statements = getStatements(subject, relation);
966 if (statements.size() == 1) {
967 return statements.iterator().next();
969 if (EMPTY_RESOURCE_CHECK)
970 if (!hasStatement(subject))
971 throw new EmptyResourceException("Resource " + debugString(subject));
972 throw new NoSingleResultException("No single statement for subject " + debugString(subject)
973 + " and relation " + debugString(relation), statements.size());
975 } catch (ServiceException e) {
976 throw new ServiceException(e);
981 final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
982 assert (subject != null);
984 ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
985 if (principalTypes.size() == 1) {
986 return principalTypes.get(0);
988 throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
990 } catch (ServiceException e) {
991 throw new ServiceException(e);
996 final public Resource getSingleType(final Resource subject,
997 final Resource baseType) throws NoSingleResultException,
1000 assert (subject != null);
1001 assert (baseType != null);
1004 return syncRequest(new SingleType(subject, baseType));
1005 } catch (DatabaseException e) {
1006 throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
1011 final public <T> T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1013 assert (subject != null);
1017 Layer0 L0 = processor.getL0(this);
1018 int object = processor.getSingleObject(this, subject, L0.HasDataType);
1019 if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1021 if(processor.isImmutable(object)) {
1022 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance());
1023 return getValue(subject, binding);
1025 byte[] dt = processor.getValue(this, object);
1026 if(dt == null) throw new ServiceException("No data type for " + subject);
1027 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1028 Binding binding = Bindings.getBinding(datatype);
1029 return getValue(subject, binding);
1032 } catch (IOException e) {
1034 throw new ServiceException(e);
1036 } catch (DoesNotContainValueException e) {
1038 throw new DoesNotContainValueException(e, subject);
1040 } catch (ServiceException e) {
1042 throw new ServiceException(e);
1044 } catch (DatabaseException e) {
1046 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1053 final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1055 assert (subject != null);
1059 Layer0 L0 = processor.getL0(this);
1060 int object = processor.getSingleObject(this, subject, L0.HasDataType);
1061 if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1063 if(processor.isImmutable(object)) {
1064 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance());
1065 return new Variant(binding, getValue(subject, binding));
1067 byte[] dt = processor.getValue(this, object);
1068 if(dt == null) throw new ServiceException("No data type for " + subject);
1069 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1070 Binding binding = Bindings.getBinding(datatype);
1071 return new Variant(binding, getValue(subject, binding));
1074 } catch (IOException e) {
1076 throw new ServiceException(e);
1078 } catch (DoesNotContainValueException e) {
1080 throw new DoesNotContainValueException(e, subject);
1082 } catch (ServiceException e) {
1084 throw new ServiceException(e);
1086 } catch (DatabaseException e) {
1088 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1093 static final IdentityHashMap<Binding,Serializer> serializers = new IdentityHashMap<Binding,Serializer>();
1096 serializers.put(Bindings.STRING, Bindings.STRING.serializer());
1099 final protected Serializer getSerializer(Binding binding) {
1100 return binding.serializer();
1104 final public <T> T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException,
1107 assert (subject != null);
1109 byte[] bytes = null;
1112 bytes = processor.getValue(this, subject);
1113 if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
1115 Serializer serializer = getSerializer(binding);
1116 return (T)serializer.deserialize(bytes);
1118 } catch (DoesNotContainValueException e) {
1120 throw new DoesNotContainValueException(e);
1122 } catch (Throwable t) {
1123 throw new ServiceException("Could not getValue for subject " + debugString(subject) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(bytes), t);
1128 final public <T> T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1129 DoesNotContainValueException, ServiceException {
1131 assert (subject != null);
1132 assert (relation != null);
1135 Resource object = getSingleObject(subject, relation);
1136 return getValue(object);
1137 } catch (NoSingleResultException e) {
1138 throw new NoSingleResultException("No single value found for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1139 } catch (DoesNotContainValueException e) {
1141 Layer0 L0 = processor.getL0(this);
1142 Resource object = getPossibleObject(subject, relation);
1143 if(isInstanceOf(object, L0.Value)) {
1144 if(isInstanceOf(object, L0.Literal)) {
1145 throw new DoesNotContainValueException(e);
1147 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1150 throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1152 } catch (DoesNotContainValueException e2) {
1154 } catch (DatabaseException e2) {
1155 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1157 } catch (ServiceException e) {
1158 throw new ServiceException(e);
1163 final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1164 DoesNotContainValueException, ServiceException {
1166 assert (subject != null);
1167 assert (relation != null);
1170 Resource object = getSingleObject(subject, relation);
1171 return getVariantValue(object);
1172 } catch (NoSingleResultException e) {
1173 throw new NoSingleResultException("No single object for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1174 } catch (DoesNotContainValueException e) {
1176 Layer0 L0 = processor.getL0(this);
1177 Resource object = getPossibleObject(subject, relation);
1178 if(isInstanceOf(object, L0.Value)) {
1179 if(isInstanceOf(object, L0.Literal)) {
1180 throw new DoesNotContainValueException(e);
1182 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1185 throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1187 } catch (DoesNotContainValueException e2) {
1189 } catch (DatabaseException e2) {
1190 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1192 } catch (ServiceException e) {
1193 throw new ServiceException(e);
1198 final public <T> T getRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1199 throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException {
1201 assert (subject != null);
1202 assert (relation != null);
1205 Resource object = getSingleObject(subject, relation);
1206 return getValue(object, binding);
1207 } catch (NoSingleResultException e) {
1208 String message = "";
1210 String subjectName = NameUtils.getSafeName(this, subject, true);
1211 String relationName = NameUtils.getSafeName(this, relation, true);
1212 message = "Subject: " + subjectName + ", Relation: " + relationName;
1213 } catch (DatabaseException e2) {
1216 throw new NoSingleResultException(message, e.getResultCount(), e);
1217 } catch (DoesNotContainValueException e) {
1218 throw new DoesNotContainValueException(e);
1219 } catch (ServiceException e) {
1220 throw new ServiceException(e);
1225 final public <T> T adapt(final Resource resource, final Class<T> clazz)
1226 throws AdaptionException, ValidationException, ServiceException {
1228 assert (resource != null);
1229 assert (clazz != null);
1233 return syncRequest(new Adapter<T>(resource, clazz));
1235 } catch (AdaptionException e) {
1237 throw new AdaptionException(e);
1239 } catch (ValidationException e) {
1241 throw new ValidationException(e);
1243 } catch (ServiceException e) {
1245 throw new ServiceException(e);
1247 } catch (DatabaseException e) {
1249 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1256 final public <T,C> T adaptContextual(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1257 throws AdaptionException, ValidationException, ServiceException {
1259 assert (resource != null);
1260 assert (context != null);
1262 class ContextualAdapter implements AsyncRead<T> {
1264 final private Resource resource;
1265 final private C context;
1266 final private Class<T> clazz;
1269 public int hashCode() {
1270 return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1274 final public int threadHash() {
1275 return resource.getThreadHash();
1279 public boolean equals(Object object) {
1282 else if (object == null)
1284 else if (getClass() != object.getClass())
1286 ContextualAdapter r = (ContextualAdapter)object;
1287 return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1291 public int getFlags() {
1295 public ContextualAdapter(Resource resource, C context, Class<T> clazz) {
1296 this.resource = resource;
1297 this.context = context;
1302 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1304 final AdaptionService service = getSession().peekService(AdaptionService.class);
1305 if (service == null)
1306 procedure.exception(graph, new ServiceException("No AdaptionService available"));
1308 service.adapt(graph, resource, context, contextClass, clazz, false, procedure);
1313 public String toString() {
1314 return "Adapter for (" + resource + "," + context + ") as " + clazz.getName();
1321 return syncRequest(new ContextualAdapter(resource, context, clazz));
1323 } catch (AdaptionException e) {
1325 throw new AdaptionException(e);
1327 } catch (ValidationException e) {
1329 throw new ValidationException(e);
1331 } catch (ServiceException e) {
1333 throw new ServiceException(e);
1335 } catch (DatabaseException e) {
1337 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1344 final public <T> T adaptRelated(final Resource resource, final Resource relation, final Class<T> clazz)
1345 throws AdaptionException, NoSingleResultException, ValidationException, ServiceException {
1347 assert (resource != null);
1348 assert (clazz != null);
1350 Statement stm = getSingleStatement(resource, relation);
1352 return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz);
1357 final public <T> T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class<T> clazz)
1358 throws ValidationException, ServiceException {
1361 return adaptRelated(resource, relation, clazz);
1362 } catch (DatabaseException e) {
1369 final public <T,C> T getPossibleContextualAdapter(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1370 throws ValidationException, ServiceException {
1372 assert (resource != null);
1373 assert (context != null);
1375 class PossibleContextualAdapter implements AsyncRead<T> {
1377 final private Resource resource;
1378 final private C context;
1379 final private Class<T> clazz;
1382 public int hashCode() {
1383 return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1387 final public int threadHash() {
1388 return resource.getThreadHash();
1392 public boolean equals(Object object) {
1395 else if (object == null)
1397 else if (getClass() != object.getClass())
1399 PossibleContextualAdapter r = (PossibleContextualAdapter)object;
1400 return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1404 public int getFlags() {
1408 public PossibleContextualAdapter(Resource resource, C context, Class<T> clazz) {
1409 this.resource = resource;
1410 this.context = context;
1415 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1417 final AdaptionService service = getSession().peekService(AdaptionService.class);
1418 if (service == null)
1419 procedure.exception(graph, new ServiceException("No AdaptionService available"));
1421 service.adapt(graph, resource, context, contextClass, clazz, true, procedure);
1426 public String toString() {
1427 return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName();
1434 return syncRequest(new PossibleContextualAdapter(resource, context, clazz));
1436 } catch (ValidationException e) {
1438 throw new ValidationException(e);
1440 } catch (ServiceException e) {
1442 throw new ServiceException(e);
1444 } catch (DatabaseException e) {
1446 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1453 final public <T> T adaptUnique(final Resource resource, final Class<T> clazz)
1454 throws AdaptionException, ValidationException, ServiceException {
1456 assert (resource != null);
1457 assert (clazz != null);
1461 return syncRequest(new UniqueAdapter<T>(resource, clazz));
1463 } catch (AdaptionException e) {
1465 throw new AdaptionException(e);
1467 } catch (ValidationException e) {
1469 throw new ValidationException(e);
1471 } catch (ServiceException e) {
1473 throw new ServiceException(e);
1475 } catch (DatabaseException e) {
1477 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1484 final public Resource getPossibleInverse(final Resource relation)
1485 throws ServiceException {
1487 assert (relation != null);
1491 return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
1493 } catch (ServiceException e) {
1495 throw new ServiceException(e);
1497 } catch (DatabaseException e) {
1499 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1506 public Resource getPossibleObject(final Resource subject, final Resource relation)
1507 throws ManyObjectsForFunctionalRelationException, ServiceException {
1509 assert (subject != null);
1510 assert (relation != null);
1514 int result = processor.getSingleObject(this, subject, relation);
1515 if(result == 0) return null;
1517 return processor.querySupport.getResource(result);
1519 } catch (ManyObjectsForFunctionalRelationException e) {
1521 throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
1523 } catch (DatabaseException e) {
1525 throw new ServiceException(e);
1532 final public Statement getPossibleStatement(final Resource subject, final Resource relation)
1533 throws ManyObjectsForFunctionalRelationException, ServiceException {
1535 assert (subject != null);
1536 assert (relation != null);
1540 Collection<Statement> statements = getStatements(subject, relation);
1541 if(statements.size() == 1) return statements.iterator().next();
1544 } catch (ManyObjectsForFunctionalRelationException e) {
1546 throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
1548 } catch (ServiceException e) {
1550 throw new ServiceException(e);
1557 final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException {
1559 assert (subject != null);
1560 assert (baseType != null);
1564 AsyncReadProcedure<Resource> procedure = new AsyncReadProcedure<Resource>();
1565 forPossibleType(subject, baseType, procedure);
1566 procedure.checkAndThrow();
1567 return procedure.result;
1569 } catch (ServiceException e) {
1571 throw new ServiceException(e);
1573 } catch (DatabaseException e) {
1575 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1582 final public <T> T getPossibleValue(final Resource subject) throws ServiceException {
1584 assert (subject != null);
1588 int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType);
1589 if(object == 0) return null;
1591 if(processor.isImmutable(object)) {
1592 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance());
1593 return getPossibleValue(subject, binding);
1595 byte[] dt = processor.getValue(this, object);
1596 if(dt == null) return null;
1597 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1598 Binding binding = Bindings.getBinding(datatype);
1599 return getPossibleValue(subject, binding);
1602 } catch (IOException e) {
1604 throw new ServiceException(e);
1606 } catch (ServiceException e) {
1608 throw new ServiceException(e);
1610 } catch (DatabaseException e) {
1612 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1619 final public <T> T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException {
1621 assert (subject != null);
1622 assert (binding != null);
1626 byte[] dt = processor.getValue(this, subject);
1627 if(dt == null) return null;
1628 Serializer serializer = getSerializer(binding);
1629 return (T)serializer.deserialize(dt);
1631 } catch (IOException e) {
1633 throw new ServiceException(e);
1635 } catch (BindingException e) {
1637 throw new BindingException(e);
1639 } catch (ServiceException e) {
1641 throw new ServiceException(e);
1643 } catch (DatabaseException e) {
1644 e.printStackTrace();
1645 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1651 public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation)
1652 throws ManyObjectsForFunctionalRelationException, ServiceException {
1654 assert (subject != null);
1655 assert (relation != null);
1659 Resource object = getPossibleObject(subject, relation);
1660 if(object == null) return null;
1661 else return getPossibleValue(object);
1663 } catch (ManyObjectsForFunctionalRelationException e) {
1665 throw new ManyObjectsForFunctionalRelationException(e);
1667 } catch (ServiceException e) {
1669 throw new ServiceException(e);
1676 public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1677 throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
1679 assert (subject != null);
1680 assert (relation != null);
1681 assert (binding != null);
1685 Resource object = getPossibleObject(subject, relation);
1686 if(object == null) return null;
1687 else return getPossibleValue(object, binding);
1689 } catch (ManyObjectsForFunctionalRelationException e) {
1691 throw new ManyObjectsForFunctionalRelationException(e);
1693 } catch (BindingException e) {
1695 throw new BindingException(e);
1697 } catch (ServiceException e) {
1699 throw new ServiceException(e);
1706 public <T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1708 assert (resource != null);
1709 assert (clazz != null);
1713 return syncRequest(new PossibleAdapter<T>(resource, clazz));
1715 } catch (ValidationException e) {
1717 throw new ValidationException(e);
1719 } catch (AdaptionException e) {
1723 } catch (DatabaseException e) {
1725 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1731 public <T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1733 assert (resource != null);
1734 assert (clazz != null);
1738 return syncRequest(new PossibleUniqueAdapter<T>(resource, clazz));
1740 } catch (AdaptionException e) {
1744 } catch (ValidationException e) {
1746 throw new ValidationException(e);
1748 } catch (DatabaseException e) {
1750 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1757 final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException {
1759 assert (resource != null);
1760 assert (type != null);
1762 Set<Resource> resources = getTypes(resource);
1763 // This check was necessary because some of the callers of this method got stuck when the NPE was thrown from here.
1764 if (null == resources)
1767 if(EMPTY_RESOURCE_CHECK) {
1768 if (resources.isEmpty()) {
1769 if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource));
1773 return resources.contains(type);
1778 final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException {
1780 assert (resource != null);
1781 assert (type != null);
1785 if(resource.equals(type)) return true;
1787 return getSupertypes(resource).contains(type);
1789 } catch (ServiceException e) {
1791 throw new ServiceException(e);
1798 final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException {
1800 assert (resource != null);
1801 assert (type != null);
1805 if(resource.equals(type)) return true;
1807 return getSuperrelations(resource).contains(type);
1809 } catch (ServiceException e) {
1811 throw new ServiceException(e);
1818 final public boolean hasStatement(final Resource subject) throws ServiceException {
1820 assert (subject != null);
1824 SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1825 processor.forHasStatement(this, subject, procedure);
1826 procedure.checkAndThrow();
1827 return procedure.result;
1829 } catch (ServiceException e) {
1831 throw new ServiceException(e);
1833 } catch (DatabaseException e) {
1835 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1842 final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException {
1844 assert (subject != null);
1845 assert (relation != null);
1849 Collection<Resource> objects = getObjects(subject, relation);
1850 return !objects.isEmpty();
1852 } catch (ServiceException e) {
1854 throw new ServiceException(e);
1861 final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1863 assert (subject != null);
1864 assert (relation != null);
1865 assert (object != null);
1869 for(Resource o : getObjects(subject, relation)) {
1870 if(object.equals(o)) return true;
1875 } catch (ServiceException e) {
1877 throw new ServiceException(e);
1884 final public boolean hasValue(final Resource subject) throws ServiceException {
1886 assert (subject != null);
1890 SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1891 processor.forHasValue(this, subject, procedure);
1892 procedure.checkAndThrow();
1893 return procedure.result;
1895 } catch (ServiceException e) {
1897 throw new ServiceException(e);
1899 } catch (DatabaseException e) {
1901 throw new ServiceException(INTERNAL_ERROR_STRING, e);
1907 final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1910 public void execute(AsyncReadGraph graph, Object result) {
1914 public void exception(AsyncReadGraph graph, Throwable throwable) {
1920 * Implementation of the interface RequestProcessor
1924 public <T> T syncRequest(final Read<T> request) throws DatabaseException {
1925 assert (request != null);
1926 return (T)QueryCache.runnerReadEntry(this, request, parent, null, null, true);
1930 public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1931 throws DatabaseException {
1932 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1936 public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1937 throws DatabaseException {
1938 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1942 public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1944 assert (request != null);
1946 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1948 return QueryCache.resultReadEntry(this, request, parent, listener, procedure);
1953 public <T> T syncRequest(final Read<T> request,
1954 final SyncProcedure<T> procedure) throws DatabaseException {
1955 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
1959 public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
1960 throws DatabaseException {
1961 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
1964 static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
1966 private static Throwable DONE = new Throwable();
1969 Throwable exception = null;
1972 public void execute(AsyncReadGraph graph, T t) {
1978 public void exception(AsyncReadGraph graph, Throwable t) {
1982 public void checkAndThrow() throws DatabaseException {
1983 if(exception != DONE) {
1984 if (exception instanceof DatabaseException)
1985 throw (DatabaseException) exception;
1987 throw new DatabaseException(
1988 "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
1993 public boolean done() {
1994 return exception != null;
2000 public <T> T syncRequest(final AsyncRead<T> request)
2001 throws DatabaseException {
2003 assert (request != null);
2004 return syncRequest(request, new AsyncProcedureAdapter<>() );
2009 public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2010 throws DatabaseException {
2011 return syncRequest(request, (AsyncProcedure<T>) procedure);
2015 public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2016 throws DatabaseException {
2017 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2021 public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2022 throws DatabaseException {
2023 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2027 final public <T> T syncRequest(final AsyncRead<T> request,
2028 final AsyncProcedure<T> procedure) throws DatabaseException {
2030 assert (request != null);
2032 ListenerBase listener = getListenerBase(procedure);
2034 // BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2035 return (T)QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure, true);
2041 public <T> T syncRequest(AsyncRead<T> request,
2042 final SyncProcedure<T> procedure) throws DatabaseException {
2043 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2047 final public <T> T syncRequest(final AsyncRead<T> request,
2048 final Procedure<T> procedure) throws DatabaseException {
2049 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2053 public <T> Collection<T> syncRequest(final MultiRead<T> request)
2054 throws DatabaseException {
2056 assert (request != null);
2058 final ArrayList<T> result = new ArrayList<T>();
2059 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2061 syncRequest(request, new SyncMultiProcedure<T>() {
2064 public void execute(ReadGraph graph, T t) {
2065 synchronized (result) {
2071 public void finished(ReadGraph graph) {
2075 public void exception(ReadGraph graph, Throwable t) {
2080 public String toString() {
2081 return "syncRequest(MultiRead) -> " + request;
2086 Throwable t = exception.get();
2088 if (t instanceof DatabaseException)
2089 throw (DatabaseException) t;
2091 throw new DatabaseException(
2092 "Unexpected exception in ReadGraph.syncRequest(Read)",
2101 public <T> Collection<T> syncRequest(MultiRead<T> request,
2102 SyncMultiListener<T> procedure) {
2103 return syncRequest(request, (SyncMultiProcedure<T>)procedure);
2107 public <T> Collection<T> syncRequest(MultiRead<T> request,
2108 MultiListener<T> procedure) {
2109 return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
2113 public <T> Collection<T> syncRequest(MultiRead<T> request,
2114 SyncMultiProcedure<T> procedure) {
2116 assert (request != null);
2118 ListenerBase listener = getListenerBase(procedure);
2120 final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
2122 if (parent != null || listener != null) {
2124 // Object syncParent = request;
2126 // final ReadGraphImpl newGraph = newSync();
2128 processor.query(this, request, parent, wrapper, listener);
2130 // newGraph.waitAsync(syncParent);
2134 // Object syncParent = request;
2136 // final ReadGraphImpl newGraph = newSync();
2139 request.perform(this, wrapper);
2140 } catch (Throwable t) {
2141 wrapper.exception(this, t);
2146 return wrapper.get();
2151 public <T> Collection<T> syncRequest(MultiRead<T> request,
2152 MultiProcedure<T> procedure) {
2153 return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
2156 static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2158 private static Throwable DONE = new Throwable();
2160 private static final long serialVersionUID = -6494230465108115812L;
2162 Throwable exception = null;
2165 public synchronized void execute(AsyncReadGraph graph, T t) {
2170 public void finished(AsyncReadGraph graph) {
2175 public void exception(AsyncReadGraph graph, Throwable t) {
2179 public void checkAndThrow() throws DatabaseException {
2180 if(exception != DONE) {
2181 if (exception instanceof DatabaseException)
2182 throw (DatabaseException) exception;
2184 throw new DatabaseException(
2185 "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2190 public boolean done() {
2191 return exception != null;
2197 final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2198 throws DatabaseException {
2200 assert (request != null);
2202 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2204 syncRequest(request, procedure);
2206 procedure.checkAndThrow();
2212 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2213 AsyncMultiListener<T> procedure) {
2214 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2218 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2219 SyncMultiListener<T> procedure) {
2220 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2224 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2225 MultiListener<T> procedure) {
2226 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2229 final private <T> void syncRequest(final AsyncMultiRead<T> request,
2230 final AsyncMultiReadProcedure<T> procedure) {
2232 assert (request != null);
2233 assert (procedure != null);
2235 ListenerBase listener = getListenerBase(procedure);
2237 if (parent != null || listener != null) {
2239 // Object syncParent = request;
2241 // final ReadGraphImpl newGraph = newSync();
2243 processor.query(this, request, parent, procedure, listener);
2245 // newGraph.waitAsync(syncParent);
2246 waitAsyncProcedure(procedure);
2250 // Object syncParent = callerThread == Integer.MIN_VALUE ? null
2253 // final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2258 // ReadGraphImpl sync = newSync();
2259 request.perform(this, procedure);
2260 // sync.waitAsync(null);
2261 waitAsyncProcedure(procedure);
2264 } catch (Throwable t) {
2266 waitAsyncProcedure(procedure);
2277 final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2278 final AsyncMultiProcedure<T> procedure) {
2280 assert (request != null);
2281 assert (procedure != null);
2283 ListenerBase listener = getListenerBase(procedure);
2285 if (parent != null || listener != null) {
2287 // Object syncParent = request;
2289 // final ReadGraphImpl newGraph = newSync();
2291 processor.query(this, request, parent, procedure, listener);
2293 // newGraph.waitAsync(syncParent);
2297 // Object syncParent = request;
2299 // final ReadGraphImpl newGraph = newSync();
2303 request.perform(this, new AsyncMultiProcedure<T>() {
2306 public void execute(AsyncReadGraph graph, T result) {
2307 procedure.execute(graph, result);
2311 public void finished(AsyncReadGraph graph) {
2312 procedure.finished(graph);
2316 public void exception(AsyncReadGraph graph, Throwable t) {
2317 procedure.exception(graph, t);
2321 public String toString() {
2322 return "syncRequest(AsyncMultiRead) -> " + procedure;
2327 } catch (Throwable t) {
2339 public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2340 final SyncMultiProcedure<T> procedure) {
2341 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2345 final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2346 final MultiProcedure<T> procedure) {
2347 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2351 public <T> T syncRequest(final ExternalRead<T> request)
2352 throws DatabaseException {
2354 assert (request != null);
2356 return syncRequest(request, new Procedure<T>() {
2359 public void execute(T t) {
2363 public void exception(Throwable t) {
2367 public String toString() {
2368 return "syncRequest(AsyncRead) -> " + request;
2376 public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2377 return syncRequest(request, (Procedure<T>) procedure);
2381 final public <T> T syncRequest(final ExternalRead<T> request,
2382 final Procedure<T> procedure) throws DatabaseException {
2384 assert (request != null);
2386 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
2387 return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
2392 public void syncRequest(final Write request) throws DatabaseException {
2394 assert (request != null);
2396 throw new DatabaseException(
2397 "Write operations are not supported during read transactions!");
2402 public <T> T syncRequest(final WriteResult<T> request) throws DatabaseException {
2404 assert (request != null);
2406 throw new DatabaseException(
2407 "Write operations are not supported during read transactions!");
2412 public void syncRequest(final DelayedWrite request)
2413 throws DatabaseException {
2415 assert (request != null);
2417 throw new DatabaseException(
2418 "Write operations are not supported during read transactions!");
2423 public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {
2425 assert (request != null);
2427 throw new DatabaseException(
2428 "Write operations are not supported during read transactions!");
2433 public void syncRequest(final WriteOnly request) throws DatabaseException {
2435 assert (request != null);
2437 throw new DatabaseException(
2438 "Write operations are not supported during read transactions!");
2443 public <T> T syncRequest(final WriteOnlyResult<T> request) throws DatabaseException {
2445 assert (request != null);
2447 throw new DatabaseException(
2448 "Write operations are not supported during read transactions!");
2453 public <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure) {
2454 r.request(this, procedure);
2458 public <T> void async(ReadInterface<T> r, Procedure<T> procedure) {
2459 r.request(this, procedure);
2463 public <T> void async(ReadInterface<T> r, SyncProcedure<T> procedure) {
2464 r.request(this, procedure);
2468 public <T> void async(ReadInterface<T> r, AsyncListener<T> procedure) {
2469 r.request(this, procedure);
2473 public <T> void async(ReadInterface<T> r, Listener<T> procedure) {
2474 r.request(this, procedure);
2478 public <T> void async(ReadInterface<T> r, SyncListener<T> procedure) {
2479 r.request(this, procedure);
2483 public <T> T sync(ReadInterface<T> r) throws DatabaseException {
2484 return r.request(this);
2488 public <T> T sync(WriteInterface<T> r) throws DatabaseException {
2489 return r.request(this);
2493 public <T> void async(WriteInterface<T> r, Procedure<T> procedure) {
2494 r.request(this, procedure);
2498 public <T> void async(WriteInterface<T> r) {
2499 r.request(this, new ProcedureAdapter<T>());
2503 * Implementation of the interface AsyncReadGraph
2507 public void forURI(Resource resource, AsyncListener<String> listener) {
2508 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2513 public void forURI(Resource resource, SyncListener<String> listener) {
2514 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2519 public void forURI(Resource resource, Listener<String> listener) {
2520 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2525 final public void forURI(final Resource resource,
2526 final AsyncProcedure<String> procedure) {
2528 assert (resource != null);
2529 assert (procedure != null);
2531 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2537 public void forURI(Resource resource, SyncProcedure<String> procedure) {
2538 forURI(resource, new SyncToAsyncProcedure<String>(procedure));
2542 public void forURI(Resource resource, Procedure<String> procedure) {
2543 forURI(resource, new NoneToAsyncProcedure<String>(procedure));
2547 public void forResource(String id, AsyncListener<Resource> listener) {
2548 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2553 public void forResource(String id, SyncListener<Resource> listener) {
2554 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2559 public void forResource(String id, Listener<Resource> listener) {
2560 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2565 final public void forResource(final String id,
2566 final AsyncProcedure<Resource> procedure) {
2568 assert (id != null);
2569 assert (procedure != null);
2571 processor.forResource(this, id, procedure);
2576 public void forResource(String id, SyncProcedure<Resource> procedure) {
2577 forResource(id, new SyncToAsyncProcedure<Resource>(procedure));
2581 public void forResource(String id, Procedure<Resource> procedure) {
2582 forResource(id, new NoneToAsyncProcedure<Resource>(procedure));
2586 public void forBuiltin(String id, AsyncListener<Resource> listener) {
2587 asyncRequest(new Builtin(id), listener);
2591 public void forBuiltin(String id, SyncListener<Resource> listener) {
2592 asyncRequest(new Builtin(id), listener);
2596 public void forBuiltin(String id, Listener<Resource> listener) {
2597 asyncRequest(new Builtin(id), listener);
2601 final public void forBuiltin(final String id,
2602 final AsyncProcedure<Resource> procedure) {
2604 assert (id != null);
2605 assert (procedure != null);
2607 processor.forBuiltin(this, id, procedure);
2612 public void forBuiltin(String id, SyncProcedure<Resource> procedure) {
2613 forBuiltin(id, new SyncToAsyncProcedure<Resource>(procedure));
2617 public void forBuiltin(String id, Procedure<Resource> procedure) {
2618 forBuiltin(id, new NoneToAsyncProcedure<Resource>(procedure));
2622 final public void forEachStatement(Resource subject, Resource relation,
2623 AsyncMultiProcedure<Statement> procedure) {
2625 assert (subject != null);
2626 assert (relation != null);
2627 assert (procedure != null);
2629 processor.forEachStatement(this, subject, relation, procedure);
2634 public void forEachStatement(Resource subject, Resource relation,
2635 SyncMultiProcedure<Statement> procedure) {
2636 forEachStatement(subject, relation,
2637 new SyncToAsyncMultiProcedure<Statement>(procedure));
2641 final public void forEachStatement(Resource subject, Resource relation,
2642 MultiProcedure<Statement> procedure) {
2644 assert (subject != null);
2645 assert (relation != null);
2646 assert (procedure != null);
2648 processor.forEachStatement(this, subject, relation, procedure);
2653 final public void forStatementSet(Resource subject, Resource relation,
2654 AsyncSetListener<Statement> procedure) {
2656 assert (subject != null);
2657 assert (relation != null);
2658 assert (procedure != null);
2660 processor.forStatementSet(this, subject, relation, procedure);
2665 final public void forStatementSet(Resource subject, Resource relation,
2666 SyncSetListener<Statement> procedure) {
2667 forStatementSet(subject, relation,
2668 new SyncToAsyncSetProcedure<Statement>(procedure));
2672 public void forStatementSet(Resource subject, Resource relation,
2673 SetListener<Statement> listener) {
2674 forStatementSet(subject, relation,
2675 new NoneToAsyncSetProcedure<Statement>(listener));
2679 final public void forEachAssertedStatement(final Resource