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