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