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