]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
2ef40c29459d4be20009b30a73f54bd85b6fb08f
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / graph / ReadGraphImpl.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.graph;
13
14 import java.io.BufferedOutputStream;
15 import java.io.File;
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;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.function.Consumer;
32
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;
192
193 import gnu.trove.map.hash.TObjectIntHashMap;
194
195 public class ReadGraphImpl implements AsyncReadGraph {
196
197     private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
198
199     final static boolean EMPTY_RESOURCE_CHECK = false;
200     
201         final public CacheEntry parent;
202         public final ReadGraphImpl parentGraph;
203         final public QueryProcessor processor;
204         
205         public final AsyncBarrierImpl asyncBarrier;
206         
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);
209
210         final public static TObjectIntHashMap<String> counters = new TObjectIntHashMap<String>(); 
211         
212         public static void resetCounters() {
213                 counters.clear();
214         }
215         
216         public static String listCounters(File file) throws IOException {
217                 
218                 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
219
220                 for(Pair<String,Integer> p : CollectionUtils.valueSortedEntries(counters)) {
221                         b.print(-p.second + " " + p.first + "\n");
222                 }
223
224                 b.close();
225
226                 return "Dumped " + counters.size() + " queries.";
227                 
228         }
229         
230         /*
231          * Implementation of the interface ReadGraph
232          */
233         final public String getURI(final Resource resource)     throws AssumptionException, ValidationException, ServiceException {
234                 
235                 assert (resource != null);
236
237                 try {
238
239                         return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource));
240
241                 } catch (AssumptionException e) {
242
243                         throw new AssumptionException(e);
244
245                 } catch (ValidationException e) {
246
247                         throw new ValidationException(e);
248
249                 } catch (ServiceException e) {
250
251                         throw new ServiceException(e);
252
253                 } catch (DatabaseException e) {
254
255                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
256
257                 }
258
259         }
260         
261         final public String getPossibleURI(final Resource resource)     throws ValidationException,     ServiceException {
262
263                 assert (resource != null);
264
265                 try {
266
267                         return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource));
268
269                 } catch (ValidationException e) {
270
271                         throw new ValidationException(e);
272
273                 } catch (ServiceException e) {
274
275                         throw new ServiceException(e);
276
277                 } catch (DatabaseException e) {
278
279                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
280
281                 }
282
283         }
284
285         final public Resource getResource(final String id)
286                         throws ResourceNotFoundException, ValidationException,
287                         ServiceException {
288
289                 assert (id != null);
290
291                 try {
292
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);
297
298                 } catch (ResourceNotFoundException e) {
299
300                         throw new ResourceNotFoundException(id, e);
301
302                 } catch (ValidationException e) {
303
304                         throw new ValidationException(e);
305
306                 } catch (ServiceException e) {
307
308                         throw new ServiceException(e);
309
310                 } catch (DatabaseException e) {
311
312                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
313
314                 }
315
316         }
317
318         final public Resource getPossibleResource(final String id)
319         throws ResourceNotFoundException, ValidationException,
320         ServiceException {
321
322                 assert (id != null);
323
324                 try {
325
326                         return getResource(id);
327
328                 } catch (ResourceNotFoundException e) {
329                         
330                         return null;
331
332                 } catch (ValidationException e) {
333
334                         throw new ValidationException(e);
335
336                 } catch (ServiceException e) {
337
338                         throw new ServiceException(e);
339
340                 } catch (DatabaseException e) {
341
342                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
343
344                 }
345
346         }
347         
348         @Override
349         public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
350                 
351                 assert (resource != null);
352
353                 try {
354
355                         int rId = processor.querySupport.getId(resource);
356                         return QueryCache.resultChildMap(this, rId, parent, null);
357
358                 } catch (ValidationException e) {
359
360                         throw new ValidationException(e);
361
362                 } catch (ServiceException e) {
363
364                         throw new ServiceException(e);
365
366                 } catch (DatabaseException e) {
367
368                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
369
370                 }
371                 
372         }
373
374         final public Resource getRootLibrary() {
375                 return processor.getRootLibraryResource();
376         }
377         
378         final public Resource getBuiltin(final String id)
379                         throws ResourceNotFoundException, ServiceException {
380
381                 assert (id != null);
382
383                 try {
384
385                         return syncRequest(new Builtin(id));
386
387                 } catch (ResourceNotFoundException e) {
388
389                         throw new ResourceNotFoundException(id, e);
390
391                 } catch (ServiceException e) {
392
393                         throw new ServiceException(e);
394
395                 } catch (DatabaseException e) {
396
397                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
398
399                 }
400
401         }
402
403         static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure {
404
405                 private static Throwable DONE = new Throwable();
406                 
407                 Throwable exception = null;
408                 
409                 final ResourceSupport support;
410                 
411                 public StatementReadProcedure(ResourceSupport support) {
412                         this.support = support;
413                 }
414                 
415                 @Override
416                 public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) {
417                         add(s);
418                         add(p);
419                         add(o);
420                 }
421                 
422                 @Override
423                 public void finished(AsyncReadGraph graph) {
424                         exception = DONE;
425                 }
426
427                 @Override
428                 public void exception(AsyncReadGraph graph, Throwable t) {
429                         exception = t;
430                 }
431                 
432                 public void checkAndThrow() throws DatabaseException {
433                         if(exception != DONE) {
434                                 if (exception instanceof DatabaseException)
435                                         throw (DatabaseException) exception;
436                                 else
437                                         throw new DatabaseException(
438                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
439                                                         exception);
440                         }
441                 }
442                 
443                 public boolean done() {
444                         return exception != null;
445                 }
446
447                 @Override
448                 public boolean contains(Object obj) {
449                     if(!(obj instanceof InternalStatement))
450                         return false;
451                     InternalStatement statement = (InternalStatement)obj;
452                     int s = statement.s;
453                     int p = statement.p;
454                     int o = statement.o;
455                     for(int i=0;i<sizeInternal();i+=3)
456                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
457                     return true;
458                     return false;
459                 }
460
461                 @SuppressWarnings("unchecked")
462         @Override
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);
470                     }
471                     else {
472                         for(int i=length;i<a.length;++i)
473                             a[i] = null;
474                     }
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));
477             return a;
478                 }
479
480                 @Override
481                 public boolean add(Statement e) {
482                         throw new UnsupportedOperationException();
483                 }
484
485                 @Override
486                 public boolean remove(Object o) {
487                         throw new UnsupportedOperationException();
488                 }
489
490                 @Override
491                 public boolean addAll(Collection<? extends Statement> c) {
492                         throw new UnsupportedOperationException();
493                 }
494
495                 class IteratorImpl implements ListIterator<Statement> {
496             
497             int index;
498             
499             public IteratorImpl(int index) {
500                 this.index = index;
501             }
502
503             @Override
504             public boolean hasNext() {
505                 return index < sizeInternal(); 
506             }
507
508             @Override
509             public Statement next() {
510                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
511                 index += 3;
512                 return result;
513             }
514
515             @Override
516             public void remove() {
517                 throw new Error("Not supported");
518             }
519
520             @Override
521             public boolean hasPrevious() {
522                 return index > 0;
523             }
524
525             @Override
526             public Statement previous() {
527                 index -= 3;
528                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
529                 return result;
530             }
531
532             @Override
533             public int nextIndex() {
534                 return index/3;
535             }
536
537             @Override
538             public int previousIndex() {
539                 return index/3-1;
540             }
541
542             @Override
543             public void set(Statement e) {
544                 throw new UnsupportedOperationException();
545             }
546
547             @Override
548             public void add(Statement e) {
549                 throw new UnsupportedOperationException();
550             }
551             
552         };
553         
554                 @Override
555                 public Iterator<Statement> iterator() {
556                         return new IteratorImpl(0);
557                 }
558                 
559                 @Override
560                 public int size() {
561                         return sizeInternal() / 3;
562                 }
563
564                 @Override
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));
569                         return result;
570                 }
571
572         @Override
573         public boolean addAll(int index, Collection<? extends Statement> c) {
574             throw new UnsupportedOperationException();
575         }
576
577         @Override
578         public Statement get(int index) {
579             index += 3;
580             if(index < 0 || index >= sizeInternal())
581                 throw new IndexOutOfBoundsException();
582             return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
583         }
584
585         @Override
586         public Statement set(int index, Statement element) {
587             throw new UnsupportedOperationException();
588         }
589
590         @Override
591         public void add(int index, Statement element) {
592             throw new UnsupportedOperationException();
593         }
594
595         @Override
596         public Statement remove(int index) {
597             throw new UnsupportedOperationException();
598         }
599
600         @Override
601         public int indexOf(Object obj) {
602             if(!(obj instanceof InternalStatement))
603                 return -1;
604             InternalStatement statement = (InternalStatement)obj;
605             int s = statement.s;
606             int p = statement.p;
607             int o = statement.o;
608             for(int i=0;i<sizeInternal();i+=3)
609                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
610                     return i/3;
611             return -1;
612         }
613
614         @Override
615         public int lastIndexOf(Object obj) {
616             if(!(obj instanceof InternalStatement))
617                 return -1;
618             InternalStatement statement = (InternalStatement)obj;
619             int s = statement.s;
620             int p = statement.p;
621             int o = statement.o;
622             for(int i=sizeInternal()-3;i>=0;i-=3)
623                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
624                     return i/3;
625             return -1;
626         }
627
628         @Override
629         public ListIterator<Statement> listIterator() {
630             return new IteratorImpl(0);
631         }
632
633         @Override
634         public ListIterator<Statement> listIterator(int index) {
635             return new IteratorImpl(index*3);
636         }
637
638         @Override
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);
643         }
644         }
645         
646         @Override
647         final public Collection<Statement> getStatements(final Resource subject,
648                         final Resource relation)
649                         throws ManyObjectsForFunctionalRelationException, ServiceException {
650
651                 assert (subject != null);
652                 assert (relation != null);
653
654                 try {
655
656                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
657                         processor.forEachStatement(this, subject, relation, procedure);
658                         procedure.checkAndThrow();
659                         return procedure;
660                         
661                 } catch (DatabaseException e) {
662
663                         System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation);
664
665                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
666                         processor.forEachStatement(this, subject, relation, procedure);
667                         
668                         return Collections.emptyList();
669                 
670 //                      throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e);
671
672                 }
673
674         }
675
676         @Override
677         final public Collection<Statement> getAssertedStatements(final Resource subject, final Resource relation)
678                         throws ManyObjectsForFunctionalRelationException, ServiceException {
679
680                 assert (subject != null);
681                 assert (relation != null);
682
683                 try {
684
685                         return syncRequest(new ForEachAssertedStatement(subject, relation));
686
687                 } catch (ManyObjectsForFunctionalRelationException e) {
688
689                         throw new ManyObjectsForFunctionalRelationException(e);
690
691                 } catch (ServiceException e) {
692
693                         throw new ServiceException(e);
694
695                 } catch (DatabaseException e) {
696
697                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
698
699                 }
700
701         }
702
703         @Override
704         final public Collection<Resource> getPredicates(final Resource subject) throws ServiceException {
705
706                 assert (subject != null);
707
708                 try {
709
710                         return processor.getPredicates(this, subject);
711
712 //                      AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
713 //                      processor.forEachPredicate(this, subject, procedure);
714 //                      procedure.checkAndThrow();
715 //                      return procedure;
716
717                 } catch (ServiceException e) {
718
719                         throw new ServiceException(e);
720
721                 } catch (DatabaseException e) {
722
723                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
724
725                 }  catch (Throwable e) {
726
727             throw new ServiceException(e);
728
729                 }
730
731         }
732
733         @Override
734         final public Collection<Resource> getPrincipalTypes(final Resource subject)
735                         throws ServiceException {
736
737                 assert (subject != null);
738
739                 try {
740
741                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
742                         processor.forEachPrincipalType(this, subject, procedure);
743                         procedure.checkAndThrow();
744                         return procedure;
745                         
746                 } catch (ServiceException e) {
747
748                         throw new ServiceException(e);
749
750                 } catch (DatabaseException e) {
751
752                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
753
754                 }
755
756         }
757
758         @Override
759         final public Set<Resource> getTypes(final Resource subject) throws ServiceException {
760
761                 assert (subject != null);
762
763                 try {
764                         
765                         return processor.getTypes(this, subject);
766                         
767                 } catch (ServiceException e) {
768
769                         throw new ServiceException(e);
770                         
771                 } catch (DatabaseException e) {
772
773                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
774
775         } catch (Throwable e) {
776
777             throw new ServiceException(e);
778
779                 }
780
781         }
782
783         @Override
784         final public Set<Resource> getSupertypes(final Resource subject)
785                         throws ServiceException {
786
787                 assert (subject != null);
788
789                 try {
790
791                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
792                         processor.forSupertypes(this, subject, procedure);
793                         procedure.checkAndThrow();
794                         return procedure.result;
795
796                 } catch (ServiceException e) {
797
798                         throw new ServiceException(e);
799
800                 } catch (DatabaseException e) {
801
802                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
803
804                 }
805
806         }
807
808         @Override
809         final public Set<Resource> getSuperrelations(final Resource subject)
810                         throws ServiceException {
811
812                 assert (subject != null);
813
814                 try {
815
816                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
817                         processor.forSuperrelations(this, subject, procedure);
818                         procedure.checkAndThrow();
819                         return procedure.result;
820
821                 } catch (ServiceException e) {
822
823                         throw new ServiceException(e);
824
825                 } catch (DatabaseException e) {
826
827                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
828
829                 }
830
831         }
832         
833         @Override
834         public Resource getPossibleSuperrelation(Resource subject) throws ServiceException {
835                 
836                 try {
837
838                         SyncReadProcedure<Resource> procedure = new SyncReadProcedure<Resource>();
839                         processor.forPossibleSuperrelation(this, subject, procedure);
840                         procedure.checkAndThrow();
841                         return procedure.result;
842
843                 } catch (ServiceException e) {
844
845                         throw new ServiceException(e);
846
847                 } catch (DatabaseException e) {
848
849                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
850
851                 }
852
853         }
854
855         @Override
856         final public Collection<Resource> getObjects(final Resource subject, final Resource relation)
857                         throws ServiceException {
858
859                 assert (subject != null);
860                 assert (relation != null);
861
862                 if(Development.DEVELOPMENT) {
863             if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) {
864                 counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1);
865             }
866             //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace();
867                 }
868                 
869                 try {
870
871                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
872                         processor.forEachObject(this, subject, relation, procedure);
873                         procedure.checkAndThrow();
874                         return procedure;
875                         
876                 } catch (DatabaseException e) {
877
878                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
879
880                 }
881
882         }
883
884         @Override
885         final public Collection<Resource> getAssertedObjects(
886                         final Resource subject, final Resource relation)
887                         throws ManyObjectsForFunctionalRelationException, ServiceException {
888
889         if (subject == null)
890             throw new ArgumentException("Subject must not be null.");
891         if (relation == null)
892             throw new ArgumentException("Relation must not be null. Subject=" + subject);
893
894                 try {
895
896                         return syncRequest(new ForEachAssertedObject(subject, relation));
897
898                 } catch (ManyObjectsForFunctionalRelationException e) {
899
900                         throw new ManyObjectsForFunctionalRelationException(e);
901
902                 } catch (ServiceException e) {
903
904                         throw new ServiceException(e);
905
906                 } catch (DatabaseException e) {
907
908                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
909
910                 }
911
912         }
913
914         @Override
915         final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException {
916
917                 assert (relation != null);
918
919                 try {
920
921                         return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
922
923                 } catch (NoSingleResultException e) {
924
925                         throw new NoInverseException(e);
926
927                 } catch (ServiceException e) {
928
929                         throw new ServiceException(e);
930
931                 }
932
933         }
934
935         @Override
936         final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException {
937
938                 if( subject == null) throw new IllegalArgumentException("subject can not be null");
939                 if( relation == null) throw new IllegalArgumentException("relation can not be null");
940
941                 try {
942                         int single = processor.getSingleObject(this, subject, relation);
943                         if (single == 0) {
944                                 if (EMPTY_RESOURCE_CHECK) {
945                                         if (!hasStatement(subject)) {
946                                                 throw new EmptyResourceException("Resource " + debugString(subject));
947                                         }
948                                 }
949                                 throw new NoSingleResultException("No single object for subject " + debugString(subject)
950                                                 + " and relation " + debugString(relation), single);
951                         }
952                         return processor.querySupport.getResource(single);
953                 } catch (NoSingleResultException e) {
954                         throw e;
955                 } catch (DatabaseException e) {
956                         throw new ServiceException(e);
957                 } 
958         }
959
960         @Override
961         final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
962                 assert (subject != null);
963                 assert (relation != null);
964                 try {
965                         Collection<Statement> statements = getStatements(subject, relation);
966                         if (statements.size() == 1) {
967                                 return statements.iterator().next();
968                         } else {
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());
974                         }
975                 } catch (ServiceException e) {
976                         throw new ServiceException(e);
977                 } 
978         }
979
980         @Override
981         final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
982                 assert (subject != null);
983                 try {
984                         ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
985                         if (principalTypes.size() == 1) {
986                             return principalTypes.get(0);
987                         } else {
988                             throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
989                         }
990                 } catch (ServiceException e) {
991                         throw new ServiceException(e);
992                 } 
993         }
994
995         @Override
996         final public Resource getSingleType(final Resource subject,
997                         final Resource baseType) throws NoSingleResultException,
998                         ServiceException {
999
1000                 assert (subject != null);
1001                 assert (baseType != null);
1002
1003                 try {
1004                         return syncRequest(new SingleType(subject, baseType));
1005                 } catch (DatabaseException e) {
1006                     throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
1007                 }
1008         }
1009
1010         @Override
1011         final public <T> T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1012
1013                 assert (subject != null);
1014
1015                 try {
1016
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);
1020             
1021             if(processor.isImmutable(object)) {
1022                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1023                         return getValue(subject, binding);
1024             } else {
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);
1030             }
1031                         
1032         } catch (IOException e) {
1033
1034             throw new ServiceException(e);
1035
1036                 } catch (DoesNotContainValueException e) {
1037
1038                         throw new DoesNotContainValueException(e, subject);
1039
1040                 } catch (ServiceException e) {
1041
1042                         throw new ServiceException(e);
1043
1044                 } catch (DatabaseException e) {
1045
1046                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1047
1048         }
1049
1050         }
1051
1052     @Override
1053     final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1054
1055         assert (subject != null);
1056
1057         try {
1058
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);
1062             
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));
1066             } else {
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));
1072             }
1073             
1074         } catch (IOException e) {
1075
1076             throw new ServiceException(e);
1077
1078         } catch (DoesNotContainValueException e) {
1079
1080             throw new DoesNotContainValueException(e, subject);
1081
1082         } catch (ServiceException e) {
1083
1084             throw new ServiceException(e);
1085
1086         } catch (DatabaseException e) {
1087
1088             throw new ServiceException(INTERNAL_ERROR_STRING, e);
1089
1090         }               
1091         }
1092
1093         static final IdentityHashMap<Binding,Serializer> serializers = new IdentityHashMap<Binding,Serializer>();
1094         
1095         static {
1096                 serializers.put(Bindings.STRING, Bindings.STRING.serializer());
1097         }
1098         
1099         final protected Serializer getSerializer(Binding binding) {
1100             return binding.serializer();
1101         }
1102         
1103         @Override
1104         final public <T> T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException,
1105                         ServiceException {
1106
1107                 assert (subject != null);
1108
1109                 byte[] bytes = null;
1110                 try {
1111                         
1112                         bytes = processor.getValue(this, subject);
1113                         if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
1114
1115                         Serializer serializer = getSerializer(binding);
1116                         return (T)serializer.deserialize(bytes);
1117
1118                 } catch (DoesNotContainValueException e) {
1119
1120                         throw new DoesNotContainValueException(e);
1121
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);
1124                 }
1125         }
1126
1127         @Override
1128         final public <T> T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1129                         DoesNotContainValueException, ServiceException {
1130
1131                 assert (subject != null);
1132                 assert (relation != null);
1133
1134                 try {
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) {
1140                         try {
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);
1146                                         } else {
1147                                                 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1148                                         }
1149                                 } else {
1150                                         throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1151                                 }
1152                         } catch (DoesNotContainValueException e2) {
1153                                 throw e2;
1154                         } catch (DatabaseException e2) {
1155                                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1156                         }
1157                 } catch (ServiceException e) {
1158                         throw new ServiceException(e);
1159                 }
1160         }
1161
1162     @Override
1163     final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1164             DoesNotContainValueException, ServiceException {
1165
1166         assert (subject != null);
1167         assert (relation != null);
1168
1169         try {
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) {
1175             try {
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);
1181                     } else {
1182                         throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1183                     }
1184                 } else {
1185                     throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1186                 }
1187             } catch (DoesNotContainValueException e2) {
1188                 throw e2;
1189             } catch (DatabaseException e2) {
1190                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1191             }
1192         } catch (ServiceException e) {
1193             throw new ServiceException(e);
1194         } 
1195     }
1196     
1197         @Override
1198         final public <T> T getRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1199                         throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException {
1200
1201                 assert (subject != null);
1202                 assert (relation != null);
1203
1204                 try {
1205                         Resource object = getSingleObject(subject, relation);
1206                         return getValue(object, binding);
1207                 } catch (NoSingleResultException e) {
1208                     String message = "";
1209                     try {
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) {
1214                         
1215                     }
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);
1221                 }
1222         }
1223
1224         @Override
1225         final public <T> T adapt(final Resource resource, final Class<T> clazz)
1226                         throws AdaptionException, ValidationException, ServiceException {
1227
1228                 assert (resource != null);
1229                 assert (clazz != null);
1230
1231                 try {
1232
1233                         return syncRequest(new Adapter<T>(resource, clazz));
1234
1235                 } catch (AdaptionException e) {
1236
1237                         throw new AdaptionException(e);
1238
1239                 } catch (ValidationException e) {
1240
1241                         throw new ValidationException(e);
1242
1243                 } catch (ServiceException e) {
1244
1245                         throw new ServiceException(e);
1246
1247                 } catch (DatabaseException e) {
1248
1249                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1250
1251                 }
1252
1253         }
1254
1255         @Override
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 {
1258
1259                 assert (resource != null);
1260                 assert (context != null);
1261
1262                 class ContextualAdapter implements AsyncRead<T> {
1263
1264                         final private Resource resource;
1265                         final private C context;
1266                     final private Class<T> clazz;
1267                     
1268                     @Override
1269                     public int hashCode() {
1270                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1271                     }
1272                     
1273                     @Override
1274                     final public int threadHash() {
1275                         return resource.getThreadHash();
1276                     }
1277                     
1278                     @Override
1279                     public boolean equals(Object object) {
1280                         if (this == object)
1281                             return true;
1282                         else if (object == null)
1283                             return false;
1284                         else if (getClass() != object.getClass())
1285                             return false;
1286                         ContextualAdapter r = (ContextualAdapter)object;
1287                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1288                     }
1289
1290                     @Override
1291                     public int getFlags() {
1292                         return 0;
1293                     }
1294                     
1295                     public ContextualAdapter(Resource resource, C context, Class<T> clazz) {
1296                         this.resource = resource;
1297                         this.context = context;
1298                         this.clazz = clazz;
1299                     }
1300
1301                     @Override
1302                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1303                         
1304                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1305                                 if (service == null)
1306                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1307                                 else
1308                                         service.adapt(graph, resource, context, contextClass, clazz, false, procedure); 
1309                         
1310                     }
1311
1312                     @Override
1313                     public String toString() {
1314                         return "Adapter for (" + resource + "," + context + ") as " + clazz.getName();
1315                     }
1316                     
1317                 }
1318                 
1319                 try {
1320
1321                         return syncRequest(new ContextualAdapter(resource, context, clazz));
1322
1323                 } catch (AdaptionException e) {
1324
1325                         throw new AdaptionException(e);
1326
1327                 } catch (ValidationException e) {
1328
1329                         throw new ValidationException(e);
1330
1331                 } catch (ServiceException e) {
1332
1333                         throw new ServiceException(e);
1334
1335                 } catch (DatabaseException e) {
1336
1337                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1338
1339                 }
1340
1341         }
1342         
1343         @Override
1344         final public <T> T adaptRelated(final Resource resource, final Resource relation, final Class<T> clazz)
1345                         throws AdaptionException, NoSingleResultException, ValidationException, ServiceException {
1346
1347                 assert (resource != null);
1348                 assert (clazz != null);
1349
1350                 Statement stm = getSingleStatement(resource, relation);
1351                 
1352                 return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz);
1353                 
1354         }
1355
1356         @Override
1357         final public <T> T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class<T> clazz)
1358                         throws ValidationException, ServiceException {
1359
1360                 try {
1361                         return adaptRelated(resource, relation, clazz);
1362                 } catch (DatabaseException e) {
1363                         return null;
1364                 }
1365                 
1366         }
1367
1368         @Override
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 {
1371
1372                 assert (resource != null);
1373                 assert (context != null);
1374
1375                 class PossibleContextualAdapter implements AsyncRead<T> {
1376
1377                         final private Resource resource;
1378                         final private C context;
1379                     final private Class<T> clazz;
1380                     
1381                     @Override
1382                     public int hashCode() {
1383                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1384                     }
1385                     
1386                     @Override
1387                     final public int threadHash() {
1388                         return resource.getThreadHash();
1389                     }
1390                     
1391                     @Override
1392                     public boolean equals(Object object) {
1393                         if (this == object)
1394                             return true;
1395                         else if (object == null)
1396                             return false;
1397                         else if (getClass() != object.getClass())
1398                             return false;
1399                         PossibleContextualAdapter r = (PossibleContextualAdapter)object;
1400                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1401                     }
1402
1403                     @Override
1404                     public int getFlags() {
1405                         return 0;
1406                     }
1407                     
1408                     public PossibleContextualAdapter(Resource resource, C context, Class<T> clazz) {
1409                         this.resource = resource;
1410                         this.context = context;
1411                         this.clazz = clazz;
1412                     }
1413
1414                     @Override
1415                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1416                         
1417                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1418                                 if (service == null)
1419                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1420                                 else
1421                                         service.adapt(graph, resource, context, contextClass, clazz, true, procedure); 
1422                         
1423                     }
1424
1425                     @Override
1426                     public String toString() {
1427                         return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName();
1428                     }
1429                     
1430                 }
1431                 
1432                 try {
1433
1434                         return syncRequest(new PossibleContextualAdapter(resource, context, clazz));
1435
1436                 } catch (ValidationException e) {
1437
1438                         throw new ValidationException(e);
1439
1440                 } catch (ServiceException e) {
1441
1442                         throw new ServiceException(e);
1443
1444                 } catch (DatabaseException e) {
1445
1446                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1447
1448                 }
1449                 
1450         }
1451
1452         @Override
1453         final public <T> T adaptUnique(final Resource resource, final Class<T> clazz)
1454                         throws AdaptionException, ValidationException, ServiceException {
1455
1456                 assert (resource != null);
1457                 assert (clazz != null);
1458
1459                 try {
1460
1461                         return syncRequest(new UniqueAdapter<T>(resource, clazz));
1462
1463                 } catch (AdaptionException e) {
1464
1465                         throw new AdaptionException(e);
1466
1467                 } catch (ValidationException e) {
1468
1469                         throw new ValidationException(e);
1470
1471                 } catch (ServiceException e) {
1472
1473                         throw new ServiceException(e);
1474
1475                 } catch (DatabaseException e) {
1476
1477                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1478
1479                 }
1480
1481         }
1482
1483         @Override
1484         final public Resource getPossibleInverse(final Resource relation)
1485                         throws ServiceException {
1486
1487                 assert (relation != null);
1488
1489                 try {
1490
1491                         return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
1492
1493                 } catch (ServiceException e) {
1494
1495                         throw new ServiceException(e);
1496
1497                 } catch (DatabaseException e) {
1498
1499                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1500
1501                 }
1502
1503         }
1504
1505         @Override
1506         public Resource getPossibleObject(final Resource subject, final Resource relation)
1507                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1508
1509                 assert (subject != null);
1510                 assert (relation != null);
1511
1512                 try {
1513
1514                     int result = processor.getSingleObject(this, subject, relation);
1515                     if(result == 0) return null;
1516                     
1517                     return processor.querySupport.getResource(result);
1518
1519              } catch (ManyObjectsForFunctionalRelationException e) {
1520
1521                  throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
1522                  
1523                 } catch (DatabaseException e) {
1524
1525                         throw new ServiceException(e);
1526
1527                 }
1528                 
1529         }
1530
1531         @Override
1532         final public Statement getPossibleStatement(final Resource subject, final Resource relation)
1533                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1534
1535                 assert (subject != null);
1536                 assert (relation != null);
1537
1538                 try {
1539
1540                         Collection<Statement> statements = getStatements(subject, relation);
1541                         if(statements.size() == 1) return statements.iterator().next();
1542                         else return null;
1543
1544                 } catch (ManyObjectsForFunctionalRelationException e) {
1545
1546                         throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
1547
1548                 } catch (ServiceException e) {
1549
1550                         throw new ServiceException(e);
1551
1552                 } 
1553
1554         }
1555
1556         @Override
1557         final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException {
1558
1559                 assert (subject != null);
1560                 assert (baseType != null);
1561
1562                 try {
1563
1564                         AsyncReadProcedure<Resource> procedure = new AsyncReadProcedure<Resource>();
1565                         forPossibleType(subject, baseType, procedure);
1566                         procedure.checkAndThrow();
1567                         return procedure.result;                        
1568
1569                 } catch (ServiceException e) {
1570
1571                         throw new ServiceException(e);
1572
1573                 } catch (DatabaseException e) {
1574
1575                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1576
1577                 }
1578
1579         }
1580
1581         @Override
1582         final public <T> T getPossibleValue(final Resource subject) throws ServiceException {
1583
1584                 assert (subject != null);
1585
1586                 try {
1587                     
1588                     int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType);
1589                     if(object == 0) return null;
1590                     
1591             if(processor.isImmutable(object)) {
1592                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1593                         return getPossibleValue(subject, binding);
1594             } else {
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);
1600             }
1601                     
1602         } catch (IOException e) {
1603             
1604             throw new ServiceException(e);
1605             
1606                 } catch (ServiceException e) {
1607
1608                         throw new ServiceException(e);
1609
1610                 } catch (DatabaseException e) {
1611
1612                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1613
1614         }
1615
1616         }
1617
1618         @Override
1619         final public <T> T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException {
1620
1621                 assert (subject != null);
1622                 assert (binding != null);
1623
1624                 try {
1625
1626             byte[] dt = processor.getValue(this, subject);
1627             if(dt == null) return null;
1628                         Serializer serializer = getSerializer(binding);
1629             return (T)serializer.deserialize(dt);
1630
1631         } catch (IOException e) {
1632
1633             throw new ServiceException(e);
1634             
1635                 } catch (BindingException e) {
1636
1637                         throw new BindingException(e);
1638
1639                 } catch (ServiceException e) {
1640
1641                         throw new ServiceException(e);
1642
1643                 } catch (DatabaseException e) {
1644                         e.printStackTrace();
1645                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1646         }
1647
1648         }
1649
1650         @Override
1651         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation)
1652                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1653
1654                 assert (subject != null);
1655                 assert (relation != null);
1656
1657                 try {
1658
1659                         Resource object = getPossibleObject(subject, relation);
1660                         if(object == null) return null;
1661                         else return getPossibleValue(object);
1662
1663                 } catch (ManyObjectsForFunctionalRelationException e) {
1664
1665                         throw new ManyObjectsForFunctionalRelationException(e);
1666
1667                 } catch (ServiceException e) {
1668
1669                         throw new ServiceException(e);
1670
1671                 } 
1672
1673         }
1674
1675         @Override
1676         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1677                         throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
1678
1679                 assert (subject != null);
1680                 assert (relation != null);
1681                 assert (binding != null);
1682
1683                 try {
1684
1685                         Resource object = getPossibleObject(subject, relation);
1686                         if(object == null) return null;
1687                         else return getPossibleValue(object, binding);
1688
1689                 } catch (ManyObjectsForFunctionalRelationException e) {
1690
1691                         throw new ManyObjectsForFunctionalRelationException(e);
1692
1693                 } catch (BindingException e) {
1694
1695                         throw new BindingException(e);
1696
1697                 } catch (ServiceException e) {
1698
1699                         throw new ServiceException(e);
1700
1701                 }
1702
1703         }
1704
1705         @Override
1706         public <T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1707
1708                 assert (resource != null);
1709                 assert (clazz != null);
1710
1711                 try {
1712
1713                         return syncRequest(new PossibleAdapter<T>(resource, clazz));
1714
1715                 } catch (ValidationException e) {
1716
1717                         throw new ValidationException(e);
1718
1719                 } catch (AdaptionException e) {
1720
1721                         return null;
1722
1723                 } catch (DatabaseException e) {
1724
1725                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1726
1727                 }
1728         }
1729
1730         @Override
1731         public <T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1732
1733                 assert (resource != null);
1734                 assert (clazz != null);
1735
1736                 try {
1737
1738                         return syncRequest(new PossibleUniqueAdapter<T>(resource, clazz));
1739
1740                 } catch (AdaptionException e) {
1741
1742                         return null;
1743
1744                 } catch (ValidationException e) {
1745
1746                         throw new ValidationException(e);
1747
1748                 } catch (DatabaseException e) {
1749
1750                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1751
1752                 }
1753
1754         }
1755
1756     @Override
1757     final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException {
1758
1759         assert (resource != null);
1760         assert (type != null);
1761
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)
1765             return false;
1766         
1767         if(EMPTY_RESOURCE_CHECK) {
1768             if (resources.isEmpty()) {
1769                 if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource));
1770             }
1771         }
1772         
1773         return resources.contains(type);
1774
1775     }
1776
1777         @Override
1778         final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException {
1779
1780                 assert (resource != null);
1781                 assert (type != null);
1782
1783                 try {
1784
1785                         if(resource.equals(type)) return true;
1786                         
1787                         return getSupertypes(resource).contains(type);
1788
1789                 } catch (ServiceException e) {
1790
1791                         throw new ServiceException(e);
1792
1793                 } 
1794                 
1795         }
1796
1797         @Override
1798         final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException {
1799
1800                 assert (resource != null);
1801                 assert (type != null);
1802
1803                 try {
1804
1805                         if(resource.equals(type)) return true;
1806                         
1807                         return getSuperrelations(resource).contains(type);
1808
1809                 } catch (ServiceException e) {
1810
1811                         throw new ServiceException(e);
1812
1813                 } 
1814
1815         }
1816
1817         @Override
1818         final public boolean hasStatement(final Resource subject) throws ServiceException {
1819
1820                 assert (subject != null);
1821
1822                 try {
1823
1824                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1825                         processor.forHasStatement(this, subject, procedure);
1826                         procedure.checkAndThrow();
1827                         return procedure.result;
1828
1829                 } catch (ServiceException e) {
1830
1831                         throw new ServiceException(e);
1832
1833                 } catch (DatabaseException e) {
1834
1835                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1836
1837                 }
1838
1839         }
1840
1841         @Override
1842         final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException {
1843
1844                 assert (subject != null);
1845                 assert (relation != null);
1846
1847                 try {
1848
1849                         Collection<Resource> objects = getObjects(subject, relation);
1850                         return !objects.isEmpty();
1851
1852                 } catch (ServiceException e) {
1853
1854                         throw new ServiceException(e);
1855
1856                 } 
1857                 
1858         }
1859
1860         @Override
1861         final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1862
1863                 assert (subject != null);
1864                 assert (relation != null);
1865                 assert (object != null);
1866
1867                 try {
1868
1869                         for(Resource o : getObjects(subject, relation)) {
1870                                 if(object.equals(o)) return true;
1871                         }
1872                         
1873                         return false;
1874
1875                 } catch (ServiceException e) {
1876
1877                         throw new ServiceException(e);
1878
1879                 }
1880
1881         }
1882
1883         @Override
1884         final public boolean hasValue(final Resource subject) throws ServiceException {
1885
1886                 assert (subject != null);
1887
1888                 try {
1889
1890                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1891                         processor.forHasValue(this, subject, procedure);
1892                         procedure.checkAndThrow();
1893                         return procedure.result;
1894
1895                 } catch (ServiceException e) {
1896
1897                         throw new ServiceException(e);
1898
1899                 } catch (DatabaseException e) {
1900
1901                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1902
1903                 }
1904
1905         }
1906
1907         final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1908
1909                 @Override
1910                 public void execute(AsyncReadGraph graph, Object result) {
1911                 }
1912
1913                 @Override
1914                 public void exception(AsyncReadGraph graph, Throwable throwable) {
1915                 }
1916                 
1917         };
1918         
1919         /*
1920          * Implementation of the interface RequestProcessor
1921          */
1922
1923         @Override
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);
1927         }
1928
1929         @Override
1930         public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1931                         throws DatabaseException {
1932                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1933         }
1934
1935         @Override
1936         public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1937                         throws DatabaseException {
1938                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1939         }
1940
1941         @Override
1942         public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1943
1944                 assert (request != null);
1945
1946                 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1947
1948                 return QueryCache.resultReadEntry(this, request, parent, listener, procedure);
1949
1950         }
1951
1952         @Override
1953         public <T> T syncRequest(final Read<T> request,
1954                         final SyncProcedure<T> procedure) throws DatabaseException {
1955                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
1956         }
1957
1958         @Override
1959         public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
1960                         throws DatabaseException {
1961                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
1962         }
1963
1964         static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
1965
1966                 private static Throwable DONE = new Throwable();
1967                 
1968                 T result = null;
1969                 Throwable exception = null;
1970                 
1971                 @Override
1972                 public void execute(AsyncReadGraph graph, T t) {
1973                         result = t;
1974                         exception = DONE;
1975                 }
1976
1977                 @Override
1978                 public void exception(AsyncReadGraph graph, Throwable t) {
1979                         exception = t;
1980                 }
1981                 
1982                 public void checkAndThrow() throws DatabaseException {
1983                         if(exception != DONE) {
1984                                 if (exception instanceof DatabaseException)
1985                                         throw (DatabaseException) exception;
1986                                 else
1987                                         throw new DatabaseException(
1988                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
1989                                                         exception);
1990                         }
1991                 }
1992                 
1993                 public boolean done() {
1994                         return exception != null;
1995                 }
1996                 
1997         }
1998         
1999         @Override
2000         public <T> T syncRequest(final AsyncRead<T> request)
2001                         throws DatabaseException {
2002
2003                 assert (request != null);
2004                 return syncRequest(request, new AsyncProcedureAdapter<>() );
2005
2006         }
2007
2008         @Override
2009         public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2010                         throws DatabaseException {
2011                 return syncRequest(request, (AsyncProcedure<T>) procedure);
2012         }
2013
2014         @Override
2015         public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2016                         throws DatabaseException {
2017                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2018         }
2019
2020         @Override
2021         public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2022                         throws DatabaseException {
2023                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2024         }
2025
2026         @Override
2027         final public <T> T syncRequest(final AsyncRead<T> request,
2028                         final AsyncProcedure<T> procedure) throws DatabaseException {
2029
2030                 assert (request != null);
2031
2032                 ListenerBase listener = getListenerBase(procedure);
2033
2034 //              BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2035                 return (T)QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure, true);
2036 //              return ap.get();
2037
2038         }
2039
2040         @Override
2041         public <T> T syncRequest(AsyncRead<T> request,
2042                         final SyncProcedure<T> procedure) throws DatabaseException {
2043                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2044         }
2045
2046         @Override
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));
2050         }
2051
2052         @Override
2053         public <T> Collection<T> syncRequest(final MultiRead<T> request)
2054                         throws DatabaseException {
2055
2056                 assert (request != null);
2057
2058                 final ArrayList<T> result = new ArrayList<T>();
2059                 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2060
2061                 syncRequest(request, new SyncMultiProcedure<T>() {
2062
2063                         @Override
2064                         public void execute(ReadGraph graph, T t) {
2065                                 synchronized (result) {
2066                                         result.add(t);
2067                                 }
2068                         }
2069
2070                         @Override
2071                         public void finished(ReadGraph graph) {
2072                         }
2073
2074                         @Override
2075                         public void exception(ReadGraph graph, Throwable t) {
2076                                 exception.set(t);
2077                         }
2078
2079                         @Override
2080                         public String toString() {
2081                                 return "syncRequest(MultiRead) -> " + request;
2082                         }
2083
2084                 });
2085
2086                 Throwable t = exception.get();
2087                 if (t != null) {
2088                         if (t instanceof DatabaseException)
2089                                 throw (DatabaseException) t;
2090                         else
2091                                 throw new DatabaseException(
2092                                                 "Unexpected exception in ReadGraph.syncRequest(Read)",
2093                                                 t);
2094                 }
2095
2096                 return result;
2097
2098         }
2099
2100         @Override
2101         public <T> Collection<T> syncRequest(MultiRead<T> request,
2102                         SyncMultiListener<T> procedure) {
2103                 return syncRequest(request, (SyncMultiProcedure<T>)procedure);
2104         }
2105
2106         @Override
2107         public <T> Collection<T> syncRequest(MultiRead<T> request,
2108                         MultiListener<T> procedure) {
2109                 return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
2110         }
2111
2112         @Override
2113         public <T> Collection<T> syncRequest(MultiRead<T> request,
2114                         SyncMultiProcedure<T> procedure) {
2115
2116                 assert (request != null);
2117
2118                 ListenerBase listener = getListenerBase(procedure);
2119
2120                 final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
2121
2122                 if (parent != null || listener != null) {
2123
2124 //                      Object syncParent = request;
2125
2126 //                      final ReadGraphImpl newGraph = newSync();
2127
2128                         processor.query(this, request, parent, wrapper, listener);
2129
2130 //                      newGraph.waitAsync(syncParent);
2131
2132                 } else {
2133
2134 //                      Object syncParent = request;
2135
2136 //                      final ReadGraphImpl newGraph = newSync();
2137
2138                         try {
2139                                 request.perform(this, wrapper);
2140                         } catch (Throwable t) {
2141                                 wrapper.exception(this, t);
2142                         }
2143
2144                 }
2145
2146                 return wrapper.get();
2147
2148         }
2149
2150         @Override
2151         public <T> Collection<T> syncRequest(MultiRead<T> request,
2152                         MultiProcedure<T> procedure) {
2153                 return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
2154         }
2155
2156         static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2157
2158                 private static Throwable DONE = new Throwable();
2159                 
2160                 private static final long serialVersionUID = -6494230465108115812L;
2161                 
2162                 Throwable exception = null;
2163                 
2164                 @Override
2165                 public synchronized void execute(AsyncReadGraph graph, T t) {
2166                         add(t);
2167                 }
2168
2169                 @Override
2170                 public void finished(AsyncReadGraph graph) {
2171                         exception = DONE;
2172                 }
2173
2174                 @Override
2175                 public void exception(AsyncReadGraph graph, Throwable t) {
2176                         exception = t;
2177                 }
2178                 
2179                 public void checkAndThrow() throws DatabaseException {
2180                         if(exception != DONE) {
2181                                 if (exception instanceof DatabaseException)
2182                                         throw (DatabaseException) exception;
2183                                 else
2184                                         throw new DatabaseException(
2185                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2186                                                         exception);
2187                         }
2188                 }
2189                 
2190                 public boolean done() {
2191                         return exception != null;
2192                 }
2193                 
2194         }
2195
2196         @Override
2197         final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2198                         throws DatabaseException {
2199
2200                 assert (request != null);
2201
2202                 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2203                 
2204                 syncRequest(request, procedure);
2205                 
2206                 procedure.checkAndThrow();
2207                 return procedure;
2208
2209         }
2210
2211         @Override
2212         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2213                         AsyncMultiListener<T> procedure) {
2214                 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2215         }
2216
2217         @Override
2218         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2219                         SyncMultiListener<T> procedure) {
2220                 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2221         }
2222
2223         @Override
2224         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2225                         MultiListener<T> procedure) {
2226                 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2227         }
2228
2229         final private <T> void syncRequest(final AsyncMultiRead<T> request,
2230                         final AsyncMultiReadProcedure<T> procedure) {
2231
2232                 assert (request != null);
2233                 assert (procedure != null);
2234
2235                 ListenerBase listener = getListenerBase(procedure);
2236
2237                 if (parent != null || listener != null) {
2238
2239 //                      Object syncParent = request;
2240
2241 //                      final ReadGraphImpl newGraph = newSync();
2242
2243                         processor.query(this, request, parent, procedure, listener);
2244
2245 //                      newGraph.waitAsync(syncParent);
2246                         waitAsyncProcedure(procedure);
2247
2248                 } else {
2249
2250 //                      Object syncParent = callerThread == Integer.MIN_VALUE ? null
2251 //                                      : request;
2252 //
2253 //                      final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2254
2255                         try {
2256
2257 //                              inc();
2258 //                              ReadGraphImpl sync = newSync();
2259                                 request.perform(this, procedure);
2260 //                              sync.waitAsync(null);
2261                                 waitAsyncProcedure(procedure);
2262 //                              dec();
2263
2264                         } catch (Throwable t) {
2265
2266                                 waitAsyncProcedure(procedure);
2267 //                              dec();
2268
2269                         }
2270
2271                 }
2272
2273         }
2274         
2275         
2276         @Override
2277         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2278                         final AsyncMultiProcedure<T> procedure) {
2279
2280                 assert (request != null);
2281                 assert (procedure != null);
2282
2283                 ListenerBase listener = getListenerBase(procedure);
2284
2285                 if (parent != null || listener != null) {
2286
2287 //                      Object syncParent = request;
2288
2289 //                      final ReadGraphImpl newGraph = newSync();
2290
2291                         processor.query(this, request, parent, procedure, listener);
2292
2293 //                      newGraph.waitAsync(syncParent);
2294
2295                 } else {
2296
2297 //                      Object syncParent = request;
2298
2299 //                      final ReadGraphImpl newGraph = newSync();
2300
2301                         try {
2302
2303                                 request.perform(this, new AsyncMultiProcedure<T>() {
2304
2305                                         @Override
2306                                         public void execute(AsyncReadGraph graph, T result) {
2307                                                 procedure.execute(graph, result);
2308                                         }
2309
2310                                         @Override
2311                                         public void finished(AsyncReadGraph graph) {
2312                                                 procedure.finished(graph);
2313                                         }
2314
2315                                         @Override
2316                                         public void exception(AsyncReadGraph graph, Throwable t) {
2317                                                 procedure.exception(graph, t);
2318                                         }
2319
2320                                         @Override
2321                                         public String toString() {
2322                                                 return "syncRequest(AsyncMultiRead) -> " + procedure;
2323                                         }
2324
2325                                 });
2326
2327                         } catch (Throwable t) {
2328
2329                         }
2330
2331                 }
2332
2333                 // TODO!!
2334                 return null;
2335
2336         }
2337
2338         @Override
2339         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2340                         final SyncMultiProcedure<T> procedure) {
2341                 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2342         }
2343
2344         @Override
2345         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2346                         final MultiProcedure<T> procedure) {
2347                 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2348         }
2349
2350         @Override
2351         public <T> T syncRequest(final ExternalRead<T> request)
2352                         throws DatabaseException {
2353
2354                 assert (request != null);
2355
2356                 return syncRequest(request, new Procedure<T>() {
2357
2358                         @Override
2359                         public void execute(T t) {
2360                         }
2361
2362                         @Override
2363                         public void exception(Throwable t) {
2364                         }
2365
2366                         @Override
2367                         public String toString() {
2368                                 return "syncRequest(AsyncRead) -> " + request;
2369                         }
2370
2371                 });
2372
2373         }
2374
2375         @Override
2376         public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2377                 return syncRequest(request, (Procedure<T>) procedure);
2378         }
2379
2380         @Override
2381         final public <T> T syncRequest(final ExternalRead<T> request,
2382                         final Procedure<T> procedure) throws DatabaseException {
2383
2384         assert (request != null);
2385
2386         ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
2387         return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
2388
2389         }
2390
2391         @Override
2392         public void syncRequest(final Write request) throws DatabaseException {
2393
2394                 assert (request != null);
2395
2396                 throw new DatabaseException(
2397                                 "Write operations are not supported during read transactions!");
2398
2399         }
2400
2401         @Override
2402         public <T> T syncRequest(final WriteResult<T> request) throws DatabaseException {
2403
2404                 assert (request != null);
2405
2406                 throw new DatabaseException(
2407                                 "Write operations are not supported during read transactions!");
2408
2409         }
2410
2411         @Override
2412         public void syncRequest(final DelayedWrite request)
2413                         throws DatabaseException {
2414
2415                 assert (request != null);
2416
2417                 throw new DatabaseException(
2418                                 "Write operations are not supported during read transactions!");
2419
2420         }
2421
2422         @Override
2423         public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {
2424
2425                 assert (request != null);
2426
2427                 throw new DatabaseException(
2428                                 "Write operations are not supported during read transactions!");
2429
2430         }
2431         
2432         @Override
2433         public void syncRequest(final WriteOnly request) throws DatabaseException {
2434
2435                 assert (request != null);
2436
2437                 throw new DatabaseException(
2438                                 "Write operations are not supported during read transactions!");
2439
2440         }
2441
2442         @Override
2443         public <T> T syncRequest(final WriteOnlyResult<T> request) throws DatabaseException {
2444
2445                 assert (request != null);
2446
2447                 throw new DatabaseException(
2448                                 "Write operations are not supported during read transactions!");
2449
2450         }
2451         
2452         @Override
2453         public <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure) {
2454                 r.request(this, procedure);
2455         }
2456         
2457         @Override
2458         public <T> void async(ReadInterface<T> r, Procedure<T> procedure) {
2459                 r.request(this, procedure);
2460         }
2461         
2462         @Override
2463         public <T> void async(ReadInterface<T> r, SyncProcedure<T> procedure) {
2464                 r.request(this, procedure);
2465         }
2466         
2467         @Override
2468         public <T> void async(ReadInterface<T> r, AsyncListener<T> procedure) {
2469                 r.request(this, procedure);
2470         }
2471         
2472         @Override
2473         public <T> void async(ReadInterface<T> r, Listener<T> procedure) {
2474                 r.request(this, procedure);
2475         }
2476         
2477         @Override
2478         public <T> void async(ReadInterface<T> r, SyncListener<T> procedure) {
2479                 r.request(this, procedure);
2480         }
2481
2482         @Override
2483         public <T> T sync(ReadInterface<T> r) throws DatabaseException {
2484                 return r.request(this);
2485         }
2486         
2487         @Override
2488         public <T> T sync(WriteInterface<T> r) throws DatabaseException {
2489                 return r.request(this);
2490         }
2491         
2492         @Override
2493         public <T> void async(WriteInterface<T> r, Procedure<T> procedure) {
2494                 r.request(this, procedure);
2495         }
2496
2497         @Override
2498         public <T> void async(WriteInterface<T> r) {
2499                 r.request(this, new ProcedureAdapter<T>());
2500         }
2501
2502         /*
2503          * Implementation of the interface AsyncReadGraph
2504          */
2505
2506         @Override
2507         public void forURI(Resource resource, AsyncListener<String> listener) {
2508                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2509                                 listener);
2510         }
2511
2512         @Override
2513         public void forURI(Resource resource, SyncListener<String> listener) {
2514                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2515                                 listener);
2516         }
2517
2518         @Override
2519         public void forURI(Resource resource, Listener<String> listener) {
2520                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2521                                 listener);
2522         }
2523
2524         @Override
2525         final public void forURI(final Resource resource,
2526                         final AsyncProcedure<String> procedure) {
2527
2528                 assert (resource != null);
2529                 assert (procedure != null);
2530
2531                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2532                                 procedure);
2533
2534         }
2535
2536         @Override
2537         public void forURI(Resource resource, SyncProcedure<String> procedure) {
2538                 forURI(resource, new SyncToAsyncProcedure<String>(procedure));
2539         }
2540
2541         @Override
2542         public void forURI(Resource resource, Procedure<String> procedure) {
2543                 forURI(resource, new NoneToAsyncProcedure<String>(procedure));
2544         }
2545         
2546         @Override
2547         public void forResource(String id, AsyncListener<Resource> listener) {
2548                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2549                                 listener);
2550         }
2551
2552         @Override
2553         public void forResource(String id, SyncListener<Resource> listener) {
2554                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2555                                 listener);
2556         }
2557
2558         @Override
2559         public void forResource(String id, Listener<Resource> listener) {
2560                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2561                                 listener);
2562         }
2563
2564         @Override
2565         final public void forResource(final String id,
2566                         final AsyncProcedure<Resource> procedure) {
2567
2568                 assert (id != null);
2569                 assert (procedure != null);
2570
2571                 processor.forResource(this, id, procedure);
2572
2573         }
2574
2575         @Override
2576         public void forResource(String id, SyncProcedure<Resource> procedure) {
2577                 forResource(id, new SyncToAsyncProcedure<Resource>(procedure));
2578         }
2579
2580         @Override
2581         public void forResource(String id, Procedure<Resource> procedure) {
2582                 forResource(id, new NoneToAsyncProcedure<Resource>(procedure));
2583         }
2584
2585         @Override
2586         public void forBuiltin(String id, AsyncListener<Resource> listener) {
2587                 asyncRequest(new Builtin(id), listener);
2588         }
2589
2590         @Override
2591         public void forBuiltin(String id, SyncListener<Resource> listener) {
2592                 asyncRequest(new Builtin(id), listener);
2593         }
2594
2595         @Override
2596         public void forBuiltin(String id, Listener<Resource> listener) {
2597                 asyncRequest(new Builtin(id), listener);
2598         }
2599
2600         @Override
2601         final public void forBuiltin(final String id,
2602                         final AsyncProcedure<Resource> procedure) {
2603
2604                 assert (id != null);
2605                 assert (procedure != null);
2606
2607                 processor.forBuiltin(this, id, procedure);
2608
2609         }
2610
2611         @Override
2612         public void forBuiltin(String id, SyncProcedure<Resource> procedure) {
2613                 forBuiltin(id, new SyncToAsyncProcedure<Resource>(procedure));
2614         }
2615
2616         @Override
2617         public void forBuiltin(String id, Procedure<Resource> procedure) {
2618                 forBuiltin(id, new NoneToAsyncProcedure<Resource>(procedure));
2619         }
2620
2621         @Override
2622         final public void forEachStatement(Resource subject, Resource relation,
2623                         AsyncMultiProcedure<Statement> procedure) {
2624
2625                 assert (subject != null);
2626                 assert (relation != null);
2627                 assert (procedure != null);
2628
2629                 processor.forEachStatement(this, subject, relation, procedure);
2630
2631         }
2632
2633         @Override
2634         public void forEachStatement(Resource subject, Resource relation,
2635                         SyncMultiProcedure<Statement> procedure) {
2636                 forEachStatement(subject, relation,
2637                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2638         }
2639
2640         @Override
2641         final public void forEachStatement(Resource subject, Resource relation,
2642                         MultiProcedure<Statement> procedure) {
2643
2644                 assert (subject != null);
2645                 assert (relation != null);
2646                 assert (procedure != null);
2647
2648                 processor.forEachStatement(this, subject, relation, procedure);
2649
2650         }
2651
2652         @Override
2653         final public void forStatementSet(Resource subject, Resource relation,
2654                         AsyncSetListener<Statement> procedure) {
2655
2656                 assert (subject != null);
2657                 assert (relation != null);
2658                 assert (procedure != null);
2659
2660                 processor.forStatementSet(this, subject, relation, procedure);
2661
2662         }
2663
2664         @Override
2665         final public void forStatementSet(Resource subject, Resource relation,
2666                         SyncSetListener<Statement> procedure) {
2667                 forStatementSet(subject, relation,
2668                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2669         }
2670
2671         @Override
2672         public void forStatementSet(Resource subject, Resource relation,
2673                         SetListener<Statement> listener) {
2674                 forStatementSet(subject, relation,
2675                                 new NoneToAsyncSetProcedure<Statement>(listener));
2676         }
2677
2678         @Override
2679         final public void forEachAssertedStatement(final Resource subject,
2680                         final Resource relation,
2681                         final AsyncMultiProcedure<Statement> procedure) {
2682