]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
Merge "Move debugging options under DevelopmentKeys"
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / graph / ReadGraphImpl.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.graph;
13
14 import java.io.BufferedOutputStream;
15 import java.io.File;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.io.PrintStream;
19 import java.lang.reflect.Array;
20 import java.lang.reflect.InvocationTargetException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.IdentityHashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.function.Consumer;
32
33 import org.eclipse.core.runtime.Platform;
34 import org.simantics.databoard.Accessors;
35 import org.simantics.databoard.Bindings;
36 import org.simantics.databoard.accessor.Accessor;
37 import org.simantics.databoard.accessor.error.AccessorConstructionException;
38 import org.simantics.databoard.adapter.AdaptException;
39 import org.simantics.databoard.binding.Binding;
40 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;
41 import org.simantics.databoard.binding.impl.ObjectVariantBinding;
42 import org.simantics.databoard.binding.mutable.Variant;
43 import org.simantics.databoard.serialization.Serializer;
44 import org.simantics.databoard.type.Datatype;
45 import org.simantics.databoard.util.binary.BinaryFile;
46 import org.simantics.databoard.util.binary.RandomAccessBinary;
47 import org.simantics.db.AsyncReadGraph;
48 import org.simantics.db.ComputationalValue;
49 import org.simantics.db.DevelopmentKeys;
50 import org.simantics.db.ExternalValueSupport;
51 import org.simantics.db.ReadGraph;
52 import org.simantics.db.RelationContext;
53 import org.simantics.db.Resource;
54 import org.simantics.db.Session;
55 import org.simantics.db.Statement;
56 import org.simantics.db.adaption.AdaptionService;
57 import org.simantics.db.common.primitiverequest.Adapter;
58 import org.simantics.db.common.primitiverequest.Builtin;
59 import org.simantics.db.common.primitiverequest.DatatypeBinding;
60 import org.simantics.db.common.primitiverequest.ForEachAssertedObject;
61 import org.simantics.db.common.primitiverequest.ForEachAssertedStatement;
62 import org.simantics.db.common.primitiverequest.HasStatement;
63 import org.simantics.db.common.primitiverequest.HasStatementSubject;
64 import org.simantics.db.common.primitiverequest.HasStatementSubjectObject;
65 import org.simantics.db.common.primitiverequest.HasValue;
66 import org.simantics.db.common.primitiverequest.Inverse;
67 import org.simantics.db.common.primitiverequest.IsInheritedFrom;
68 import org.simantics.db.common.primitiverequest.IsInstanceOf;
69 import org.simantics.db.common.primitiverequest.IsSubrelationOf;
70 import org.simantics.db.common.primitiverequest.OrderedSet;
71 import org.simantics.db.common.primitiverequest.PossibleAdapter;
72 import org.simantics.db.common.primitiverequest.PossibleInverse;
73 import org.simantics.db.common.primitiverequest.PossibleObject;
74 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
75 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied;
76 import org.simantics.db.common.primitiverequest.PossibleStatement;
77 import org.simantics.db.common.primitiverequest.PossibleType;
78 import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter;
79 import org.simantics.db.common.primitiverequest.PossibleValue;
80 import org.simantics.db.common.primitiverequest.PossibleValueImplied;
81 import org.simantics.db.common.primitiverequest.RelatedValue;
82 import org.simantics.db.common.primitiverequest.RelatedValueImplied;
83 import org.simantics.db.common.primitiverequest.SingleObject;
84 import org.simantics.db.common.primitiverequest.SingleStatement;
85 import org.simantics.db.common.primitiverequest.SingleType;
86 import org.simantics.db.common.primitiverequest.SingleTypeAny;
87 import org.simantics.db.common.primitiverequest.Types;
88 import org.simantics.db.common.primitiverequest.UniqueAdapter;
89 import org.simantics.db.common.primitiverequest.Value;
90 import org.simantics.db.common.primitiverequest.ValueImplied;
91 import org.simantics.db.common.primitiverequest.VariantValueImplied;
92 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
93 import org.simantics.db.common.procedure.adapter.AsyncProcedureAdapter;
94 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
95 import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
96 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
97 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
98 import org.simantics.db.common.procedure.single.SyncReadProcedure;
99 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrErrorProcedure;
100 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure;
101 import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure;
102 import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure;
103 import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure;
104 import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure;
105 import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure;
106 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
107 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
108 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
109 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
110 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
111 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
112 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
113 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
114 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
115 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
116 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
117 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
118 import org.simantics.db.common.request.AdaptValue;
119 import org.simantics.db.common.request.ResourceRead;
120 import org.simantics.db.common.utils.Logger;
121 import org.simantics.db.common.utils.NameUtils;
122 import org.simantics.db.common.validation.L0Validations;
123 import org.simantics.db.exception.AdaptionException;
124 import org.simantics.db.exception.ArgumentException;
125 import org.simantics.db.exception.AssumptionException;
126 import org.simantics.db.exception.BindingException;
127 import org.simantics.db.exception.DatabaseException;
128 import org.simantics.db.exception.DoesNotContainValueException;
129 import org.simantics.db.exception.EmptyResourceException;
130 import org.simantics.db.exception.InternalException;
131 import org.simantics.db.exception.InvalidLiteralException;
132 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
133 import org.simantics.db.exception.NoInverseException;
134 import org.simantics.db.exception.NoSingleResultException;
135 import org.simantics.db.exception.ResourceNotFoundException;
136 import org.simantics.db.exception.ServiceException;
137 import org.simantics.db.exception.ValidationException;
138 import org.simantics.db.impl.RelationContextImpl;
139 import org.simantics.db.impl.ResourceImpl;
140 import org.simantics.db.impl.internal.RandomAccessValueSupport;
141 import org.simantics.db.impl.internal.ResourceData;
142 import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
143 import org.simantics.db.impl.query.CacheEntry;
144 import org.simantics.db.impl.query.QueryCache;
145 import org.simantics.db.impl.query.QueryCacheBase;
146 import org.simantics.db.impl.query.QueryProcessor;
147 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
148 import org.simantics.db.impl.query.QuerySupport;
149 import org.simantics.db.impl.query.TripleIntProcedure;
150 import org.simantics.db.impl.support.ResourceSupport;
151 import org.simantics.db.procedure.AsyncListener;
152 import org.simantics.db.procedure.AsyncMultiListener;
153 import org.simantics.db.procedure.AsyncMultiProcedure;
154 import org.simantics.db.procedure.AsyncProcedure;
155 import org.simantics.db.procedure.AsyncSetListener;
156 import org.simantics.db.procedure.Listener;
157 import org.simantics.db.procedure.ListenerBase;
158 import org.simantics.db.procedure.MultiListener;
159 import org.simantics.db.procedure.MultiProcedure;
160 import org.simantics.db.procedure.Procedure;
161 import org.simantics.db.procedure.SetListener;
162 import org.simantics.db.procedure.StatementProcedure;
163 import org.simantics.db.procedure.SyncListener;
164 import org.simantics.db.procedure.SyncMultiListener;
165 import org.simantics.db.procedure.SyncMultiProcedure;
166 import org.simantics.db.procedure.SyncProcedure;
167 import org.simantics.db.procedure.SyncSetListener;
168 import org.simantics.db.request.AsyncMultiRead;
169 import org.simantics.db.request.AsyncRead;
170 import org.simantics.db.request.DelayedWrite;
171 import org.simantics.db.request.DelayedWriteResult;
172 import org.simantics.db.request.ExternalRead;
173 import org.simantics.db.request.MultiRead;
174 import org.simantics.db.request.Read;
175 import org.simantics.db.request.ReadInterface;
176 import org.simantics.db.request.Write;
177 import org.simantics.db.request.WriteInterface;
178 import org.simantics.db.request.WriteOnly;
179 import org.simantics.db.request.WriteOnlyResult;
180 import org.simantics.db.request.WriteResult;
181 import org.simantics.layer0.Layer0;
182 import org.simantics.scl.compiler.types.Type;
183 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
184 import org.simantics.scl.reflection.ReflectionUtils;
185 import org.simantics.scl.reflection.ValueNotFoundException;
186 import org.simantics.scl.runtime.function.Function3;
187 import org.simantics.utils.DataContainer;
188 import org.simantics.utils.Development;
189 import org.simantics.utils.datastructures.Pair;
190 import org.simantics.utils.datastructures.collections.CollectionUtils;
191 import org.slf4j.LoggerFactory;
192
193 import gnu.trove.map.hash.TObjectIntHashMap;
194
195 public class ReadGraphImpl implements AsyncReadGraph {
196
197     private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
198
199     final static boolean EMPTY_RESOURCE_CHECK = false;
200     
201         final public CacheEntry parent;
202         public final ReadGraphImpl parentGraph;
203         final public QueryProcessor processor;
204         
205         public final AsyncBarrierImpl asyncBarrier;
206         
207         final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
208         final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
209
210         final public static TObjectIntHashMap<String> counters = new TObjectIntHashMap<String>(); 
211         
212         public static void resetCounters() {
213                 counters.clear();
214         }
215         
216         public static String listCounters(File file) throws IOException {
217                 
218                 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
219
220                 for(Pair<String,Integer> p : CollectionUtils.valueSortedEntries(counters)) {
221                         b.print(-p.second + " " + p.first + "\n");
222                 }
223
224                 b.close();
225
226                 return "Dumped " + counters.size() + " queries.";
227                 
228         }
229         
230         /*
231          * Implementation of the interface ReadGraph
232          */
233         final public String getURI(final Resource resource)     throws AssumptionException, ValidationException, ServiceException {
234                 
235                 assert (resource != null);
236
237                 try {
238
239                         return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource));
240
241                 } catch (AssumptionException e) {
242
243                         throw new AssumptionException(e);
244
245                 } catch (ValidationException e) {
246
247                         throw new ValidationException(e);
248
249                 } catch (ServiceException e) {
250
251                         throw new ServiceException(e);
252
253                 } catch (DatabaseException e) {
254
255                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
256
257                 }
258
259         }
260         
261         final public String getPossibleURI(final Resource resource)     throws ValidationException,     ServiceException {
262
263                 assert (resource != null);
264
265                 try {
266
267                         return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource));
268
269                 } catch (ValidationException e) {
270
271                         throw new ValidationException(e);
272
273                 } catch (ServiceException e) {
274
275                         throw new ServiceException(e);
276
277                 } catch (DatabaseException e) {
278
279                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
280
281                 }
282
283         }
284
285         final public Resource getResource(final String id)
286                         throws ResourceNotFoundException, ValidationException,
287                         ServiceException {
288
289                 assert (id != null);
290
291                 try {
292
293                         Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
294                         // FIXME: stupid to throw this here and catch and wrap it right away
295                         if(rid == 0) throw new ResourceNotFoundException(id);
296                         return processor.querySupport.getResource(rid);
297
298                 } catch (ResourceNotFoundException e) {
299
300                         throw new ResourceNotFoundException(id, e);
301
302                 } catch (ValidationException e) {
303
304                         throw new ValidationException(e);
305
306                 } catch (ServiceException e) {
307
308                         throw new ServiceException(e);
309
310                 } catch (DatabaseException e) {
311
312                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
313
314                 }
315
316         }
317
318         final public Resource getPossibleResource(final String id)
319         throws ResourceNotFoundException, ValidationException,
320         ServiceException {
321
322                 assert (id != null);
323
324                 try {
325
326                         return getResource(id);
327
328                 } catch (ResourceNotFoundException e) {
329                         
330                         return null;
331
332                 } catch (ValidationException e) {
333
334                         throw new ValidationException(e);
335
336                 } catch (ServiceException e) {
337
338                         throw new ServiceException(e);
339
340                 } catch (DatabaseException e) {
341
342                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
343
344                 }
345
346         }
347         
348         @Override
349         public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
350                 
351                 assert (resource != null);
352
353                 try {
354
355                         int rId = processor.querySupport.getId(resource);
356                         return QueryCache.resultChildMap(this, rId, parent, null);
357
358                 } catch (ValidationException e) {
359
360                         throw new ValidationException(e);
361
362                 } catch (ServiceException e) {
363
364                         throw new ServiceException(e);
365
366                 } catch (DatabaseException e) {
367
368                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
369
370                 }
371                 
372         }
373
374         final public Resource getRootLibrary() {
375                 return processor.getRootLibraryResource();
376         }
377         
378         final public Resource getBuiltin(final String id)
379                         throws ResourceNotFoundException, ServiceException {
380
381                 assert (id != null);
382
383                 try {
384
385                         return syncRequest(new Builtin(id));
386
387                 } catch (ResourceNotFoundException e) {
388
389                         throw new ResourceNotFoundException(id, e);
390
391                 } catch (ServiceException e) {
392
393                         throw new ServiceException(e);
394
395                 } catch (DatabaseException e) {
396
397                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
398
399                 }
400
401         }
402
403         static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure {
404
405                 private static Throwable DONE = new Throwable();
406                 
407                 Throwable exception = null;
408                 
409                 final ResourceSupport support;
410                 
411                 public StatementReadProcedure(ResourceSupport support) {
412                         this.support = support;
413                 }
414                 
415                 @Override
416                 public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) {
417                         add(s);
418                         add(p);
419                         add(o);
420                 }
421                 
422                 @Override
423                 public void finished(AsyncReadGraph graph) {
424                         exception = DONE;
425                 }
426
427                 @Override
428                 public void exception(AsyncReadGraph graph, Throwable t) {
429                         exception = t;
430                 }
431                 
432                 public void checkAndThrow() throws DatabaseException {
433                         if(exception != DONE) {
434                                 if (exception instanceof DatabaseException)
435                                         throw (DatabaseException) exception;
436                                 else
437                                         throw new DatabaseException(
438                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
439                                                         exception);
440                         }
441                 }
442                 
443                 public boolean done() {
444                         return exception != null;
445                 }
446
447                 @Override
448                 public boolean contains(Object obj) {
449                     if(!(obj instanceof InternalStatement))
450                         return false;
451                     InternalStatement statement = (InternalStatement)obj;
452                     int s = statement.s;
453                     int p = statement.p;
454                     int o = statement.o;
455                     for(int i=0;i<sizeInternal();i+=3)
456                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
457                     return true;
458                     return false;
459                 }
460
461                 @SuppressWarnings("unchecked")
462         @Override
463                 public <T> T[] toArray(T[] a) {
464                     int length = sizeInternal() / 3;
465                     if(length > a.length) {
466                         Class<?> arrayType = a.getClass();
467                         a = (arrayType == Object[].class) 
468                                 ? (T[]) new Object[length]
469                                 : (T[]) Array.newInstance(arrayType.getComponentType(), length);
470                     }
471                     else {
472                         for(int i=length;i<a.length;++i)
473                             a[i] = null;
474                     }
475             for(int i=0,j=0;i<sizeInternal();i+=3,++j)
476                 a[j] = (T)new InternalStatement(support, getQuick(i), getQuick(i+1), getQuick(i+2));
477             return a;
478                 }
479
480                 @Override
481                 public boolean add(Statement e) {
482                         throw new UnsupportedOperationException();
483                 }
484
485                 @Override
486                 public boolean remove(Object o) {
487                         throw new UnsupportedOperationException();
488                 }
489
490                 @Override
491                 public boolean addAll(Collection<? extends Statement> c) {
492                         throw new UnsupportedOperationException();
493                 }
494
495                 class IteratorImpl implements ListIterator<Statement> {
496             
497             int index;
498             
499             public IteratorImpl(int index) {
500                 this.index = index;
501             }
502
503             @Override
504             public boolean hasNext() {
505                 return index < sizeInternal(); 
506             }
507
508             @Override
509             public Statement next() {
510                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
511                 index += 3;
512                 return result;
513             }
514
515             @Override
516             public void remove() {
517                 throw new Error("Not supported");
518             }
519
520             @Override
521             public boolean hasPrevious() {
522                 return index > 0;
523             }
524
525             @Override
526             public Statement previous() {
527                 index -= 3;
528                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
529                 return result;
530             }
531
532             @Override
533             public int nextIndex() {
534                 return index/3;
535             }
536
537             @Override
538             public int previousIndex() {
539                 return index/3-1;
540             }
541
542             @Override
543             public void set(Statement e) {
544                 throw new UnsupportedOperationException();
545             }
546
547             @Override
548             public void add(Statement e) {
549                 throw new UnsupportedOperationException();
550             }
551             
552         };
553         
554                 @Override
555                 public Iterator<Statement> iterator() {
556                         return new IteratorImpl(0);
557                 }
558                 
559                 @Override
560                 public int size() {
561                         return sizeInternal() / 3;
562                 }
563
564                 @Override
565                 public Object[] toArray() {
566                     Object[] result = new Object[sizeInternal() / 3];
567                     for(int i=0,j=0;j<sizeInternal();i++,j+=3)
568                         result[i] = new InternalStatement(support, getQuick(j), getQuick(j+1), getQuick(j+2));
569                         return result;
570                 }
571
572         @Override
573         public boolean addAll(int index, Collection<? extends Statement> c) {
574             throw new UnsupportedOperationException();
575         }
576
577         @Override
578         public Statement get(int index) {
579             index += 3;
580             if(index < 0 || index >= sizeInternal())
581                 throw new IndexOutOfBoundsException();
582             return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
583         }
584
585         @Override
586         public Statement set(int index, Statement element) {
587             throw new UnsupportedOperationException();
588         }
589
590         @Override
591         public void add(int index, Statement element) {
592             throw new UnsupportedOperationException();
593         }
594
595         @Override
596         public Statement remove(int index) {
597             throw new UnsupportedOperationException();
598         }
599
600         @Override
601         public int indexOf(Object obj) {
602             if(!(obj instanceof InternalStatement))
603                 return -1;
604             InternalStatement statement = (InternalStatement)obj;
605             int s = statement.s;
606             int p = statement.p;
607             int o = statement.o;
608             for(int i=0;i<sizeInternal();i+=3)
609                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
610                     return i/3;
611             return -1;
612         }
613
614         @Override
615         public int lastIndexOf(Object obj) {
616             if(!(obj instanceof InternalStatement))
617                 return -1;
618             InternalStatement statement = (InternalStatement)obj;
619             int s = statement.s;
620             int p = statement.p;
621             int o = statement.o;
622             for(int i=sizeInternal()-3;i>=0;i-=3)
623                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
624                     return i/3;
625             return -1;
626         }
627
628         @Override
629         public ListIterator<Statement> listIterator() {
630             return new IteratorImpl(0);
631         }
632
633         @Override
634         public ListIterator<Statement> listIterator(int index) {
635             return new IteratorImpl(index*3);
636         }
637
638         @Override
639         public List<Statement> subList(int fromIndex, int toIndex) {
640             if(fromIndex < 0 || toIndex*3 >= sizeInternal() || fromIndex > toIndex)
641                 throw new IndexOutOfBoundsException();
642             return new RandomAccessSubList<Statement>(this, fromIndex, toIndex-fromIndex);
643         }
644         }
645         
646         @Override
647         final public Collection<Statement> getStatements(final Resource subject,
648                         final Resource relation)
649                         throws ManyObjectsForFunctionalRelationException, ServiceException {
650
651                 assert (subject != null);
652                 assert (relation != null);
653
654                 try {
655
656                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
657                         processor.forEachStatement(this, subject, relation, procedure);
658                         procedure.checkAndThrow();
659                         return procedure;
660                         
661                 } catch (DatabaseException e) {
662
663                         System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation);
664
665                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
666                         processor.forEachStatement(this, subject, relation, procedure);
667                         
668                         return Collections.emptyList();
669                 
670 //                      throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e);
671
672                 }
673
674         }
675
676         @Override
677         final public Collection<Statement> getAssertedStatements(final Resource subject, final Resource relation)
678                         throws ManyObjectsForFunctionalRelationException, ServiceException {
679
680                 assert (subject != null);
681                 assert (relation != null);
682
683                 try {
684
685                         return syncRequest(new ForEachAssertedStatement(subject, relation));
686
687                 } catch (ManyObjectsForFunctionalRelationException e) {
688
689                         throw new ManyObjectsForFunctionalRelationException(e);
690
691                 } catch (ServiceException e) {
692
693                         throw new ServiceException(e);
694
695                 } catch (DatabaseException e) {
696
697                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
698
699                 }
700
701         }
702
703         @Override
704         final public Collection<Resource> getPredicates(final Resource subject) throws ServiceException {
705
706                 assert (subject != null);
707
708                 try {
709
710                         return processor.getPredicates(this, subject);
711
712 //                      AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
713 //                      processor.forEachPredicate(this, subject, procedure);
714 //                      procedure.checkAndThrow();
715 //                      return procedure;
716
717                 } catch (ServiceException e) {
718
719                         throw new ServiceException(e);
720
721                 } catch (DatabaseException e) {
722
723                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
724
725                 }  catch (Throwable e) {
726
727             throw new ServiceException(e);
728
729                 }
730
731         }
732
733         @Override
734         final public Collection<Resource> getPrincipalTypes(final Resource subject)
735                         throws ServiceException {
736
737                 assert (subject != null);
738
739                 try {
740
741                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
742                         processor.forEachPrincipalType(this, subject, procedure);
743                         procedure.checkAndThrow();
744                         return procedure;
745                         
746                 } catch (ServiceException e) {
747
748                         throw new ServiceException(e);
749
750                 } catch (DatabaseException e) {
751
752                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
753
754                 }
755
756         }
757
758         @Override
759         final public Set<Resource> getTypes(final Resource subject) throws ServiceException {
760
761                 assert (subject != null);
762
763                 try {
764                         
765                         return processor.getTypes(this, subject);
766                         
767                 } catch (ServiceException e) {
768
769                         throw new ServiceException(e);
770                         
771                 } catch (DatabaseException e) {
772
773                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
774
775         } catch (Throwable e) {
776
777             throw new ServiceException(e);
778
779                 }
780
781         }
782
783         @Override
784         final public Set<Resource> getSupertypes(final Resource subject)
785                         throws ServiceException {
786
787                 assert (subject != null);
788
789                 try {
790
791                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
792                         processor.forSupertypes(this, subject, procedure);
793                         procedure.checkAndThrow();
794                         return procedure.result;
795
796                 } catch (ServiceException e) {
797
798                         throw new ServiceException(e);
799
800                 } catch (DatabaseException e) {
801
802                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
803
804                 }
805
806         }
807
808         @Override
809         final public Set<Resource> getSuperrelations(final Resource subject)
810                         throws ServiceException {
811
812                 assert (subject != null);
813
814                 try {
815
816                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
817                         processor.forSuperrelations(this, subject, procedure);
818                         procedure.checkAndThrow();
819                         return procedure.result;
820
821                 } catch (ServiceException e) {
822
823                         throw new ServiceException(e);
824
825                 } catch (DatabaseException e) {
826
827                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
828
829                 }
830
831         }
832         
833         @Override
834         public Resource getPossibleSuperrelation(Resource subject) throws ServiceException {
835                 
836                 try {
837
838                         SyncReadProcedure<Resource> procedure = new SyncReadProcedure<Resource>();
839                         processor.forPossibleSuperrelation(this, subject, procedure);
840                         procedure.checkAndThrow();
841                         return procedure.result;
842
843                 } catch (ServiceException e) {
844
845                         throw new ServiceException(e);
846
847                 } catch (DatabaseException e) {
848
849                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
850
851                 }
852
853         }
854
855         @Override
856         final public Collection<Resource> getObjects(final Resource subject, final Resource relation)
857                         throws ServiceException {
858
859                 assert (subject != null);
860                 assert (relation != null);
861
862                 if(Development.DEVELOPMENT) {
863             if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) {
864                 counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1);
865             }
866             //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace();
867                 }
868                 
869                 try {
870
871                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
872                         processor.forEachObject(this, subject, relation, procedure);
873                         procedure.checkAndThrow();
874                         return procedure;
875                         
876                 } catch (DatabaseException e) {
877
878                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
879
880                 }
881
882         }
883
884         @Override
885         final public Collection<Resource> getAssertedObjects(
886                         final Resource subject, final Resource relation)
887                         throws ManyObjectsForFunctionalRelationException, ServiceException {
888
889         if (subject == null)
890             throw new ArgumentException("Subject must not be null.");
891         if (relation == null)
892             throw new ArgumentException("Relation must not be null. Subject=" + subject);
893
894                 try {
895
896                         return syncRequest(new ForEachAssertedObject(subject, relation));
897
898                 } catch (ManyObjectsForFunctionalRelationException e) {
899
900                         throw new ManyObjectsForFunctionalRelationException(e);
901
902                 } catch (ServiceException e) {
903
904                         throw new ServiceException(e);
905
906                 } catch (DatabaseException e) {
907
908                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
909
910                 }
911
912         }
913
914         @Override
915         final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException {
916
917                 assert (relation != null);
918
919                 try {
920
921                         return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
922
923                 } catch (NoSingleResultException e) {
924
925                         throw new NoInverseException(e);
926
927                 } catch (ServiceException e) {
928
929                         throw new ServiceException(e);
930
931                 }
932
933         }
934
935         @Override
936         final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException {
937
938                 if( subject == null) throw new IllegalArgumentException("subject can not be null");
939                 if( relation == null) throw new IllegalArgumentException("relation can not be null");
940
941                 try {
942                         int single = processor.getSingleObject(this, subject, relation);
943                         if (single == 0) {
944                                 if (EMPTY_RESOURCE_CHECK) {
945                                         if (!hasStatement(subject)) {
946                                                 throw new EmptyResourceException("Resource " + debugString(subject));
947                                         }
948                                 }
949                                 throw new NoSingleResultException("No single object for subject " + debugString(subject)
950                                                 + " and relation " + debugString(relation), single);
951                         }
952                         return processor.querySupport.getResource(single);
953                 } catch (NoSingleResultException e) {
954                         throw e;
955                 } catch (DatabaseException e) {
956                         throw new ServiceException(e);
957                 } 
958         }
959
960         @Override
961         final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
962                 assert (subject != null);
963                 assert (relation != null);
964                 try {
965                         Collection<Statement> statements = getStatements(subject, relation);
966                         if (statements.size() == 1) {
967                                 return statements.iterator().next();
968                         } else {
969                                 if (EMPTY_RESOURCE_CHECK)
970                                         if (!hasStatement(subject))
971                                                 throw new EmptyResourceException("Resource " + debugString(subject));
972                                 throw new NoSingleResultException("No single statement for subject " + debugString(subject)
973                                                 + " and relation " + debugString(relation), statements.size());
974                         }
975                 } catch (ServiceException e) {
976                         throw new ServiceException(e);
977                 } 
978         }
979
980         @Override
981         final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
982                 assert (subject != null);
983                 try {
984                         ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
985                         if (principalTypes.size() == 1) {
986                             return principalTypes.get(0);
987                         } else {
988                             throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
989                         }
990                 } catch (ServiceException e) {
991                         throw new ServiceException(e);
992                 } 
993         }
994
995         @Override
996         final public Resource getSingleType(final Resource subject,
997                         final Resource baseType) throws NoSingleResultException,
998                         ServiceException {
999
1000                 assert (subject != null);
1001                 assert (baseType != null);
1002
1003                 try {
1004                         return syncRequest(new SingleType(subject, baseType));
1005                 } catch (DatabaseException e) {
1006                     throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
1007                 }
1008         }
1009
1010         @Override
1011         final public <T> T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1012
1013                 assert (subject != null);
1014
1015                 try {
1016
1017                         Layer0 L0 = processor.getL0(this);
1018             int object = processor.getSingleObject(this, subject, L0.HasDataType);
1019             if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1020             
1021             if(processor.isImmutable(object)) {
1022                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1023                         return getValue(subject, binding);
1024             } else {
1025                     byte[] dt = processor.getValue(this, object);
1026                     if(dt == null) throw new ServiceException("No data type for " + subject);
1027                     Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1028                     Binding binding = Bindings.getBinding(datatype);
1029                     return getValue(subject, binding);
1030             }
1031                         
1032         } catch (IOException e) {
1033
1034             throw new ServiceException(e);
1035
1036                 } catch (DoesNotContainValueException e) {
1037
1038                         throw new DoesNotContainValueException(e, subject);
1039
1040                 } catch (ServiceException e) {
1041
1042                         throw new ServiceException(e);
1043
1044                 } catch (DatabaseException e) {
1045
1046                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1047
1048         }
1049
1050         }
1051
1052     @Override
1053     final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1054
1055         assert (subject != null);
1056
1057         try {
1058
1059             Layer0 L0 = processor.getL0(this);
1060             int object = processor.getSingleObject(this, subject, L0.HasDataType);
1061             if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1062             
1063             if(processor.isImmutable(object)) {
1064                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1065                 return new Variant(binding, getValue(subject, binding));
1066             } else {
1067                 byte[] dt = processor.getValue(this, object);
1068                 if(dt == null) throw new ServiceException("No data type for " + subject);
1069                 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1070                 Binding binding = Bindings.getBinding(datatype);
1071                 return new Variant(binding, getValue(subject, binding));
1072             }
1073             
1074         } catch (IOException e) {
1075
1076             throw new ServiceException(e);
1077
1078         } catch (DoesNotContainValueException e) {
1079
1080             throw new DoesNotContainValueException(e, subject);
1081
1082         } catch (ServiceException e) {
1083
1084             throw new ServiceException(e);
1085
1086         } catch (DatabaseException e) {
1087
1088             throw new ServiceException(INTERNAL_ERROR_STRING, e);
1089
1090         }               
1091         }
1092
1093         static final IdentityHashMap<Binding,Serializer> serializers = new IdentityHashMap<Binding,Serializer>();
1094         
1095         static {
1096                 serializers.put(Bindings.STRING, Bindings.STRING.serializer());
1097         }
1098         
1099         final protected Serializer getSerializer(Binding binding) {
1100             return binding.serializer();
1101         }
1102         
1103         @Override
1104         final public <T> T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException,
1105                         ServiceException {
1106
1107                 assert (subject != null);
1108
1109                 byte[] bytes = null;
1110                 try {
1111                         
1112                         bytes = processor.getValue(this, subject);
1113                         if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
1114
1115                         Serializer serializer = getSerializer(binding);
1116                         return (T)serializer.deserialize(bytes);
1117
1118                 } catch (DoesNotContainValueException e) {
1119
1120                         throw new DoesNotContainValueException(e);
1121
1122                 } catch (Throwable t) {
1123                         throw new ServiceException("Could not getValue for subject " + debugString(subject) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(bytes), t);
1124                 }
1125         }
1126
1127         @Override
1128         final public <T> T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1129                         DoesNotContainValueException, ServiceException {
1130
1131                 assert (subject != null);
1132                 assert (relation != null);
1133
1134                 try {
1135                         Resource object = getSingleObject(subject, relation);
1136                         return getValue(object);
1137                 } catch (NoSingleResultException e) {
1138                         throw new NoSingleResultException("No single value found for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1139                 } catch (DoesNotContainValueException e) {
1140                         try {
1141                                 Layer0 L0 = processor.getL0(this);
1142                                 Resource object = getPossibleObject(subject, relation);
1143                                 if(isInstanceOf(object, L0.Value)) {
1144                                         if(isInstanceOf(object, L0.Literal)) {
1145                                                 throw new DoesNotContainValueException(e);
1146                                         } else {
1147                                                 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1148                                         }
1149                                 } else {
1150                                         throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1151                                 }
1152                         } catch (DoesNotContainValueException e2) {
1153                                 throw e2;
1154                         } catch (DatabaseException e2) {
1155                                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1156                         }
1157                 } catch (ServiceException e) {
1158                         throw new ServiceException(e);
1159                 }
1160         }
1161
1162     @Override
1163     final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1164             DoesNotContainValueException, ServiceException {
1165
1166         assert (subject != null);
1167         assert (relation != null);
1168
1169         try {
1170             Resource object = getSingleObject(subject, relation);
1171             return getVariantValue(object);
1172         } catch (NoSingleResultException e) {
1173             throw new NoSingleResultException("No single object for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1174         } catch (DoesNotContainValueException e) {
1175             try {
1176                 Layer0 L0 = processor.getL0(this);
1177                 Resource object = getPossibleObject(subject, relation);
1178                 if(isInstanceOf(object, L0.Value)) {
1179                     if(isInstanceOf(object, L0.Literal)) {
1180                         throw new DoesNotContainValueException(e);
1181                     } else {
1182                         throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1183                     }
1184                 } else {
1185                     throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1186                 }
1187             } catch (DoesNotContainValueException e2) {
1188                 throw e2;
1189             } catch (DatabaseException e2) {
1190                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1191             }
1192         } catch (ServiceException e) {
1193             throw new ServiceException(e);
1194         } 
1195     }
1196     
1197         @Override
1198         final public <T> T getRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1199                         throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException {
1200
1201                 assert (subject != null);
1202                 assert (relation != null);
1203
1204                 try {
1205                         Resource object = getSingleObject(subject, relation);
1206                         return getValue(object, binding);
1207                 } catch (NoSingleResultException e) {
1208                     String message = "";
1209                     try {
1210                     String subjectName = NameUtils.getSafeName(this, subject, true);
1211                     String relationName = NameUtils.getSafeName(this, relation, true);
1212                     message = "Subject: " + subjectName + ", Relation: " + relationName;
1213                     } catch (DatabaseException e2) {
1214                         
1215                     }
1216             throw new NoSingleResultException(message, e.getResultCount(), e);
1217                 } catch (DoesNotContainValueException e) {
1218                         throw new DoesNotContainValueException(e);
1219                 } catch (ServiceException e) {
1220                         throw new ServiceException(e);
1221                 }
1222         }
1223
1224         @Override
1225         final public <T> T adapt(final Resource resource, final Class<T> clazz)
1226                         throws AdaptionException, ValidationException, ServiceException {
1227
1228                 assert (resource != null);
1229                 assert (clazz != null);
1230
1231                 try {
1232
1233                         return syncRequest(new Adapter<T>(resource, clazz));
1234
1235                 } catch (AdaptionException e) {
1236
1237                         throw new AdaptionException(e);
1238
1239                 } catch (ValidationException e) {
1240
1241                         throw new ValidationException(e);
1242
1243                 } catch (ServiceException e) {
1244
1245                         throw new ServiceException(e);
1246
1247                 } catch (DatabaseException e) {
1248
1249                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1250
1251                 }
1252
1253         }
1254
1255         @Override
1256         final public <T,C> T adaptContextual(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1257                         throws AdaptionException, ValidationException, ServiceException {
1258
1259                 assert (resource != null);
1260                 assert (context != null);
1261
1262                 class ContextualAdapter implements AsyncRead<T> {
1263
1264                         final private Resource resource;
1265                         final private C context;
1266                     final private Class<T> clazz;
1267                     
1268                     @Override
1269                     public int hashCode() {
1270                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1271                     }
1272                     
1273                     @Override
1274                     final public int threadHash() {
1275                         return resource.getThreadHash();
1276                     }
1277                     
1278                     @Override
1279                     public boolean equals(Object object) {
1280                         if (this == object)
1281                             return true;
1282                         else if (object == null)
1283                             return false;
1284                         else if (getClass() != object.getClass())
1285                             return false;
1286                         ContextualAdapter r = (ContextualAdapter)object;
1287                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1288                     }
1289
1290                     @Override
1291                     public int getFlags() {
1292                         return 0;
1293                     }
1294                     
1295                     public ContextualAdapter(Resource resource, C context, Class<T> clazz) {
1296                         this.resource = resource;
1297                         this.context = context;
1298                         this.clazz = clazz;
1299                     }
1300
1301                     @Override
1302                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1303                         
1304                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1305                                 if (service == null)
1306                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1307                                 else
1308                                         service.adapt(graph, resource, context, contextClass, clazz, false, procedure); 
1309                         
1310                     }
1311
1312                     @Override
1313                     public String toString() {
1314                         return "Adapter for (" + resource + "," + context + ") as " + clazz.getName();
1315                     }
1316                     
1317                 }
1318                 
1319                 try {
1320
1321                         return syncRequest(new ContextualAdapter(resource, context, clazz));
1322
1323                 } catch (AdaptionException e) {
1324
1325                         throw new AdaptionException(e);
1326
1327                 } catch (ValidationException e) {
1328
1329                         throw new ValidationException(e);
1330
1331                 } catch (ServiceException e) {
1332
1333                         throw new ServiceException(e);
1334
1335                 } catch (DatabaseException e) {
1336
1337                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1338
1339                 }
1340
1341         }
1342         
1343         @Override
1344         final public <T> T adaptRelated(final Resource resource, final Resource relation, final Class<T> clazz)
1345                         throws AdaptionException, NoSingleResultException, ValidationException, ServiceException {
1346
1347                 assert (resource != null);
1348                 assert (clazz != null);
1349
1350                 Statement stm = getSingleStatement(resource, relation);
1351                 
1352                 return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz);
1353                 
1354         }
1355
1356         @Override
1357         final public <T> T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class<T> clazz)
1358                         throws ValidationException, ServiceException {
1359
1360                 try {
1361                         return adaptRelated(resource, relation, clazz);
1362                 } catch (DatabaseException e) {
1363                         return null;
1364                 }
1365                 
1366         }
1367
1368         @Override
1369         final public <T,C> T getPossibleContextualAdapter(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1370                         throws ValidationException, ServiceException {
1371
1372                 assert (resource != null);
1373                 assert (context != null);
1374
1375                 class PossibleContextualAdapter implements AsyncRead<T> {
1376
1377                         final private Resource resource;
1378                         final private C context;
1379                     final private Class<T> clazz;
1380                     
1381                     @Override
1382                     public int hashCode() {
1383                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1384                     }
1385                     
1386                     @Override
1387                     final public int threadHash() {
1388                         return resource.getThreadHash();
1389                     }
1390                     
1391                     @Override
1392                     public boolean equals(Object object) {
1393                         if (this == object)
1394                             return true;
1395                         else if (object == null)
1396                             return false;
1397                         else if (getClass() != object.getClass())
1398                             return false;
1399                         PossibleContextualAdapter r = (PossibleContextualAdapter)object;
1400                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1401                     }
1402
1403                     @Override
1404                     public int getFlags() {
1405                         return 0;
1406                     }
1407                     
1408                     public PossibleContextualAdapter(Resource resource, C context, Class<T> clazz) {
1409                         this.resource = resource;
1410                         this.context = context;
1411                         this.clazz = clazz;
1412                     }
1413
1414                     @Override
1415                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1416                         
1417                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1418                                 if (service == null)
1419                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1420                                 else
1421                                         service.adapt(graph, resource, context, contextClass, clazz, true, procedure); 
1422                         
1423                     }
1424
1425                     @Override
1426                     public String toString() {
1427                         return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName();
1428                     }
1429                     
1430                 }
1431                 
1432                 try {
1433
1434                         return syncRequest(new PossibleContextualAdapter(resource, context, clazz));
1435
1436                 } catch (ValidationException e) {
1437
1438                         throw new ValidationException(e);
1439
1440                 } catch (ServiceException e) {
1441
1442                         throw new ServiceException(e);
1443
1444                 } catch (DatabaseException e) {
1445
1446                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1447
1448                 }
1449                 
1450         }
1451
1452         @Override
1453         final public <T> T adaptUnique(final Resource resource, final Class<T> clazz)
1454                         throws AdaptionException, ValidationException, ServiceException {
1455
1456                 assert (resource != null);
1457                 assert (clazz != null);
1458
1459                 try {
1460
1461                         return syncRequest(new UniqueAdapter<T>(resource, clazz));
1462
1463                 } catch (AdaptionException e) {
1464
1465                         throw new AdaptionException(e);
1466
1467                 } catch (ValidationException e) {
1468
1469                         throw new ValidationException(e);
1470
1471                 } catch (ServiceException e) {
1472
1473                         throw new ServiceException(e);
1474
1475                 } catch (DatabaseException e) {
1476
1477                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1478
1479                 }
1480
1481         }
1482
1483         @Override
1484         final public Resource getPossibleInverse(final Resource relation)
1485                         throws ServiceException {
1486
1487                 assert (relation != null);
1488
1489                 try {
1490
1491                         return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
1492
1493                 } catch (ServiceException e) {
1494
1495                         throw new ServiceException(e);
1496
1497                 } catch (DatabaseException e) {
1498
1499                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1500
1501                 }
1502
1503         }
1504
1505         @Override
1506         public Resource getPossibleObject(final Resource subject, final Resource relation)
1507                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1508
1509                 assert (subject != null);
1510                 assert (relation != null);
1511
1512                 try {
1513
1514                     int result = processor.getSingleObject(this, subject, relation);
1515                     if(result == 0) return null;
1516                     
1517                     return processor.querySupport.getResource(result);
1518
1519              } catch (ManyObjectsForFunctionalRelationException e) {
1520
1521                  throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
1522                  
1523                 } catch (DatabaseException e) {
1524
1525                         throw new ServiceException(e);
1526
1527                 }
1528                 
1529         }
1530
1531         @Override
1532         final public Statement getPossibleStatement(final Resource subject, final Resource relation)
1533                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1534
1535                 assert (subject != null);
1536                 assert (relation != null);
1537
1538                 try {
1539
1540                         Collection<Statement> statements = getStatements(subject, relation);
1541                         if(statements.size() == 1) return statements.iterator().next();
1542                         else return null;
1543
1544                 } catch (ManyObjectsForFunctionalRelationException e) {
1545
1546                         throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
1547
1548                 } catch (ServiceException e) {
1549
1550                         throw new ServiceException(e);
1551
1552                 } 
1553
1554         }
1555
1556         @Override
1557         final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException {
1558
1559                 assert (subject != null);
1560                 assert (baseType != null);
1561
1562                 try {
1563
1564                         AsyncReadProcedure<Resource> procedure = new AsyncReadProcedure<Resource>();
1565                         forPossibleType(subject, baseType, procedure);
1566                         procedure.checkAndThrow();
1567                         return procedure.result;                        
1568
1569                 } catch (ServiceException e) {
1570
1571                         throw new ServiceException(e);
1572
1573                 } catch (DatabaseException e) {
1574
1575                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1576
1577                 }
1578
1579         }
1580
1581         @Override
1582         final public <T> T getPossibleValue(final Resource subject) throws ServiceException {
1583
1584                 assert (subject != null);
1585
1586                 try {
1587                     
1588                     int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType);
1589                     if(object == 0) return null;
1590                     
1591             if(processor.isImmutable(object)) {
1592                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1593                         return getPossibleValue(subject, binding);
1594             } else {
1595                     byte[] dt = processor.getValue(this, object);
1596                     if(dt == null) return null;
1597                     Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1598                     Binding binding = Bindings.getBinding(datatype);
1599                     return getPossibleValue(subject, binding);
1600             }
1601                     
1602         } catch (IOException e) {
1603             
1604             throw new ServiceException(e);
1605             
1606                 } catch (ServiceException e) {
1607
1608                         throw new ServiceException(e);
1609
1610                 } catch (DatabaseException e) {
1611
1612                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1613
1614         }
1615
1616         }
1617
1618         @Override
1619         final public <T> T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException {
1620
1621                 assert (subject != null);
1622                 assert (binding != null);
1623
1624                 try {
1625
1626             byte[] dt = processor.getValue(this, subject);
1627             if(dt == null) return null;
1628                         Serializer serializer = getSerializer(binding);
1629             return (T)serializer.deserialize(dt);
1630
1631         } catch (IOException e) {
1632
1633             throw new ServiceException(e);
1634             
1635                 } catch (BindingException e) {
1636
1637                         throw new BindingException(e);
1638
1639                 } catch (ServiceException e) {
1640
1641                         throw new ServiceException(e);
1642
1643                 } catch (DatabaseException e) {
1644                         e.printStackTrace();
1645                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1646         }
1647
1648         }
1649
1650         @Override
1651         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation)
1652                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1653
1654                 assert (subject != null);
1655                 assert (relation != null);
1656
1657                 try {
1658
1659                         Resource object = getPossibleObject(subject, relation);
1660                         if(object == null) return null;
1661                         else return getPossibleValue(object);
1662
1663                 } catch (ManyObjectsForFunctionalRelationException e) {
1664
1665                         throw new ManyObjectsForFunctionalRelationException(e);
1666
1667                 } catch (ServiceException e) {
1668
1669                         throw new ServiceException(e);
1670
1671                 } 
1672
1673         }
1674
1675         @Override
1676         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1677                         throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
1678
1679                 assert (subject != null);
1680                 assert (relation != null);
1681                 assert (binding != null);
1682
1683                 try {
1684
1685                         Resource object = getPossibleObject(subject, relation);
1686                         if(object == null) return null;
1687                         else return getPossibleValue(object, binding);
1688
1689                 } catch (ManyObjectsForFunctionalRelationException e) {
1690
1691                         throw new ManyObjectsForFunctionalRelationException(e);
1692
1693                 } catch (BindingException e) {
1694
1695                         throw new BindingException(e);
1696
1697                 } catch (ServiceException e) {
1698
1699                         throw new ServiceException(e);
1700
1701                 }
1702
1703         }
1704
1705         @Override
1706         public <T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1707
1708                 assert (resource != null);
1709                 assert (clazz != null);
1710
1711                 try {
1712
1713                         return syncRequest(new PossibleAdapter<T>(resource, clazz));
1714
1715                 } catch (ValidationException e) {
1716
1717                         throw new ValidationException(e);
1718
1719                 } catch (AdaptionException e) {
1720
1721                         return null;
1722
1723                 } catch (DatabaseException e) {
1724
1725                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1726
1727                 }
1728         }
1729
1730         @Override
1731         public <T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1732
1733                 assert (resource != null);
1734                 assert (clazz != null);
1735
1736                 try {
1737
1738                         return syncRequest(new PossibleUniqueAdapter<T>(resource, clazz));
1739
1740                 } catch (AdaptionException e) {
1741
1742                         return null;
1743
1744                 } catch (ValidationException e) {
1745
1746                         throw new ValidationException(e);
1747
1748                 } catch (DatabaseException e) {
1749
1750                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1751
1752                 }
1753
1754         }
1755
1756     @Override
1757     final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException {
1758
1759         assert (resource != null);
1760         assert (type != null);
1761
1762         Set<Resource> resources = getTypes(resource);
1763         // This check was necessary because some of the callers of this method got stuck when the NPE was thrown from here.
1764         if (null == resources)
1765             return false;
1766         
1767         if(EMPTY_RESOURCE_CHECK) {
1768             if (resources.isEmpty()) {
1769                 if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource));
1770             }
1771         }
1772         
1773         return resources.contains(type);
1774
1775     }
1776
1777         @Override
1778         final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException {
1779
1780                 assert (resource != null);
1781                 assert (type != null);
1782
1783                 try {
1784
1785                         if(resource.equals(type)) return true;
1786                         
1787                         return getSupertypes(resource).contains(type);
1788
1789                 } catch (ServiceException e) {
1790
1791                         throw new ServiceException(e);
1792
1793                 } 
1794                 
1795         }
1796
1797         @Override
1798         final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException {
1799
1800                 assert (resource != null);
1801                 assert (type != null);
1802
1803                 try {
1804
1805                         if(resource.equals(type)) return true;
1806                         
1807                         return getSuperrelations(resource).contains(type);
1808
1809                 } catch (ServiceException e) {
1810
1811                         throw new ServiceException(e);
1812
1813                 } 
1814
1815         }
1816
1817         @Override
1818         final public boolean hasStatement(final Resource subject) throws ServiceException {
1819
1820                 assert (subject != null);
1821
1822                 try {
1823
1824                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1825                         processor.forHasStatement(this, subject, procedure);
1826                         procedure.checkAndThrow();
1827                         return procedure.result;
1828
1829                 } catch (ServiceException e) {
1830
1831                         throw new ServiceException(e);
1832
1833                 } catch (DatabaseException e) {
1834
1835                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1836
1837                 }
1838
1839         }
1840
1841         @Override
1842         final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException {
1843
1844                 assert (subject != null);
1845                 assert (relation != null);
1846
1847                 try {
1848
1849                         Collection<Resource> objects = getObjects(subject, relation);
1850                         return !objects.isEmpty();
1851
1852                 } catch (ServiceException e) {
1853
1854                         throw new ServiceException(e);
1855
1856                 } 
1857                 
1858         }
1859
1860         @Override
1861         final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1862
1863                 assert (subject != null);
1864                 assert (relation != null);
1865                 assert (object != null);
1866
1867                 try {
1868
1869                         for(Resource o : getObjects(subject, relation)) {
1870                                 if(object.equals(o)) return true;
1871                         }
1872                         
1873                         return false;
1874
1875                 } catch (ServiceException e) {
1876
1877                         throw new ServiceException(e);
1878
1879                 }
1880
1881         }
1882
1883         @Override
1884         final public boolean hasValue(final Resource subject) throws ServiceException {
1885
1886                 assert (subject != null);
1887
1888                 try {
1889
1890                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1891                         processor.forHasValue(this, subject, procedure);
1892                         procedure.checkAndThrow();
1893                         return procedure.result;
1894
1895                 } catch (ServiceException e) {
1896
1897                         throw new ServiceException(e);
1898
1899                 } catch (DatabaseException e) {
1900
1901                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1902
1903                 }
1904
1905         }
1906
1907         final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1908
1909                 @Override
1910                 public void execute(AsyncReadGraph graph, Object result) {
1911                 }
1912
1913                 @Override
1914                 public void exception(AsyncReadGraph graph, Throwable throwable) {
1915                 }
1916                 
1917         };
1918         
1919         /*
1920          * Implementation of the interface RequestProcessor
1921          */
1922
1923         @Override
1924         public <T> T syncRequest(final Read<T> request) throws DatabaseException {
1925                 assert (request != null);
1926                 return (T)QueryCache.runnerReadEntry(this, request, parent, null, null, true);
1927         }
1928
1929         @Override
1930         public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1931                         throws DatabaseException {
1932                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1933         }
1934
1935         @Override
1936         public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1937                         throws DatabaseException {
1938                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1939         }
1940
1941         @Override
1942         public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1943
1944                 assert (request != null);
1945
1946                 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1947
1948                 return QueryCache.resultReadEntry(this, request, parent, listener, procedure);
1949
1950         }
1951
1952         @Override
1953         public <T> T syncRequest(final Read<T> request,
1954                         final SyncProcedure<T> procedure) throws DatabaseException {
1955                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
1956         }
1957
1958         @Override
1959         public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
1960                         throws DatabaseException {
1961                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
1962         }
1963
1964         static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
1965
1966                 private static Throwable DONE = new Throwable();
1967                 
1968                 T result = null;
1969                 Throwable exception = null;
1970                 
1971                 @Override
1972                 public void execute(AsyncReadGraph graph, T t) {
1973                         result = t;
1974                         exception = DONE;
1975                 }
1976
1977                 @Override
1978                 public void exception(AsyncReadGraph graph, Throwable t) {
1979                         exception = t;
1980                 }
1981                 
1982                 public void checkAndThrow() throws DatabaseException {
1983                         if(exception != DONE) {
1984                                 if (exception instanceof DatabaseException)
1985                                         throw (DatabaseException) exception;
1986                                 else
1987                                         throw new DatabaseException(
1988                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
1989                                                         exception);
1990                         }
1991                 }
1992                 
1993                 public boolean done() {
1994                         return exception != null;
1995                 }
1996                 
1997         }
1998         
1999         @Override
2000         public <T> T syncRequest(final AsyncRead<T> request)
2001                         throws DatabaseException {
2002
2003                 assert (request != null);
2004                 return syncRequest(request, new AsyncProcedureAdapter<>() );
2005
2006         }
2007
2008         @Override
2009         public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2010                         throws DatabaseException {
2011                 return syncRequest(request, (AsyncProcedure<T>) procedure);
2012         }
2013
2014         @Override
2015         public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2016                         throws DatabaseException {
2017                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2018         }
2019
2020         @Override
2021         public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2022                         throws DatabaseException {
2023                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2024         }
2025
2026         @Override
2027         final public <T> T syncRequest(final AsyncRead<T> request,
2028                         final AsyncProcedure<T> procedure) throws DatabaseException {
2029
2030                 assert (request != null);
2031
2032                 ListenerBase listener = getListenerBase(procedure);
2033
2034 //              BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2035                 return (T)QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure, true);
2036 //              return ap.get();
2037
2038         }
2039
2040         @Override
2041         public <T> T syncRequest(AsyncRead<T> request,
2042                         final SyncProcedure<T> procedure) throws DatabaseException {
2043                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2044         }
2045
2046         @Override
2047         final public <T> T syncRequest(final AsyncRead<T> request,
2048                         final Procedure<T> procedure) throws DatabaseException {
2049                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2050         }
2051
2052         @Override
2053         public <T> Collection<T> syncRequest(final MultiRead<T> request)
2054                         throws DatabaseException {
2055
2056                 assert (request != null);
2057
2058                 final ArrayList<T> result = new ArrayList<T>();
2059                 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2060
2061                 syncRequest(request, new SyncMultiProcedure<T>() {
2062
2063                         @Override
2064                         public void execute(ReadGraph graph, T t) {
2065                                 synchronized (result) {
2066                                         result.add(t);
2067                                 }
2068                         }
2069
2070                         @Override
2071                         public void finished(ReadGraph graph) {
2072                         }
2073
2074                         @Override
2075                         public void exception(ReadGraph graph, Throwable t) {
2076                                 exception.set(t);
2077                         }
2078
2079                         @Override
2080                         public String toString() {
2081                                 return "syncRequest(MultiRead) -> " + request;
2082                         }
2083
2084                 });
2085
2086                 Throwable t = exception.get();
2087                 if (t != null) {
2088                         if (t instanceof DatabaseException)
2089                                 throw (DatabaseException) t;
2090                         else
2091                                 throw new DatabaseException(
2092                                                 "Unexpected exception in ReadGraph.syncRequest(Read)",
2093                                                 t);
2094                 }
2095
2096                 return result;
2097
2098         }
2099
2100         @Override
2101         public <T> Collection<T> syncRequest(MultiRead<T> request,
2102                         SyncMultiListener<T> procedure) {
2103                 return syncRequest(request, (SyncMultiProcedure<T>)procedure);
2104         }
2105
2106         @Override
2107         public <T> Collection<T> syncRequest(MultiRead<T> request,
2108                         MultiListener<T> procedure) {
2109                 return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
2110         }
2111
2112         @Override
2113         public <T> Collection<T> syncRequest(MultiRead<T> request,
2114                         SyncMultiProcedure<T> procedure) {
2115
2116                 assert (request != null);
2117
2118                 ListenerBase listener = getListenerBase(procedure);
2119
2120                 final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
2121
2122                 if (parent != null || listener != null) {
2123
2124 //                      Object syncParent = request;
2125
2126 //                      final ReadGraphImpl newGraph = newSync();
2127
2128                         processor.query(this, request, parent, wrapper, listener);
2129
2130 //                      newGraph.waitAsync(syncParent);
2131
2132                 } else {
2133
2134 //                      Object syncParent = request;
2135
2136 //                      final ReadGraphImpl newGraph = newSync();
2137
2138                         try {
2139                                 request.perform(this, wrapper);
2140                         } catch (Throwable t) {
2141                                 wrapper.exception(this, t);
2142                         }
2143
2144                 }
2145
2146                 return wrapper.get();
2147
2148         }
2149
2150         @Override
2151         public <T> Collection<T> syncRequest(MultiRead<T> request,
2152                         MultiProcedure<T> procedure) {
2153                 return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
2154         }
2155
2156         static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2157
2158                 private static Throwable DONE = new Throwable();
2159                 
2160                 private static final long serialVersionUID = -6494230465108115812L;
2161                 
2162                 Throwable exception = null;
2163                 
2164                 @Override
2165                 public synchronized void execute(AsyncReadGraph graph, T t) {
2166                         add(t);
2167                 }
2168
2169                 @Override
2170                 public void finished(AsyncReadGraph graph) {
2171                         exception = DONE;
2172                 }
2173
2174                 @Override
2175                 public void exception(AsyncReadGraph graph, Throwable t) {
2176                         exception = t;
2177                 }
2178                 
2179                 public void checkAndThrow() throws DatabaseException {
2180                         if(exception != DONE) {
2181                                 if (exception instanceof DatabaseException)
2182                                         throw (DatabaseException) exception;
2183                                 else
2184                                         throw new DatabaseException(
2185                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2186                                                         exception);
2187                         }
2188                 }
2189                 
2190                 public boolean done() {
2191                         return exception != null;
2192                 }
2193                 
2194         }
2195
2196         @Override
2197         final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2198                         throws DatabaseException {
2199
2200                 assert (request != null);
2201
2202                 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2203                 
2204                 syncRequest(request, procedure);
2205                 
2206                 procedure.checkAndThrow();
2207                 return procedure;
2208
2209         }
2210
2211         @Override
2212         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2213                         AsyncMultiListener<T> procedure) {
2214                 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2215         }
2216
2217         @Override
2218         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2219                         SyncMultiListener<T> procedure) {
2220                 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2221         }
2222
2223         @Override
2224         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2225                         MultiListener<T> procedure) {
2226                 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2227         }
2228
2229         final private <T> void syncRequest(final AsyncMultiRead<T> request,
2230                         final AsyncMultiReadProcedure<T> procedure) {
2231
2232                 assert (request != null);
2233                 assert (procedure != null);
2234
2235                 ListenerBase listener = getListenerBase(procedure);
2236
2237                 if (parent != null || listener != null) {
2238
2239 //                      Object syncParent = request;
2240
2241 //                      final ReadGraphImpl newGraph = newSync();
2242
2243                         processor.query(this, request, parent, procedure, listener);
2244
2245 //                      newGraph.waitAsync(syncParent);
2246                         waitAsyncProcedure(procedure);
2247
2248                 } else {
2249
2250 //                      Object syncParent = callerThread == Integer.MIN_VALUE ? null
2251 //                                      : request;
2252 //
2253 //                      final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2254
2255                         try {
2256
2257 //                              inc();
2258 //                              ReadGraphImpl sync = newSync();
2259                                 request.perform(this, procedure);
2260 //                              sync.waitAsync(null);
2261                                 waitAsyncProcedure(procedure);
2262 //                              dec();
2263
2264                         } catch (Throwable t) {
2265
2266                                 waitAsyncProcedure(procedure);
2267 //                              dec();
2268
2269                         }
2270
2271                 }
2272
2273         }
2274         
2275         
2276         @Override
2277         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2278                         final AsyncMultiProcedure<T> procedure) {
2279
2280                 assert (request != null);
2281                 assert (procedure != null);
2282
2283                 ListenerBase listener = getListenerBase(procedure);
2284
2285                 if (parent != null || listener != null) {
2286
2287 //                      Object syncParent = request;
2288
2289 //                      final ReadGraphImpl newGraph = newSync();
2290
2291                         processor.query(this, request, parent, procedure, listener);
2292
2293 //                      newGraph.waitAsync(syncParent);
2294
2295                 } else {
2296
2297 //                      Object syncParent = request;
2298
2299 //                      final ReadGraphImpl newGraph = newSync();
2300
2301                         try {
2302
2303                                 request.perform(this, new AsyncMultiProcedure<T>() {
2304
2305                                         @Override
2306                                         public void execute(AsyncReadGraph graph, T result) {
2307                                                 procedure.execute(graph, result);
2308                                         }
2309
2310                                         @Override
2311                                         public void finished(AsyncReadGraph graph) {
2312                                                 procedure.finished(graph);
2313                                         }
2314
2315                                         @Override
2316                                         public void exception(AsyncReadGraph graph, Throwable t) {
2317                                                 procedure.exception(graph, t);
2318                                         }
2319
2320                                         @Override
2321                                         public String toString() {
2322                                                 return "syncRequest(AsyncMultiRead) -> " + procedure;
2323                                         }
2324
2325                                 });
2326
2327                         } catch (Throwable t) {
2328
2329                         }
2330
2331                 }
2332
2333                 // TODO!!
2334                 return null;
2335
2336         }
2337
2338         @Override
2339         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2340                         final SyncMultiProcedure<T> procedure) {
2341                 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2342         }
2343
2344         @Override
2345         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2346                         final MultiProcedure<T> procedure) {
2347                 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2348         }
2349
2350         @Override
2351         public <T> T syncRequest(final ExternalRead<T> request)
2352                         throws DatabaseException {
2353
2354                 assert (request != null);
2355
2356                 return syncRequest(request, new Procedure<T>() {
2357
2358                         @Override
2359                         public void execute(T t) {
2360                         }
2361
2362                         @Override
2363                         public void exception(Throwable t) {
2364                         }
2365
2366                         @Override
2367                         public String toString() {
2368                                 return "syncRequest(AsyncRead) -> " + request;
2369                         }
2370
2371                 });
2372
2373         }
2374
2375         @Override
2376         public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2377                 return syncRequest(request, (Procedure<T>) procedure);
2378         }
2379
2380         @Override
2381         final public <T> T syncRequest(final ExternalRead<T> request,
2382                         final Procedure<T> procedure) throws DatabaseException {
2383
2384         assert (request != null);
2385
2386         ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
2387         return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
2388
2389         }
2390
2391         @Override
2392         public void syncRequest(final Write request) throws DatabaseException {
2393
2394                 assert (request != null);
2395
2396                 throw new DatabaseException(
2397                                 "Write operations are not supported during read transactions!");
2398
2399         }
2400
2401         @Override
2402         public <T> T syncRequest(final WriteResult<T> request) throws DatabaseException {
2403
2404                 assert (request != null);
2405
2406                 throw new DatabaseException(
2407                                 "Write operations are not supported during read transactions!");
2408
2409         }
2410
2411         @Override
2412         public void syncRequest(final DelayedWrite request)
2413                         throws DatabaseException {
2414
2415                 assert (request != null);
2416
2417                 throw new DatabaseException(
2418                                 "Write operations are not supported during read transactions!");
2419
2420         }
2421
2422         @Override
2423         public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {
2424
2425                 assert (request != null);
2426
2427                 throw new DatabaseException(
2428                                 "Write operations are not supported during read transactions!");
2429
2430         }
2431         
2432         @Override
2433         public void syncRequest(final WriteOnly request) throws DatabaseException {
2434
2435                 assert (request != null);
2436
2437                 throw new DatabaseException(
2438                                 "Write operations are not supported during read transactions!");
2439
2440         }
2441
2442         @Override
2443         public <T> T syncRequest(final WriteOnlyResult<T> request) throws DatabaseException {
2444
2445                 assert (request != null);
2446
2447                 throw new DatabaseException(
2448                                 "Write operations are not supported during read transactions!");
2449
2450         }
2451         
2452         @Override
2453         public <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure) {
2454                 r.request(this, procedure);
2455         }
2456         
2457         @Override
2458         public <T> void async(ReadInterface<T> r, Procedure<T> procedure) {
2459                 r.request(this, procedure);
2460         }
2461         
2462         @Override
2463         public <T> void async(ReadInterface<T> r, SyncProcedure<T> procedure) {
2464                 r.request(this, procedure);
2465         }
2466         
2467         @Override
2468         public <T> void async(ReadInterface<T> r, AsyncListener<T> procedure) {
2469                 r.request(this, procedure);
2470         }
2471         
2472         @Override
2473         public <T> void async(ReadInterface<T> r, Listener<T> procedure) {
2474                 r.request(this, procedure);
2475         }
2476         
2477         @Override
2478         public <T> void async(ReadInterface<T> r, SyncListener<T> procedure) {
2479                 r.request(this, procedure);
2480         }
2481
2482         @Override
2483         public <T> T sync(ReadInterface<T> r) throws DatabaseException {
2484                 return r.request(this);
2485         }
2486         
2487         @Override
2488         public <T> T sync(WriteInterface<T> r) throws DatabaseException {
2489                 return r.request(this);
2490         }
2491         
2492         @Override
2493         public <T> void async(WriteInterface<T> r, Procedure<T> procedure) {
2494                 r.request(this, procedure);
2495         }
2496
2497         @Override
2498         public <T> void async(WriteInterface<T> r) {
2499                 r.request(this, new ProcedureAdapter<T>());
2500         }
2501
2502         /*
2503          * Implementation of the interface AsyncReadGraph
2504          */
2505
2506         @Override
2507         public void forURI(Resource resource, AsyncListener<String> listener) {
2508                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2509                                 listener);
2510         }
2511
2512         @Override
2513         public void forURI(Resource resource, SyncListener<String> listener) {
2514                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2515                                 listener);
2516         }
2517
2518         @Override
2519         public void forURI(Resource resource, Listener<String> listener) {
2520                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2521                                 listener);
2522         }
2523
2524         @Override
2525         final public void forURI(final Resource resource,
2526                         final AsyncProcedure<String> procedure) {
2527
2528                 assert (resource != null);
2529                 assert (procedure != null);
2530
2531                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2532                                 procedure);
2533
2534         }
2535
2536         @Override
2537         public void forURI(Resource resource, SyncProcedure<String> procedure) {
2538                 forURI(resource, new SyncToAsyncProcedure<String>(procedure));
2539         }
2540
2541         @Override
2542         public void forURI(Resource resource, Procedure<String> procedure) {
2543                 forURI(resource, new NoneToAsyncProcedure<String>(procedure));
2544         }
2545         
2546         @Override
2547         public void forResource(String id, AsyncListener<Resource> listener) {
2548                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2549                                 listener);
2550         }
2551
2552         @Override
2553         public void forResource(String id, SyncListener<Resource> listener) {
2554                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2555                                 listener);
2556         }
2557
2558         @Override
2559         public void forResource(String id, Listener<Resource> listener) {
2560                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2561                                 listener);
2562         }
2563
2564         @Override
2565         final public void forResource(final String id,
2566                         final AsyncProcedure<Resource> procedure) {
2567
2568                 assert (id != null);
2569                 assert (procedure != null);
2570
2571                 processor.forResource(this, id, procedure);
2572
2573         }
2574
2575         @Override
2576         public void forResource(String id, SyncProcedure<Resource> procedure) {
2577                 forResource(id, new SyncToAsyncProcedure<Resource>(procedure));
2578         }
2579
2580         @Override
2581         public void forResource(String id, Procedure<Resource> procedure) {
2582                 forResource(id, new NoneToAsyncProcedure<Resource>(procedure));
2583         }
2584
2585         @Override
2586         public void forBuiltin(String id, AsyncListener<Resource> listener) {
2587                 asyncRequest(new Builtin(id), listener);
2588         }
2589
2590         @Override
2591         public void forBuiltin(String id, SyncListener<Resource> listener) {
2592                 asyncRequest(new Builtin(id), listener);
2593         }
2594
2595         @Override
2596         public void forBuiltin(String id, Listener<Resource> listener) {
2597                 asyncRequest(new Builtin(id), listener);
2598         }
2599
2600         @Override
2601         final public void forBuiltin(final String id,
2602                         final AsyncProcedure<Resource> procedure) {
2603
2604                 assert (id != null);
2605                 assert (procedure != null);
2606
2607                 processor.forBuiltin(this, id, procedure);
2608
2609         }
2610
2611         @Override
2612         public void forBuiltin(String id, SyncProcedure<Resource> procedure) {
2613                 forBuiltin(id, new SyncToAsyncProcedure<Resource>(procedure));
2614         }
2615
2616         @Override
2617         public void forBuiltin(String id, Procedure<Resource> procedure) {
2618                 forBuiltin(id, new NoneToAsyncProcedure<Resource>(procedure));
2619         }
2620
2621         @Override
2622         final public void forEachStatement(Resource subject, Resource relation,
2623                         AsyncMultiProcedure<Statement> procedure) {
2624
2625                 assert (subject != null);
2626                 assert (relation != null);
2627                 assert (procedure != null);
2628
2629                 processor.forEachStatement(this, subject, relation, procedure);
2630
2631         }
2632
2633         @Override
2634         public void forEachStatement(Resource subject, Resource relation,
2635                         SyncMultiProcedure<Statement> procedure) {
2636                 forEachStatement(subject, relation,
2637                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2638         }
2639
2640         @Override
2641         final public void forEachStatement(Resource subject, Resource relation,
2642                         MultiProcedure<Statement> procedure) {
2643
2644                 assert (subject != null);
2645                 assert (relation != null);
2646                 assert (procedure != null);
2647
2648                 processor.forEachStatement(this, subject, relation, procedure);
2649
2650         }
2651
2652         @Override
2653         final public void forStatementSet(Resource subject, Resource relation,
2654                         AsyncSetListener<Statement> procedure) {
2655
2656                 assert (subject != null);
2657                 assert (relation != null);
2658                 assert (procedure != null);
2659
2660                 processor.forStatementSet(this, subject, relation, procedure);
2661
2662         }
2663
2664         @Override
2665         final public void forStatementSet(Resource subject, Resource relation,
2666                         SyncSetListener<Statement> procedure) {
2667                 forStatementSet(subject, relation,
2668                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2669         }
2670
2671         @Override
2672         public void forStatementSet(Resource subject, Resource relation,
2673                         SetListener<Statement> listener) {
2674                 forStatementSet(subject, relation,
2675                                 new NoneToAsyncSetProcedure<Statement>(listener));
2676         }
2677
2678         @Override
2679         final public void forEachAssertedStatement(final Resource subject,
2680                         final Resource relation,
2681                         final AsyncMultiProcedure<Statement> procedure) {
2682
2683                 assert (subject != null);
2684                 assert (relation != null);
2685                 assert (procedure != null);
2686
2687                 processor.forEachAssertedStatement(this, subject, relation, procedure);
2688
2689         }
2690
2691         @Override
2692         public void forEachAssertedStatement(Resource subject, Resource relation,
2693                         SyncMultiProcedure<Statement> procedure) {
2694                 forEachAssertedStatement(subject, relation,
2695                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2696         }
2697
2698         @Override
2699         public void forEachAssertedStatement(Resource subject, Resource relation,
2700                         MultiProcedure<Statement> procedure) {
2701                 forEachAssertedStatement(subject, relation,
2702                                 new NoneToAsyncMultiProcedure<Statement>(procedure));
2703         }
2704
2705         @Override
2706         public void forAssertedStatementSet(Resource subject, Resource relation,
2707                         AsyncSetListener<Statement> procedure) {
2708
2709                 assert (subject != null);
2710                 assert (relation != null);
2711                 assert (procedure != null);
2712
2713                 processor.forAssertedStatementSet(this, subject, relation, procedure);
2714
2715         }
2716
2717         @Override
2718         public void forAssertedStatementSet(Resource subject, Resource relation,
2719                         SyncSetListener<Statement> procedure) {
2720
2721                 assert (subject != null);
2722                 assert (relation != null);
2723                 assert (procedure != null);
2724
2725                 forAssertedStatementSet(subject, relation,
2726                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2727
2728         }
2729
2730         @Override
2731         public void forAssertedStatementSet(Resource subject, Resource relation,
2732                         SetListener<Statement> procedure) {
2733
2734                 assert (subject != null);
2735                 assert (relation != null);
2736                 assert (procedure != null);
2737
2738                 forAssertedStatementSet(subject, relation,
2739                                 new NoneToAsyncSetProcedure<Statement>(procedure));
2740
2741         }
2742
2743         @Override
2744         final public void forEachPredicate(final Resource subject,
2745                         final AsyncMultiProcedure<Resource> procedure) {
2746
2747                 assert (subject != null);
2748                 assert (procedure != null);
2749
2750                 processor.forEachPredicate(this, subject, procedure);
2751
2752         }
2753
2754         @Override
2755         public void forEachPredicate(Resource subject,
2756                         SyncMultiProcedure<Resource> procedure) {
2757                 forEachPredicate(subject, new SyncToAsyncMultiProcedure<Resource>(
2758                                 procedure));
2759         }
2760
2761         @Override
2762         final public void forEachPredicate(final Resource subject,
2763                         final MultiProcedure<Resource> procedure) {
2764
2765                 assert (subject != null);
2766                 assert (procedure != null);
2767
2768                 processor.forEachPredicate(this, subject, procedure);
2769
2770         }
2771
2772         @Override
2773         final public void forPredicateSet(final Resource subject,
2774                         final AsyncSetListener<Resource> procedure) {
2775
2776                 assert (subject != null);
2777                 assert (procedure != null);
2778
2779                 processor.forPredicateSet(this, subject, procedure);
2780
2781         }
2782
2783         @Override
2784         final public void forPredicateSet(final Resource subject,
2785                         final SyncSetListener<Resource> procedure) {
2786
2787                 assert (subject != null);
2788                 assert (procedure != null);
2789
2790                 forPredicateSet(subject, new SyncToAsyncSetProcedure<Resource>(
2791                                 procedure));
2792
2793         }
2794
2795         @Override
2796         final public void forPredicateSet(final Resource subject,
2797                         final SetListener<Resource> procedure) {
2798
2799                 assert (subject != null);
2800                 assert (procedure != null);
2801
2802                 forPredicateSet(subject, new NoneToAsyncSetProcedure<Resource>(
2803                                 procedure));
2804
2805         }
2806
2807         @Override
2808         final public void forEachPrincipalType(final Resource subject,
2809                         final AsyncMultiProcedure<Resource> procedure) {
2810
2811                 assert (subject != null);
2812                 assert (procedure != null);
2813
2814                 processor.forEachPrincipalType(this, subject, procedure);
2815
2816         }
2817
2818         @Override
2819         public void forEachPrincipalType(Resource subject,
2820                         SyncMultiProcedure<Resource> procedure) {
2821                 forEachPrincipalType(subject, new SyncToAsyncMultiProcedure<Resource>(
2822                                 procedure));
2823         }
2824
2825         @Override
2826         final public void forEachPrincipalType(final Resource subject,
2827                         final MultiProcedure<Resource> procedure) {
2828
2829                 assert (subject != null);
2830                 assert (procedure != null);
2831
2832                 processor.forEachPrincipalType(this, subject, procedure);
2833
2834         }
2835
2836         @Override
2837         final public void forPrincipalTypeSet(final Resource subject,
2838                         final AsyncSetListener<Resource> procedure) {
2839
2840                 assert (subject != null);
2841                 assert (procedure != null);
2842
2843                 processor.forPrincipalTypeSet(this, subject, procedure);
2844
2845         }
2846
2847         @Override
2848         final public void forPrincipalTypeSet(final Resource subject,
2849                         final SyncSetListener<Resource> procedure) {
2850
2851                 assert (subject != null);
2852                 assert (procedure != null);
2853
2854                 forPrincipalTypeSet(subject, new SyncToAsyncSetProcedure<Resource>(
2855                                 procedure));
2856
2857         }
2858
2859         @Override
2860         final public void forPrincipalTypeSet(final Resource subject,
2861                         final SetListener<Resource> procedure) {
2862
2863                 assert (subject != null);
2864                 assert (procedure != null);
2865
2866                 forPrincipalTypeSet(subject, new NoneToAsyncSetProcedure<Resource>(
2867                                 procedure));
2868
2869         }
2870
2871         @Override
2872         public void forTypes(Resource subject, AsyncListener<Set<Resource>> listener) {
2873                 asyncRequest(new Types(subject), listener);
2874         }
2875
2876         @Override
2877         public void forTypes(Resource subject, SyncListener<Set<Resource>> listener) {
2878                 asyncRequest(new Types(subject), listener);
2879         }
2880
2881         @Override
2882         public void forTypes(Resource subject, Listener<Set<Resource>> listener) {
2883                 asyncRequest(new Types(subject), listener);
2884         }
2885
2886         @Override
2887         final public void forTypes(final Resource subject,
2888                         final AsyncProcedure<Set<Resource>> procedure) {
2889
2890                 assert (subject != null);
2891                 assert (procedure != null);
2892
2893                 processor.forTypes(this, subject, procedure);
2894
2895         }
2896
2897         @Override
2898         public void forTypes(Resource subject,
2899                         SyncProcedure<Set<Resource>> procedure) {
2900                 forTypes(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
2901         }
2902
2903         @Override
2904         public void forTypes(Resource subject, Procedure<Set<Resource>> procedure) {
2905                 forTypes(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
2906         }
2907
2908         @Override
2909         public void forSupertypes(Resource subject,
2910                         AsyncListener<Set<Resource>> listener) {
2911                 asyncRequest(new Types(subject), listener);
2912         }
2913
2914         @Override
2915         public void forSupertypes(Resource subject,
2916                         SyncListener<Set<Resource>> listener) {
2917                 asyncRequest(new Types(subject), listener);
2918         }
2919
2920         @Override
2921         public void forSupertypes(Resource subject, Listener<Set<Resource>> listener) {
2922                 asyncRequest(new Types(subject), listener);
2923         }
2924
2925         @Override
2926         final public void forSupertypes(final Resource subject,
2927                         final AsyncProcedure<Set<Resource>> procedure) {
2928
2929                 assert (subject != null);
2930                 assert (procedure != null);
2931
2932                 processor.forSupertypes(this, subject, procedure);
2933
2934         }
2935
2936         @Override
2937         public void forSupertypes(Resource subject,
2938                         SyncProcedure<Set<Resource>> procedure) {
2939                 forSupertypes(subject, new SyncToAsyncProcedure<Set<Resource>>(
2940                                 procedure));
2941         }
2942
2943         @Override
2944         public void forSupertypes(Resource subject,
2945                         Procedure<Set<Resource>> procedure) {
2946                 forSupertypes(subject, new NoneToAsyncProcedure<Set<Resource>>(
2947                                 procedure));
2948         }
2949
2950         @Override
2951         public void forDirectSuperrelations(Resource subject,
2952                         AsyncMultiProcedure<Resource> procedure) {
2953                 
2954                 assert (subject != null);
2955                 assert (procedure != null);
2956
2957                 processor.forDirectSuperrelations(this, subject, procedure);
2958                 
2959         }
2960
2961         @Override
2962         public void forPossibleSuperrelation(Resource subject, AsyncProcedure<Resource> procedure) {
2963                 
2964                 assert (subject != null);
2965                 assert (procedure != null);
2966
2967                 processor.forPossibleSuperrelation(this, subject, procedure);
2968                 
2969         }
2970
2971         @Override
2972         public void forSuperrelations(Resource subject,
2973                         AsyncListener<Set<Resource>> listener) {
2974                 asyncRequest(new Types(subject), listener);
2975         }
2976
2977         @Override
2978         public void forSuperrelations(Resource subject,
2979                         SyncListener<Set<Resource>> listener) {
2980                 asyncRequest(new Types(subject), listener);
2981         }
2982
2983         @Override
2984         public void forSuperrelations(Resource subject,
2985                         Listener<Set<Resource>> listener) {
2986                 asyncRequest(new Types(subject), listener);
2987         }
2988
2989         @Override
2990         final public void forSuperrelations(final Resource subject,
2991                         final AsyncProcedure<Set<Resource>> procedure) {
2992
2993                 assert (subject != null);
2994                 assert (procedure != null);
2995
2996                 processor.forSuperrelations(this, subject, procedure);
2997
2998         }
2999
3000         @Override
3001         public void forSuperrelations(Resource subject,
3002                         SyncProcedure<Set<Resource>> procedure) {
3003                 forSuperrelations(subject, new SyncToAsyncProcedure<Set<Resource>>(
3004                                 procedure));
3005         }
3006
3007         @Override
3008         public void forSuperrelations(Resource subject,
3009                         Procedure<Set<Resource>> procedure) {
3010                 forSuperrelations(subject, new NoneToAsyncProcedure<Set<Resource>>(
3011                                 procedure));
3012         }
3013
3014         @Override
3015         final public void forEachObject(final Resource subject, final Resource relation, final AsyncMultiProcedure<Resource> procedure) {
3016                 processor.forEachObject(this, subject, relation, procedure);
3017         }
3018
3019         @Override
3020         public void forEachObject(Resource subject, Resource relation,
3021                         SyncMultiProcedure<Resource> procedure) {
3022                 forEachObject(subject, relation,
3023                                 new SyncToAsyncMultiProcedure<Resource>(procedure));
3024         }
3025
3026         @Override
3027         public void forEachObject(Resource subject, Resource relation,
3028                         MultiProcedure<Resource> procedure) {
3029
3030                 processor.forEachObject(this, subject, relation, procedure);
3031
3032         }
3033
3034         @Override
3035         final public void forEachDirectPredicate(final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3036                 processor.forEachDirectPredicate(this, subject, procedure);
3037         }
3038
3039         @Override
3040         final public void forEachDirectPredicate(final Resource subject, final SyncProcedure<Set<Resource>> procedure) {
3041                 forEachDirectPredicate(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
3042         }
3043
3044         @Override
3045         public void forEachDirectPredicate(Resource subject, Procedure<Set<Resource>> procedure) {
3046                 forEachDirectPredicate(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
3047         }
3048
3049         @Override
3050         final public void forObjectSet(final Resource subject,
3051                         final Resource relation, final AsyncSetListener<Resource> procedure) {
3052
3053                 assert (subject != null);
3054                 assert (relation != null);
3055                 assert (procedure != null);
3056
3057                 processor.forObjectSet(this, subject, relation, procedure);
3058
3059         }
3060
3061         @Override
3062         final public void forObjectSet(final Resource subject,
3063                         final Resource relation, final SyncSetListener<Resource> procedure) {
3064
3065                 assert (subject != null);
3066                 assert (relation != null);
3067                 assert (procedure != null);
3068
3069                 forObjectSet(subject, relation, new SyncToAsyncSetProcedure<Resource>(
3070                                 procedure));
3071
3072         }
3073
3074         @Override
3075         final public void forObjectSet(final Resource subject,
3076                         final Resource relation, final SetListener<Resource> procedure) {
3077
3078                 assert (subject != null);
3079                 assert (relation != null);
3080                 assert (procedure != null);
3081
3082                 forObjectSet(subject, relation, new NoneToAsyncSetProcedure<Resource>(
3083                                 procedure));
3084
3085         }
3086
3087         @Override
3088         final public void forEachAssertedObject(final Resource subject,
3089                         final Resource relation,
3090                         final AsyncMultiProcedure<Resource> procedure) {
3091
3092                 assert (subject != null);
3093                 assert (relation != null);
3094                 assert (procedure != null);
3095
3096                 processor.forEachAssertedObject(this, subject, relation, procedure);
3097
3098         }
3099
3100         @Override
3101         public void forEachAssertedObject(Resource subject, Resource relation,
3102                         SyncMultiProcedure<Resource> procedure) {
3103
3104                 assert (subject != null);
3105                 assert (relation != null);
3106                 assert (procedure != null);
3107
3108                 forEachAssertedObject(subject, relation,
3109                                 new SyncToAsyncMultiProcedure<Resource>(procedure));
3110
3111         }
3112
3113         @Override
3114         public void forEachAssertedObject(Resource subject, Resource relation,
3115                         MultiProcedure<Resource> procedure) {
3116
3117                 assert (subject != null);
3118                 assert (relation != null);
3119                 assert (procedure != null);
3120
3121                 forEachAssertedObject(subject, relation,
3122                                 new NoneToAsyncMultiProcedure<Resource>(procedure));
3123
3124         }
3125
3126         @Override
3127         public void forAssertedObjectSet(Resource subject, Resource relation,
3128                         AsyncSetListener<Resource> procedure) {
3129
3130                 assert (subject != null);
3131                 assert (relation != null);
3132                 assert (procedure != null);
3133
3134                 processor.forAssertedObjectSet(this, subject, relation, procedure);
3135
3136         }
3137
3138         @Override
3139         public void forAssertedObjectSet(Resource subject, Resource relation,
3140                         SyncSetListener<Resource> procedure) {
3141
3142                 assert (subject != null);
3143                 assert (relation != null);
3144                 assert (procedure != null);
3145
3146                 forAssertedObjectSet(subject, relation,
3147                                 new SyncToAsyncSetProcedure<Resource>(procedure));
3148
3149         }
3150
3151         @Override
3152         public void forAssertedObjectSet(Resource subject, Resource relation,
3153                         SetListener<Resource> procedure) {
3154
3155                 assert (subject != null);
3156                 assert (relation != null);
3157                 assert (procedure != null);
3158
3159                 forAssertedObjectSet(subject, relation,
3160                                 new NoneToAsyncSetProcedure<Resource>(procedure));
3161
3162         }
3163
3164         @Override
3165         public void forInverse(Resource relation, AsyncListener<Resource> listener) {
3166                 asyncRequest(new Inverse(relation), listener);
3167         }
3168
3169         @Override
3170         public void forInverse(Resource relation, SyncListener<Resource> listener) {
3171                 asyncRequest(new Inverse(relation), listener);
3172         }
3173
3174         @Override
3175         public void forInverse(Resource relation, Listener<Resource> listener) {
3176                 asyncRequest(new Inverse(relation), listener);
3177         }
3178
3179         @Override
3180         final public void forInverse(final Resource relation,
3181                         final AsyncProcedure<Resource> procedure) {
3182
3183                 assert (relation != null);
3184                 assert (procedure != null);
3185
3186                 processor.forInverse(this, relation, new AsyncProcedure<Resource>() {
3187
3188                         @Override
3189                         public void execute(AsyncReadGraph graph, Resource result) {
3190                                 if (result != null)
3191                                         procedure.execute(graph, result);
3192                                 else {
3193                                         procedure.exception(graph, new NoInverseException(relation
3194                                                         .toString()));
3195                                 }
3196                         }
3197
3198                         @Override
3199                         public void exception(AsyncReadGraph graph, Throwable throwable) {
3200                                 procedure.exception(graph, throwable);
3201                         }
3202
3203                         @Override
3204                         public String toString() {
3205                                 return "forInverse -> " + procedure;
3206                         }
3207
3208                 });
3209
3210         }
3211
3212         @Override
3213         public void forInverse(Resource relation, SyncProcedure<Resource> procedure) {
3214                 forInverse(relation, new SyncToAsyncProcedure<Resource>(procedure));
3215         }
3216
3217         @Override
3218         public void forInverse(Resource relation, Procedure<Resource> procedure) {
3219                 forInverse(relation, new NoneToAsyncProcedure<Resource>(procedure));
3220         }
3221
3222         @Override
3223         public void forSingleObject(Resource subject, Resource relation,
3224                         AsyncListener<Resource> listener) {
3225                 asyncRequest(new SingleObject(subject, relation), listener);
3226         }
3227
3228         @Override
3229         public void forSingleObject(Resource subject, Resource relation,
3230                         SyncListener<Resource> listener) {
3231                 asyncRequest(new SingleObject(subject, relation), listener);
3232         }
3233
3234         @Override
3235         public void forSingleObject(Resource subject, Resource relation,
3236                         Listener<Resource> listener) {
3237                 asyncRequest(new SingleObject(subject, relation), listener);
3238         }
3239
3240         @Override
3241         final public void forSingleObject(final Resource subject,
3242                         final Resource relation, final AsyncProcedure<Resource> procedure) {
3243
3244                 assert (subject != null);
3245                 assert (relation != null);
3246                 assert (procedure != null);
3247
3248                 processor.forEachObject(this, subject, relation,
3249                                 new SingleOrErrorProcedure<Resource>(procedure));
3250
3251         }
3252
3253         @Override
3254         public void forSingleObject(Resource subject, Resource relation,
3255                         SyncProcedure<Resource> procedure) {
3256                 forSingleObject(subject, relation, new SyncToAsyncProcedure<Resource>(
3257                                 procedure));
3258         }
3259
3260         @Override
3261         public void forSingleObject(Resource subject, Resource relation,
3262                         Procedure<Resource> procedure) {
3263                 forSingleObject(subject, relation, new NoneToAsyncProcedure<Resource>(
3264                                 procedure));
3265         }
3266
3267         @Override
3268         public void forSingleStatement(Resource subject, Resource relation,
3269                         AsyncListener<Statement> listener) {
3270                 asyncRequest(new SingleStatement(subject, relation), listener);
3271         }
3272
3273         @Override
3274         public void forSingleStatement(Resource subject, Resource relation,
3275                         SyncListener<Statement> listener) {
3276                 asyncRequest(new SingleStatement(subject, relation), listener);
3277         }
3278
3279         @Override
3280         public void forSingleStatement(Resource subject, Resource relation,
3281                         Listener<Statement> listener) {
3282                 asyncRequest(new SingleStatement(subject, relation), listener);
3283         }
3284
3285         @Override
3286         final public void forSingleStatement(final Resource subject,
3287                         final Resource relation, final AsyncProcedure<Statement> procedure) {
3288
3289                 assert (subject != null);
3290                 assert (relation != null);
3291                 assert (procedure != null);
3292
3293                 processor.forEachStatement(this, subject, relation,
3294                                 new SingleOrErrorProcedure<Statement>(procedure));
3295
3296         }
3297
3298         @Override
3299         public void forSingleStatement(Resource subject, Resource relation,
3300                         SyncProcedure<Statement> procedure) {
3301                 forSingleStatement(subject, relation,
3302                                 new SyncToAsyncProcedure<Statement>(procedure));
3303         }
3304
3305         @Override
3306         public void forSingleStatement(Resource subject, Resource relation,
3307                         Procedure<Statement> procedure) {
3308                 forSingleStatement(subject, relation,
3309                                 new NoneToAsyncProcedure<Statement>(procedure));
3310         }
3311
3312         @Override
3313         public void forSingleType(Resource subject,
3314                         AsyncListener<Resource> listener) {
3315                 asyncRequest(new SingleTypeAny(subject), listener);
3316         }
3317
3318         @Override
3319         public void forSingleType(Resource subject,
3320                         SyncListener<Resource> listener) {
3321                 asyncRequest(new SingleTypeAny(subject), listener);
3322         }
3323
3324         @Override
3325         public void forSingleType(Resource subject,
3326                         Listener<Resource> listener) {
3327                 asyncRequest(new SingleTypeAny(subject), listener);
3328         }
3329
3330         @Override
3331         final public void forSingleType(final Resource subject, final AsyncProcedure<Resource> procedure) {
3332
3333                 assert (subject != null);
3334                 assert (procedure != null);
3335
3336                 final DeepSingleOrErrorProcedure<Resource> checkedProcedure = new DeepSingleOrErrorProcedure<Resource>(procedure);
3337
3338                 processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter<Resource>() {
3339
3340                         @Override
3341                         public void execute(AsyncReadGraph graph, final Resource principalType) {
3342                                 checkedProcedure.offer(graph, principalType);
3343                         }
3344
3345                         @Override
3346                         public void finished(AsyncReadGraph graph) {
3347                                 checkedProcedure.dec(graph);
3348                         }
3349
3350                         @Override
3351                         public void exception(AsyncReadGraph graph, Throwable t) {
3352                                 checkedProcedure.exception(graph, t);
3353                         }
3354
3355                         @Override
3356                         public String toString() {
3357                                 return "forSingleType -> " + procedure;
3358                         }
3359
3360                 });
3361
3362         }
3363
3364         @Override
3365         public void forSingleType(Resource subject, SyncProcedure<Resource> procedure) {
3366                 forSingleType(subject, new SyncToAsyncProcedure<Resource>(
3367                                 procedure));
3368         }
3369
3370         @Override
3371         public void forSingleType(Resource subject, Procedure<Resource> procedure) {
3372                 forSingleType(subject, new NoneToAsyncProcedure<Resource>(
3373                                 procedure));
3374         }
3375
3376         @Override
3377         public void forSingleType(Resource subject, Resource relation,
3378                         AsyncListener<Resource> listener) {
3379                 asyncRequest(new SingleType(subject, relation), listener);
3380         }
3381
3382         @Override
3383         public void forSingleType(Resource subject, Resource relation,
3384                         SyncListener<Resource> listener) {
3385                 asyncRequest(new SingleType(subject, relation), listener);
3386         }
3387
3388         @Override
3389         public void forSingleType(Resource subject, Resource relation,
3390                         Listener<Resource> listener) {
3391                 asyncRequest(new SingleType(subject, relation), listener);
3392         }
3393
3394         @Override
3395         final public void forSingleType(final Resource subject,
3396                         final Resource baseType, final AsyncProcedure<Resource> procedure) {
3397
3398                 assert (subject != null);
3399                 assert (procedure != null);
3400
3401                 final DeepSingleOrErrorProcedure<Resource> checkedProcedure = new DeepSingleOrErrorProcedure<Resource>(procedure);
3402
3403                 processor.forEachPrincipalType(this, subject,
3404                                 new AsyncMultiProcedureAdapter<Resource>() {
3405
3406                                         @Override
3407                                         public void execute(AsyncReadGraph graph,
3408                                                         final Resource principalType) {
3409
3410                                                 checkedProcedure.inc();
3411
3412                                                 if(baseType == null) {
3413
3414                                                         checkedProcedure.offer(graph, principalType);
3415                                                         checkedProcedure.dec(graph);
3416
3417                                                 } else if(principalType.equals(baseType)) {
3418
3419                                                         checkedProcedure.offer(graph, principalType);
3420                                                         checkedProcedure.dec(graph);
3421
3422                                                 } else {
3423
3424                                                         processor.forSupertypes((ReadGraphImpl)graph, principalType,
3425                                                                         new AsyncProcedure<Set<Resource>>() {
3426
3427                                                                                 @Override
3428                                                                                 public void execute(
3429                                                                                                 AsyncReadGraph graph,
3430                                                                                                 Set<Resource> result) {
3431
3432                                                                                         if (result.contains(baseType))
3433                                                                                                 checkedProcedure.offer(graph,
3434                                                                                                                 principalType);
3435                                                                                         checkedProcedure.dec(graph);
3436
3437                                                                                 }
3438
3439                                                                                 @Override
3440                                                                                 public void exception(
3441                                                                                                 AsyncReadGraph graph,
3442                                                                                                 Throwable t) {
3443                                                                                         checkedProcedure
3444                                                                                                         .exception(graph, t);
3445                                                                                 }
3446
3447                                                                         });
3448
3449                                                 }
3450
3451                                         }
3452
3453                                         @Override
3454                                         public void finished(AsyncReadGraph graph) {
3455                                                 checkedProcedure.dec(graph);
3456                                         }
3457
3458                                         @Override
3459                                         public void exception(AsyncReadGraph graph, Throwable t) {
3460                                                 checkedProcedure.exception(graph, t);
3461                                         }
3462
3463                                         @Override
3464                                         public String toString() {
3465                                                 return "forSingleType -> " + procedure;
3466                                         }
3467
3468                                 });
3469
3470         }
3471
3472         @Override
3473         public void forSingleType(Resource subject, Resource relation,
3474                         SyncProcedure<Resource> procedure) {
3475                 forSingleType(subject, relation, new SyncToAsyncProcedure<Resource>(
3476                                 procedure));
3477         }
3478
3479         @Override
3480         public void forSingleType(Resource subject, Resource relation,
3481                         Procedure<Resource> procedure) {
3482                 forSingleType(subject, relation, new NoneToAsyncProcedure<Resource>(
3483                                 procedure));
3484         }
3485
3486         @Override
3487         public <T> void forValue(Resource subject, Binding binding,
3488                         AsyncListener<T> listener) {
3489                 asyncRequest(new Value<T>(subject, binding), listener);
3490         }
3491
3492         @Override
3493         public <T> void forValue(Resource subject, Binding binding,
3494                         SyncListener<T> listener) {
3495                 asyncRequest(new Value<T>(subject, binding), listener);
3496         }
3497
3498         @Override
3499         public <T> void forValue(Resource subject, Binding binding,
3500                         Listener<T> listener) {
3501                 asyncRequest(new Value<T>(subject, binding), listener);
3502         }
3503
3504         @Override
3505         public <T> void forValue(final Resource resource, final Binding binding,
3506                         final AsyncProcedure<T> procedure) {
3507
3508                 assert (resource != null);
3509                 assert (binding != null);
3510                 assert (procedure != null);
3511                 
3512                 processor.forValue(this, resource, new AsyncProcedure<byte[]>() {
3513
3514                         @Override
3515                         public void execute(AsyncReadGraph graph, byte[] result) {
3516                                 
3517                                 try {
3518
3519                                         if (result == null) {
3520                                                 procedure.exception(graph,
3521                                                                 new DoesNotContainValueException(
3522                                                                                 "No value for resource " + resource));
3523                                                 return;
3524                                         }
3525
3526                                         Serializer serializer = binding.serializer();
3527 //                                      Serializer serializer = Bindings.getSerializer( binding );
3528                                         Object obj = serializer.deserialize(result);
3529 //                                      if (!binding.isInstance(obj))
3530 //                                              procedure.exception(graph, new ClassCastException(
3531 //                                                              "Cannot get value " + obj + " with binding "
3532 //                                                                              + binding));
3533 //                                      else
3534                                                 procedure.execute(graph, (T) obj);
3535
3536                                 } catch (Throwable t) {
3537                                     procedure.exception(graph, new ServiceException("Could not forValue for subject " + debugString(resource) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(result), t));
3538                                 }
3539                         }
3540
3541                         @Override
3542                         public void exception(AsyncReadGraph graph, Throwable t) {
3543                                 try {
3544                                         procedure.exception(graph, t);
3545                                 } catch (Throwable t2) {
3546                                 Logger.defaultLogError(t2);
3547                                 }
3548                         }
3549
3550                         @Override
3551                         public String toString() {
3552                                 return "forValue -> " + procedure;
3553                         }
3554
3555                 });
3556
3557         }
3558         
3559     private static String safeArrayToString(byte[] a) {
3560         if (a == null)
3561             return "null";
3562         int iMax = a.length - 1;
3563         if (iMax == -1)
3564             return "[]";
3565
3566         StringBuilder b = new StringBuilder();
3567         b.append('[');
3568         for (int i = 0; i < 100; i++) { // limit to first 100 items 
3569             b.append(a[i]);
3570             if (i == iMax)
3571                 return b.append(']').toString();
3572             b.append(", ");
3573         }
3574         return b.append(", ... (" + a.length + ")]").toString();
3575     }
3576
3577         @Override
3578         public <T> void forValue(Resource subject, Binding binding,
3579                         SyncProcedure<T> procedure) {
3580                 forValue(subject, binding, new SyncToAsyncProcedure<T>(procedure));
3581         }
3582
3583         @Override
3584         public <T> void forValue(Resource subject, Binding binding,
3585                         Procedure<T> procedure) {
3586                 forValue(subject, binding, new NoneToAsyncProcedure<T>(procedure));
3587         }
3588
3589         @Override
3590         public <T> void forValue(Resource subject, AsyncListener<T> listener) {
3591                 asyncRequest(new ValueImplied<T>(subject), listener);
3592         }
3593
3594         @Override
3595         public <T> void forValue(Resource subject, SyncListener<T> listener) {
3596                 asyncRequest(new ValueImplied<T>(subject), listener);
3597         }
3598
3599         @Override
3600         public <T> void forValue(Resource subject, Listener<T> listener) {
3601                 asyncRequest(new ValueImplied<T>(subject), listener);
3602         }
3603
3604         @Override
3605         final public <T> void forValue(final Resource subject, final AsyncProcedure<T> procedure) {
3606
3607                 assert (subject != null);
3608                 assert (procedure != null);
3609                 
3610                 forRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure<Datatype>() {
3611
3612                         @Override
3613                         public void execute(AsyncReadGraph graph, Datatype type) {
3614                                 // TODO: consider trying Bindings.getBeanBinding(type);
3615                                 Binding binding = Bindings.getBinding(type);
3616                                 graph.forValue(subject, binding, procedure);
3617                         }
3618
3619                         @Override
3620                         public void exception(AsyncReadGraph graph, Throwable throwable) {
3621                                 procedure.exception(graph, new DoesNotContainValueException("Invalid data type", throwable));
3622                         }
3623                         
3624                 });
3625
3626         }
3627
3628         @Override
3629         public <T> void forValue(Resource subject, SyncProcedure<T> procedure) {
3630                 forValue(subject, new SyncToAsyncProcedure<T>(procedure));
3631         }
3632
3633         @Override
3634         public <T> void forValue(Resource subject, Procedure<T> procedure) {
3635                 forValue(subject, new NoneToAsyncProcedure<T>(procedure));
3636         }
3637
3638         @Override
3639         public <T> void forRelatedValue(Resource subject, Resource relation,
3640                         AsyncListener<T> listener) {
3641                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3642         }
3643
3644         @Override
3645         public <T> void forRelatedValue(Resource subject, Resource relation,
3646                         SyncListener<T> listener) {
3647                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3648         }
3649
3650         @Override
3651         public <T> void forRelatedValue(Resource subject, Resource relation,
3652                         Listener<T> listener) {
3653                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3654         }
3655
3656         @Override
3657         final public <T> void forRelatedValue(final Resource subject,
3658                         final Resource relation, final AsyncProcedure<T> procedure) {
3659
3660                 assert (subject != null);
3661                 assert (relation != null);
3662                 assert (procedure != null);
3663
3664                 final DeepSingleOrErrorProcedure<T> checkedProcedure = new DeepSingleOrErrorProcedure<T>(procedure);
3665
3666                 processor.forEachObject(this, subject, relation,
3667                                 new AsyncMultiProcedureAdapter<Resource>() {
3668
3669                                         @Override
3670                                         public void execute(AsyncReadGraph graph,
3671                                                         final Resource object) {
3672
3673                                                 checkedProcedure.inc();
3674
3675                                                 graph.forValue(object, new AsyncProcedure<Object>() {
3676
3677                                                         @Override
3678                                                         public void execute(AsyncReadGraph graph,
3679                                                                         Object result) {
3680                                                                 checkedProcedure.offer(graph, (T) result);
3681                                                                 checkedProcedure.dec(graph);
3682                                                         }
3683
3684                                                         @Override
3685                                                         public void exception(AsyncReadGraph graph,
3686                                                                         Throwable t) {
3687                                                                 checkedProcedure.exception(graph, t);
3688                                                         }
3689
3690                                                         @Override
3691                                                         public String toString() {
3692                                                                 return "forRelatedValue -> " + procedure;
3693                                                         }
3694
3695                                                 });
3696
3697                                         }
3698
3699                                         @Override
3700                                         public void finished(AsyncReadGraph graph) {
3701                                                 checkedProcedure.dec(graph);
3702                                         }
3703
3704                                         @Override
3705                                         public void exception(AsyncReadGraph graph, Throwable t) {
3706                                                 checkedProcedure.exception(graph, t);
3707                                         }
3708
3709                                 });
3710
3711         }
3712
3713         @Override
3714         public <T> void forRelatedValue(Resource subject, Resource relation,
3715                         SyncProcedure<T> procedure) {
3716                 forRelatedValue(subject, relation, new SyncToAsyncProcedure<T>(
3717                                 procedure));
3718         }
3719
3720         @Override
3721         public <T> void forRelatedValue(Resource subject, Resource relation,
3722                         Procedure<T> procedure) {
3723                 forRelatedValue(subject, relation, new NoneToAsyncProcedure<T>(
3724                                 procedure));
3725         }
3726
3727         @Override
3728         public <T> void forRelatedValue(Resource subject, Resource relation,
3729                         Binding binding, AsyncListener<T> listener) {
3730                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3731         }
3732
3733         @Override
3734         public <T> void forRelatedValue(Resource subject, Resource relation,
3735                         Binding binding, SyncListener<T> listener) {
3736                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3737         }
3738
3739         @Override
3740         public <T> void forRelatedValue(Resource subject, Resource relation,
3741                         Binding binding, Listener<T> listener) {
3742                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3743         }
3744
3745         @Override
3746         final public <T> void forRelatedValue(final Resource subject,
3747                         final Resource relation, final Binding binding,
3748                         final AsyncProcedure<T> procedure) {
3749
3750                 assert (subject != null);
3751                 assert (relation != null);
3752                 assert (binding != null);
3753                 assert (procedure != null);
3754
3755                 final DeepSingleOrErrorProcedure<T> checkedProcedure = new DeepSingleOrErrorProcedure<T>(procedure);
3756                 
3757                 processor.forEachObject(this, subject, relation,
3758                                 new AsyncMultiProcedureAdapter<Resource>() {
3759
3760                                         @Override
3761                                         public void execute(AsyncReadGraph graph,
3762                                                         final Resource object) {
3763
3764                                                 checkedProcedure.inc();
3765
3766                                                 graph.forValue(object, binding, new AsyncProcedure<Object>() {
3767
3768                                                                         @Override
3769                                                                         public void execute(AsyncReadGraph graph,
3770                                                                                         Object result) {
3771                                                                                 
3772                                                                                 checkedProcedure.offer(graph,
3773                                                                                                 (T) result);
3774                                                                                 checkedProcedure.dec(graph);
3775                                                                         }
3776
3777                                                                         @Override
3778                                                                         public void exception(AsyncReadGraph graph,
3779                                                                                         Throwable t) {
3780                                                                                 checkedProcedure.exception(graph, t);
3781                                                                         }
3782
3783                                                                         @Override
3784                                                                         public String toString() {
3785                                                                                 return "forRelatedValue -> "
3786                                                                                                 + procedure;
3787                                                                         }
3788
3789                                                                 });
3790
3791                                         }
3792
3793                                         @Override
3794                                         public void finished(AsyncReadGraph graph) {
3795                                                 checkedProcedure.dec(graph);
3796                                         }
3797
3798                                         @Override
3799                                         public void exception(AsyncReadGraph graph, Throwable t) {
3800                                                 checkedProcedure.exception(graph, t);
3801                                         }
3802
3803                                 });
3804
3805         }
3806
3807         @Override
3808         public <T> void forRelatedValue(Resource subject, Resource relation,
3809                         Binding binding, SyncProcedure<T> procedure) {
3810                 forRelatedValue(subject, relation, binding,
3811                                 new SyncToAsyncProcedure<T>(procedure));
3812         }
3813
3814         @Override
3815         public <T> void forRelatedValue(Resource subject, Resource relation,
3816                         Binding binding, Procedure<T> procedure) {
3817                 forRelatedValue(subject, relation, binding,
3818                                 new NoneToAsyncProcedure<T>(procedure));
3819         }
3820
3821         @Override
3822         public <T> void forAdapted(Resource resource, Class<T> clazz,
3823                         AsyncListener<T> listener) {
3824                 asyncRequest(new Adapter<T>(resource, clazz), listener);
3825         }
3826
3827         @Override
3828         public <T> void forAdapted(Resource resource, Class<T> clazz,
3829                         SyncListener<T> listener) {
3830                 asyncRequest(new Adapter<T>(resource, clazz), listener);
3831         }
3832
3833         @Override
3834         public <T> void forAdapted(Resource resource, Class<T> clazz,
3835                         Listener<T> listener) {
3836                 asyncRequest(new Adapter<T>(resource, clazz), listener);
3837         }
3838
3839         @Override
3840         final public <T> void forAdapted(final Resource resource,
3841                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
3842
3843                 assert (resource != null);
3844                 assert (clazz != null);
3845                 assert (procedure != null);
3846
3847                 final AdaptionService service = getSession().peekService(AdaptionService.class);
3848                 if (service == null)
3849                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
3850                 else
3851                         service.adapt(this, resource, resource, Resource.class, clazz, false, procedure); 
3852
3853         }
3854
3855         @Override
3856         public <T> void forAdapted(Resource resource, Class<T> clazz,
3857                         SyncProcedure<T> procedure) {
3858                 forAdapted(resource, clazz, new SyncToAsyncProcedure<T>(procedure));
3859         }
3860
3861         @Override
3862         public <T> void forAdapted(Resource resource, Class<T> clazz,
3863                         Procedure<T> procedure) {
3864                 forAdapted(resource, clazz, new NoneToAsyncProcedure<T>(procedure));
3865         }
3866
3867         @Override
3868         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3869                         AsyncListener<T> listener) {
3870                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
3871         }
3872
3873         @Override
3874         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3875                         SyncListener<T> listener) {
3876                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
3877         }
3878
3879         @Override
3880         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3881                         Listener<T> listener) {
3882                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
3883         }
3884
3885         @Override
3886         final public <T> void forUniqueAdapted(final Resource resource,
3887                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
3888
3889                 assert (resource != null);
3890                 assert (clazz != null);
3891                 assert (procedure != null);
3892
3893                 final AdaptionService service = getSession().peekService(AdaptionService.class);
3894                 if (service == null)
3895                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
3896                 else
3897                         service.adaptNew(this, resource, clazz, false, procedure);
3898
3899         }
3900
3901         @Override
3902         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3903                         SyncProcedure<T> procedure) {
3904                 forUniqueAdapted(resource, clazz,
3905                                 new SyncToAsyncProcedure<T>(procedure));
3906         }
3907
3908         @Override
3909         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3910                         Procedure<T> procedure) {
3911                 forUniqueAdapted(resource, clazz,
3912                                 new NoneToAsyncProcedure<T>(procedure));
3913         }
3914
3915         @Override
3916         public void forPossibleInverse(Resource subject,
3917                         AsyncListener<Resource> listener) {
3918                 asyncRequest(new PossibleInverse(subject), listener);
3919         }
3920
3921         @Override
3922         public void forPossibleInverse(Resource subject,
3923                         SyncListener<Resource> listener) {
3924                 asyncRequest(new PossibleInverse(subject), listener);
3925         }
3926
3927         @Override
3928         public void forPossibleInverse(Resource subject, Listener<Resource> listener) {
3929                 asyncRequest(new PossibleInverse(subject), listener);
3930         }
3931
3932         @Override
3933         final public void forPossibleInverse(final Resource relation,
3934                         final AsyncProcedure<Resource> procedure) {
3935
3936                 assert (relation != null);
3937                 assert (procedure != null);
3938
3939                 processor.forInverse(this, relation, new ExceptionToNullProcedure<Resource>(procedure));
3940
3941         }
3942
3943         @Override
3944         public void forPossibleInverse(Resource subject,
3945                         SyncProcedure<Resource> procedure) {
3946                 forPossibleInverse(subject, new SyncToAsyncProcedure<Resource>(
3947                                 procedure));
3948         }
3949
3950         @Override
3951         public void forPossibleInverse(Resource subject,
3952                         Procedure<Resource> procedure) {
3953                 forPossibleInverse(subject, new NoneToAsyncProcedure<Resource>(
3954                                 procedure));
3955         }
3956
3957         @Override
3958         public void forPossibleObject(Resource subject, Resource relation,
3959                         AsyncListener<Resource> listener) {
3960                 asyncRequest(new PossibleObject(subject, relation), listener);
3961         }
3962
3963         @Override
3964         public void forPossibleObject(Resource subject, Resource relation,
3965                         SyncListener<Resource> listener) {
3966                 asyncRequest(new PossibleObject(subject, relation), listener);
3967         }
3968
3969         @Override
3970         public void forPossibleObject(Resource subject, Resource relation,
3971                         Listener<Resource> listener) {
3972                 asyncRequest(new PossibleObject(subject, relation), listener);
3973         }
3974
3975         @Override
3976         final public void forPossibleObject(final Resource subject,
3977                         final Resource relation, final AsyncProcedure<Resource> procedure) {
3978
3979                 assert (subject != null);
3980                 assert (relation != null);
3981                 assert (procedure != null);
3982
3983                 processor.forEachObject(this, subject, relation,
3984                                 new SingleOrNullProcedure<Resource>(procedure));
3985
3986         }
3987
3988         @Override
3989         public void forPossibleObject(Resource subject, Resource relation,
3990                         SyncProcedure<Resource> procedure) {
3991                 forPossibleObject(subject, relation,
3992                                 new SyncToAsyncProcedure<Resource>(procedure));
3993         }
3994
3995         @Override
3996         public void forPossibleObject(Resource subject, Resource relation,
3997                         Procedure<Resource> procedure) {
3998                 forPossibleObject(subject, relation,
3999                                 new NoneToAsyncProcedure<Resource>(procedure));
4000         }
4001
4002         @Override
4003         public void forPossibleStatement(Resource subject, Resource relation,
4004                         AsyncListener<Statement> listener) {
4005                 asyncRequest(new PossibleStatement(subject, relation), listener);
4006         }
4007
4008         @Override
4009         public void forPossibleStatement(Resource subject, Resource relation,
4010                         SyncListener<Statement> listener) {
4011                 asyncRequest(new PossibleStatement(subject, relation), listener);
4012         }
4013
4014         @Override
4015         public void forPossibleStatement(Resource subject, Resource relation,
4016                         Listener<Statement> listener) {
4017                 asyncRequest(new PossibleStatement(subject, relation), listener);
4018         }
4019
4020         @Override
4021         final public void forPossibleStatement(final Resource subject,
4022                         final Resource relation, final AsyncProcedure<Statement> procedure) {
4023
4024                 assert (subject != null);
4025                 assert (relation != null);
4026                 assert (procedure != null);
4027
4028                 processor.forEachStatement(this, subject, relation,
4029                                 new SingleFunctionalOrNullProcedure<Statement>(
4030                                                 "forPossibleStatement", procedure));
4031
4032         }
4033
4034         @Override
4035         public void forPossibleStatement(Resource subject, Resource relation,
4036                         SyncProcedure<Statement> procedure) {
4037                 forPossibleStatement(subject, relation,
4038                                 new SyncToAsyncProcedure<Statement>(procedure));
4039         }
4040
4041         @Override
4042         public void forPossibleStatement(Resource subject, Resource relation,
4043                         Procedure<Statement> procedure) {
4044                 forPossibleStatement(subject, relation,
4045                                 new NoneToAsyncProcedure<Statement>(procedure));
4046         }
4047
4048         @Override
4049         public void forPossibleType(Resource subject, Resource relation,
4050                         AsyncListener<Resource> listener) {
4051                 asyncRequest(new PossibleType(subject, relation), listener);
4052         }
4053
4054         @Override
4055         public void forPossibleType(Resource subject, Resource relation,
4056                         SyncListener<Resource> listener) {
4057                 asyncRequest(new PossibleType(subject, relation), listener);
4058         }
4059
4060         @Override
4061         public void forPossibleType(Resource subject, Resource relation,
4062                         Listener<Resource> listener) {
4063                 asyncRequest(new PossibleType(subject, relation), listener);
4064         }
4065
4066         @Override
4067         final public void forPossibleType(final Resource subject,
4068                         final Resource baseType, final AsyncProcedure<Resource> procedure) {
4069
4070                 assert (subject != null);
4071                 assert (procedure != null);
4072
4073                 final NullSingleOrNullProcedure<Resource> checkedProcedure = new NullSingleOrNullProcedure<Resource>(procedure);
4074
4075                 processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter<Resource>() {
4076
4077                                         @Override
4078                                         public void execute(AsyncReadGraph graph,
4079                                                         final Resource principalType) {
4080
4081                                                 if (baseType == null) {
4082
4083                                                         checkedProcedure.offer(graph, principalType);
4084
4085                                                 } else if (principalType.equals(baseType)) {
4086
4087                                                         checkedProcedure.offer(graph, principalType);
4088
4089                                                 } else {
4090
4091                                                         checkedProcedure.inc();
4092
4093                                                         processor.forSupertypes((ReadGraphImpl)graph, principalType,
4094                                                                         new AsyncProcedure<Set<Resource>>() {
4095
4096                                                                                 @Override
4097                                                                                 public void execute(
4098                                                                                                 AsyncReadGraph graph,
4099                                                                                                 Set<Resource> result) {
4100
4101                                                                                         if (result.contains(baseType)) {
4102                                                                                                 checkedProcedure.offer(graph,
4103                                                                                                                 principalType);
4104                                                                                         }
4105
4106                                                                                         checkedProcedure.dec(graph);
4107
4108                                                                                 }
4109
4110                                                                                 @Override
4111                                                                                 public void exception(
4112                                                                                                 AsyncReadGraph graph,
4113                                                                                                 Throwable t) {
4114                                                                                         checkedProcedure.exception(graph, t);
4115                                                                                         checkedProcedure.dec(graph);
4116                                                                                 }
4117
4118                                                                                 @Override
4119                                                                                 public String toString() {
4120                                                                                         return "forPossibleType -> "
4121                                                                                                         + procedure;
4122                                                                                 }
4123
4124                                                                         });
4125
4126                                                 }
4127
4128                                         }
4129
4130                                         @Override
4131                                         public void finished(AsyncReadGraph graph) {
4132                                                 checkedProcedure.dec(graph);
4133                                         }
4134
4135                                         @Override
4136                                         public void exception(AsyncReadGraph graph, Throwable t) {
4137                                                 checkedProcedure.exception(graph, t);
4138                                                 checkedProcedure.dec(graph);
4139                                         }
4140
4141                                 });
4142
4143         }
4144
4145         @Override
4146         public void forPossibleType(Resource subject, Resource relation,
4147                         SyncProcedure<Resource> procedure) {
4148                 forPossibleType(subject, relation, new SyncToAsyncProcedure<Resource>(
4149                                 procedure));
4150         }
4151
4152         @Override
4153         public void forPossibleType(Resource subject, Resource relation,
4154                         Procedure<Resource> procedure) {
4155                 forPossibleType(subject, relation, new NoneToAsyncProcedure<Resource>(
4156                                 procedure));
4157         }
4158
4159         @Override
4160         public <T> void forPossibleValue(Resource subject, AsyncListener<T> listener) {
4161                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4162         }
4163
4164         @Override
4165         public <T> void forPossibleValue(Resource subject, SyncListener<T> listener) {
4166                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4167         }
4168
4169         @Override
4170         public <T> void forPossibleValue(Resource subject, Listener<T> listener) {
4171                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4172         }
4173
4174         @Override
4175         final public <T> void forPossibleValue(final Resource subject,
4176                         final AsyncProcedure<T> procedure) {
4177
4178                 assert (subject != null);
4179                 assert (procedure != null);
4180                 
4181                 forPossibleRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure<Datatype>() {
4182
4183                         @Override
4184                         public void execute(AsyncReadGraph graph, final Datatype type) {
4185                                 if (type == null) {
4186                                         procedure.execute(graph, null);
4187                                 } else {
4188                                         try {
4189                                                 // TODO: consider trying Bindings.getBeanBinding(type);
4190                                                 Binding binding = Bindings.getBinding(type);
4191                                                 graph.forPossibleValue(subject, binding, procedure);
4192                                         } catch (RuntimeBindingConstructionException e) {
4193                                                 procedure.exception(graph, e);
4194                                         }
4195                                 }
4196                         }
4197
4198                         @Override
4199                         public void exception(AsyncReadGraph graph, Throwable t) {
4200                                 procedure.exception(graph, t);
4201                         }
4202
4203                         @Override
4204                         public String toString() {
4205                                 return "forPossibleValue -> " + procedure;
4206                         }
4207
4208                 });
4209
4210         }
4211
4212         @Override
4213         public <T> void forPossibleValue(Resource subject,
4214                         SyncProcedure<T> procedure) {
4215                 forPossibleValue(subject, new SyncToAsyncProcedure<T>(procedure));
4216         }
4217
4218         @Override
4219         public <T> void forPossibleValue(Resource subject, Procedure<T> procedure) {
4220                 forPossibleValue(subject, new NoneToAsyncProcedure<T>(procedure));
4221         }
4222
4223         @Override
4224         public <T> void forPossibleValue(Resource subject, Binding binding,
4225                         AsyncListener<T> listener) {
4226                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4227         }
4228
4229         @Override
4230         public <T> void forPossibleValue(Resource subject, Binding binding,
4231                         SyncListener<T> listener) {
4232                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4233         }
4234
4235         @Override
4236         public <T> void forPossibleValue(Resource subject, Binding binding,
4237                         Listener<T> listener) {
4238                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4239         }
4240
4241         @Override
4242         final public <T> void forPossibleValue(final Resource resource,
4243                         final Binding binding, final AsyncProcedure<T> procedure) {
4244
4245                 assert (resource != null);
4246                 assert (binding != null);
4247                 assert (procedure != null);
4248
4249                 processor.forValue(this, resource, new AsyncProcedure<byte[]>() {
4250
4251                         @Override
4252                         public void execute(AsyncReadGraph graph, byte[] result) {
4253
4254                                 try {
4255
4256                                         if (result == null) {
4257                                                 procedure.execute(graph, null);
4258                                                 return;
4259                                         }
4260
4261                                         Serializer serializer = Bindings.getSerializer( binding );
4262                                         Object obj = serializer.deserialize(result);
4263                                         if (!binding.isInstance(obj))
4264                                                 procedure.exception(graph, new ClassCastException(
4265                                                                 "Cannot get value " + obj + " with binding "
4266                                                                                 + binding));
4267                                         else
4268                                                 procedure.execute(graph, (T) obj);
4269
4270                                 } catch (Throwable t) {
4271                                         procedure.exception(graph, new ServiceException("Could not forValue for subject " + debugString(resource) + " and binding " + String.valueOf(binding) + " with bytes " + safeArrayToString(result), t));
4272                                 }
4273                         }
4274
4275                         @Override
4276                         public void exception(AsyncReadGraph graph, Throwable t) {
4277                                 try {
4278                                         procedure.exception(graph, t);
4279                                 } catch (Throwable t2) {
4280                                 Logger.defaultLogError(t2);
4281                                 }
4282                         }
4283
4284                         @Override
4285                         public String toString() {
4286                                 return "forPossibleValue -> " + procedure;
4287                         }
4288
4289                 });
4290
4291         }
4292
4293         @Override
4294         public <T> void forPossibleValue(Resource subject, Binding binding,
4295                         SyncProcedure<T> procedure) {
4296                 forPossibleValue(subject, binding, new SyncToAsyncProcedure<T>(
4297                                 procedure));
4298         }
4299
4300         @Override
4301         public <T> void forPossibleValue(Resource subject, Binding binding,
4302                         Procedure<T> procedure) {
4303                 forPossibleValue(subject, binding, new NoneToAsyncProcedure<T>(
4304                                 procedure));
4305         }
4306
4307         @Override
4308         public <T> void forPossibleRelatedValue(Resource subject,
4309                         Resource relation, AsyncListener<T> listener) {
4310                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4311                                 listener);
4312         }
4313
4314         @Override
4315         public <T> void forPossibleRelatedValue(Resource subject,
4316                         Resource relation, SyncListener<T> listener) {
4317                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4318                                 listener);
4319         }
4320
4321         @Override
4322         public <T> void forPossibleRelatedValue(Resource subject,
4323                         Resource relation, Listener<T> listener) {
4324                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4325                                 listener);
4326         }
4327
4328         @Override
4329         final public <T> void forPossibleRelatedValue(final Resource subject,
4330                         final Resource relation, final AsyncProcedure<T> procedure) {
4331
4332                 assert (subject != null);
4333                 assert (relation != null);
4334                 assert (procedure != null);
4335
4336                 final DeepSingleOrNullProcedure<T> checkedProcedure = new DeepSingleOrNullProcedure<T>(procedure);
4337                 
4338                 processor.forEachObject(this, subject, relation,
4339                                 new AsyncMultiProcedureAdapter<Resource>() {
4340
4341                                         @Override
4342                                         public void execute(AsyncReadGraph graph,
4343                                                         final Resource object) {
4344
4345                                                 checkedProcedure.inc();
4346
4347                                                 graph.forValue(object, new AsyncProcedure<Object>() {
4348
4349                                                         @Override
4350                                                         public void execute(AsyncReadGraph graph,
4351                                                                         Object result) {
4352                                                                 checkedProcedure.offer(graph, (T) result);
4353                                                                 checkedProcedure.dec(graph);
4354                                                         }
4355
4356                                                         @Override
4357                                                         public void exception(AsyncReadGraph graph,
4358                                                                         Throwable t) {
4359                                                                 checkedProcedure.exception(graph, t);
4360                                                                 checkedProcedure.dec(graph);
4361                                                         }
4362
4363                                                 });
4364
4365                                         }
4366
4367                                         @Override
4368                                         public void finished(AsyncReadGraph graph) {
4369
4370                                                 checkedProcedure.dec(graph);
4371                                         }
4372
4373                                         @Override
4374                                         public void exception(AsyncReadGraph graph, Throwable t) {
4375                                                 checkedProcedure.exception(graph, t);
4376                                                 checkedProcedure.dec(graph);
4377                                         }
4378
4379                                         @Override
4380                                         public String toString() {
4381                                                 return "forPossibleRelatedValue -> " + procedure;
4382                                         }
4383                                 });
4384
4385         }
4386
4387         @Override
4388         public <T> void forPossibleRelatedValue(Resource subject,
4389                         Resource relation, SyncProcedure<T> procedure) {
4390                 forPossibleRelatedValue(subject, relation, new SyncToAsyncProcedure<T>(
4391                                 procedure));
4392         }
4393
4394         @Override
4395         public <T> void forPossibleRelatedValue(Resource subject,
4396                         Resource relation, Procedure<T> procedure) {
4397                 forPossibleRelatedValue(subject, relation, new NoneToAsyncProcedure<T>(
4398                                 procedure));
4399         }
4400
4401         @Override
4402         public <T> void forPossibleRelatedValue(Resource subject,
4403                         Resource relation, Binding binding, AsyncListener<T> listener) {
4404                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4405                                 listener);
4406         }
4407
4408         @Override
4409         public <T> void forPossibleRelatedValue(Resource subject,
4410                         Resource relation, Binding binding, SyncListener<T> listener) {
4411                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4412                                 listener);
4413         }
4414
4415         @Override
4416         public <T> void forPossibleRelatedValue(Resource subject,
4417                         Resource relation, Binding binding, Listener<T> listener) {
4418                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4419                                 listener);
4420         }
4421
4422         final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
4423                         final AsyncProcedure<T> procedure) {
4424
4425                 assert (subject != null);
4426                 assert (relation != null);
4427                 assert (procedure != null);
4428
4429                 processor.forPossibleObject(this, subject, relation, new AsyncProcedure<Resource>() {
4430                         
4431                         @Override
4432                         public void execute(AsyncReadGraph graph, Resource object) {
4433                                 
4434                                 if(object == null) {
4435                                         procedure.execute(graph, null);
4436                                         return;
4437                                 }
4438
4439                                 processor.forPossibleValue((ReadGraphImpl)graph, object, new AsyncProcedure<byte[]>() {
4440
4441                                         @Override
4442                                         public void execute(AsyncReadGraph graph, byte[] bytes) {
4443
4444                                                 if(bytes != null) {
4445
4446                                                         try {
4447                                                         
4448                                                                 Serializer serializer = binding.serializer();
4449                                                                 Object obj = serializer.deserialize(bytes);
4450                                                                 if (!binding.isInstance(obj)) {
4451                                                                         procedure.exception(graph, new ClassCastException("Cannot get value " + obj + " with binding " + binding));
4452                                                                 } else {
4453                                                                         procedure.execute(graph, (T) obj);
4454                                                                 }
4455
4456                                                         } catch (Throwable t) {
4457                                                                 
4458                                                                 procedure.exception(graph, t);
4459                                                                 
4460                                                         }
4461                                                         
4462                                                 } else {
4463                                                         
4464                                                         procedure.execute(graph, null);
4465                                                         
4466                                                 }
4467                                                 
4468                                         }
4469
4470                                         @Override
4471                                         public void exception(AsyncReadGraph graph, Throwable t) {
4472                                                 procedure.exception(graph, t);
4473                                         }
4474
4475                                 });
4476                                 
4477                         }
4478                         
4479                         @Override
4480                         public void exception(AsyncReadGraph graph, Throwable throwable) {
4481                                 throwable.printStackTrace();
4482                                 procedure.exception(graph, throwable);
4483                         }
4484                         
4485                 });
4486
4487         }
4488
4489         @Override
4490         public <T> void forPossibleRelatedValue(Resource subject,
4491                         Resource relation, Binding binding, SyncProcedure<T> procedure) {
4492                 forPossibleRelatedValue(subject, relation, binding,
4493                                 new SyncToAsyncProcedure<T>(procedure));
4494         }
4495
4496         @Override
4497         public <T> void forPossibleRelatedValue(Resource subject,
4498                         Resource relation, Binding binding, Procedure<T> procedure) {
4499                 forPossibleRelatedValue(subject, relation, binding,
4500                                 new NoneToAsyncProcedure<T>(procedure));
4501         }
4502
4503         @Override
4504         public void forIsInstanceOf(Resource subject, Resource relation,
4505                         AsyncListener<Boolean> listener) {
4506                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4507         }
4508
4509         @Override
4510         public void forIsInstanceOf(Resource subject, Resource relation,
4511                         SyncListener<Boolean> listener) {
4512                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4513         }
4514
4515         @Override
4516         public void forIsInstanceOf(Resource subject, Resource relation,
4517                         Listener<Boolean> listener) {
4518                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4519         }
4520
4521         @Override
4522         final public void forIsInstanceOf(final Resource resource,
4523                         final Resource type, final AsyncProcedure<Boolean> procedure) {
4524
4525                 assert (resource != null);
4526                 assert (type != null);
4527                 assert (procedure != null);
4528
4529                 forTypes(resource, new AsyncProcedure<Set<Resource>>() {
4530
4531                         @Override
4532                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4533                                 
4534                                 try {
4535                                         if (result.contains(type))
4536                                                 procedure.execute(graph, true);
4537                                         else
4538                                                 procedure.execute(graph, false);
4539                                 } catch (Throwable t) {
4540                                 Logger.defaultLogError(t);
4541                                 }
4542                         }
4543
4544                         @Override
4545                         public void exception(AsyncReadGraph graph, Throwable t) {
4546                                 try {
4547                                         procedure.exception(graph, t);
4548                                 } catch (Throwable t2) {
4549                                 Logger.defaultLogError(t2);
4550                                 }
4551                         }
4552
4553                         @Override
4554                         public String toString() {
4555                                 return "forIsInstanceOf -> " + procedure;
4556                         }
4557
4558                 });
4559
4560         }
4561
4562         @Override
4563         public void forIsInstanceOf(Resource subject, Resource relation,
4564                         SyncProcedure<Boolean> procedure) {
4565                 forIsInstanceOf(subject, relation, new SyncToAsyncProcedure<Boolean>(
4566                                 procedure));
4567         }
4568
4569         @Override
4570         public void forIsInstanceOf(Resource subject, Resource relation,
4571                         Procedure<Boolean> procedure) {
4572                 forIsInstanceOf(subject, relation, new NoneToAsyncProcedure<Boolean>(
4573                                 procedure));
4574         }
4575
4576         @Override
4577         public void forIsInheritedFrom(Resource subject, Resource relation,
4578                         AsyncListener<Boolean> listener) {
4579                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4580         }
4581
4582         @Override
4583         public void forIsInheritedFrom(Resource subject, Resource relation,
4584                         SyncListener<Boolean> listener) {
4585                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4586         }
4587
4588         @Override
4589         public void forIsInheritedFrom(Resource subject, Resource relation,
4590                         Listener<Boolean> listener) {
4591                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4592         }
4593
4594         @Override
4595         final public void forIsInheritedFrom(final Resource resource,
4596                         final Resource type, final AsyncProcedure<Boolean> procedure) {
4597
4598                 assert (resource != null);
4599                 assert (type != null);
4600                 assert (procedure != null);
4601
4602                 if (resource.equals(type)) {
4603                         try {
4604                                 procedure.execute(this, true);
4605                         } catch (Throwable t) {
4606                         Logger.defaultLogError(t);
4607                         }
4608                         return;
4609                 }
4610
4611                 forSupertypes(resource, new AsyncProcedure<Set<Resource>>() {
4612
4613                         @Override
4614                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4615                                 try {
4616                                         if (result.contains(type))
4617                                                 procedure.execute(graph, true);
4618                                         else
4619                                                 procedure.execute(graph, false);
4620                                 } catch (Throwable t) {
4621                                 Logger.defaultLogError(t);
4622                                 }
4623                         }
4624
4625                         @Override
4626                         public void exception(AsyncReadGraph graph, Throwable t) {
4627                                 try {
4628                                         procedure.exception(graph, t);
4629                                 } catch (Throwable t2) {
4630                                 Logger.defaultLogError(t2);
4631                                 }
4632                         }
4633
4634                         @Override
4635                         public String toString() {
4636                                 return "forIsInheritedFrom -> " + procedure;
4637                         }
4638
4639                 });
4640
4641         }
4642
4643         @Override
4644         public void forIsInheritedFrom(Resource subject, Resource relation,
4645                         SyncProcedure<Boolean> procedure) {
4646                 forIsInheritedFrom(subject, relation,
4647                                 new SyncToAsyncProcedure<Boolean>(procedure));
4648         }
4649
4650         @Override
4651         public void forIsInheritedFrom(Resource subject, Resource relation,
4652                         Procedure<Boolean> procedure) {
4653                 forIsInheritedFrom(subject, relation,
4654                                 new NoneToAsyncProcedure<Boolean>(procedure));
4655         }
4656
4657         @Override
4658         public void forIsSubrelationOf(Resource subject, Resource relation,
4659                         AsyncListener<Boolean> listener) {
4660                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4661         }
4662
4663         @Override
4664         public void forIsSubrelationOf(Resource subject, Resource relation,
4665                         SyncListener<Boolean> listener) {
4666                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4667         }
4668
4669         @Override
4670         public void forIsSubrelationOf(Resource subject, Resource relation,
4671                         Listener<Boolean> listener) {
4672                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4673         }
4674
4675         @Override
4676         final public void forIsSubrelationOf(final Resource resource,
4677                         final Resource relation, final AsyncProcedure<Boolean> procedure) {
4678
4679                 assert (resource != null);
4680                 assert (relation != null);
4681                 assert (procedure != null);
4682
4683                 if (resource.equals(relation)) {
4684                         procedure.execute(this, true);
4685                         return;
4686                 }
4687
4688                 forSuperrelations(resource, new AsyncProcedure<Set<Resource>>() {
4689
4690                         @Override
4691                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4692                                 try {
4693                                         if (result.contains(relation))
4694                                                 procedure.execute(graph, true);
4695                                         else
4696                                                 procedure.execute(graph, false);
4697                                 } catch (Throwable t) {
4698                                 Logger.defaultLogError(t);
4699                                 }
4700                         }
4701
4702                         @Override
4703                         public void exception(AsyncReadGraph graph, Throwable t) {
4704                                 try {
4705                                         procedure.exception(graph, t);
4706                                 } catch (Throwable t2) {
4707                                 Logger.defaultLogError(t2);
4708                                 }
4709                         }
4710
4711                         @Override
4712                         public String toString() {
4713                                 return "forIsSubrelationOf -> " + procedure;
4714                         }
4715
4716                 });
4717
4718         }
4719
4720         @Override
4721         public void forIsSubrelationOf(Resource subject, Resource relation,
4722                         SyncProcedure<Boolean> procedure) {
4723                 forIsSubrelationOf(subject, relation,
4724                                 new SyncToAsyncProcedure<Boolean>(procedure));
4725         }
4726
4727         @Override
4728         public void forIsSubrelationOf(Resource subject, Resource relation,
4729                         Procedure<Boolean> procedure) {
4730                 forIsSubrelationOf(subject, relation,
4731                                 new NoneToAsyncProcedure<Boolean>(procedure));
4732         }
4733
4734         @Override
4735         public void forHasStatement(Resource subject,
4736                         AsyncListener<Boolean> listener) {
4737                 asyncRequest(new HasStatementSubject(subject), listener);
4738         }
4739
4740         @Override
4741         public void forHasStatement(Resource subject, SyncListener<Boolean> listener) {
4742                 asyncRequest(new HasStatementSubject(subject), listener);
4743         }
4744
4745         @Override
4746         public void forHasStatement(Resource subject, Listener<Boolean> listener) {
4747                 asyncRequest(new HasStatementSubject(subject), listener);
4748         }
4749
4750         @Override
4751         final public void forHasStatement(final Resource subject,
4752                         final AsyncProcedure<Boolean> procedure) {
4753
4754                 assert (subject != null);
4755                 assert (procedure != null);
4756
4757                 processor.forHasStatement(this, subject, procedure);
4758
4759         }
4760
4761         @Override
4762         public void forHasStatement(Resource subject,
4763                         SyncProcedure<Boolean> procedure) {
4764                 forHasStatement(subject, new SyncToAsyncProcedure<Boolean>(procedure));
4765         }
4766
4767         @Override
4768         public void forHasStatement(Resource subject, Procedure<Boolean> procedure) {
4769                 forHasStatement(subject, new NoneToAsyncProcedure<Boolean>(procedure));
4770         }
4771
4772         @Override
4773         public void forHasStatement(Resource subject, Resource relation,
4774                         AsyncListener<Boolean> listener) {
4775                 asyncRequest(new HasStatement(subject, relation), listener);
4776         }
4777
4778         @Override
4779         public void forHasStatement(Resource subject, Resource relation,
4780                         SyncListener<Boolean> listener) {
4781                 asyncRequest(new HasStatement(subject, relation), listener);
4782         }
4783
4784         @Override
4785         public void forHasStatement(Resource subject, Resource relation,
4786                         Listener<Boolean> listener) {
4787                 asyncRequest(new HasStatement(subject, relation), listener);
4788         }
4789
4790         @Override
4791         final public void forHasStatement(final Resource subject,
4792                         final Resource relation, final AsyncProcedure<Boolean> procedure) {
4793
4794                 assert (subject != null);
4795                 assert (relation != null);
4796                 assert (procedure != null);
4797
4798                 processor.forHasStatement(this, subject, relation, procedure);
4799
4800         }
4801
4802         @Override
4803         public void forHasStatement(Resource subject, Resource relation,
4804                         SyncProcedure<Boolean> procedure) {
4805                 forHasStatement(subject, relation, new SyncToAsyncProcedure<Boolean>(
4806                                 procedure));
4807         }
4808
4809         @Override
4810         public void forHasStatement(Resource subject, Resource relation,
4811                         Procedure<Boolean> procedure) {
4812                 forHasStatement(subject, relation, new NoneToAsyncProcedure<Boolean>(
4813                                 procedure));
4814         }
4815
4816         @Override
4817         public void forHasStatement(Resource subject, Resource relation,
4818                         Resource object, AsyncListener<Boolean> listener) {
4819                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
4820                                 listener);
4821         }
4822
4823         @Override
4824         public void forHasStatement(Resource subject, Resource relation,
4825                         Resource object, SyncListener<Boolean> listener) {
4826                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
4827                                 listener);
4828         }
4829
4830         @Override
4831         public void forHasStatement(Resource subject, Resource relation,
4832                         Resource object, Listener<Boolean> listener) {
4833                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
4834                                 listener);
4835         }
4836
4837         @Override
4838         final public void forHasStatement(final Resource subject,
4839                         final Resource relation, final Resource object,
4840                         final AsyncProcedure<Boolean> procedure) {
4841
4842                 assert (subject != null);
4843                 assert (relation != null);
4844                 assert (object != null);
4845                 assert (procedure != null);
4846
4847                 processor.forHasStatement(this, subject, relation, object, procedure);
4848
4849         }
4850
4851         @Override
4852         public void forHasStatement(Resource subject, Resource relation,
4853                         Resource object, SyncProcedure<Boolean> procedure) {
4854                 forHasStatement(subject, relation, object,
4855                                 new SyncToAsyncProcedure<Boolean>(procedure));
4856         }
4857
4858         @Override
4859         public void forHasStatement(Resource subject, Resource relation,
4860                         Resource object, Procedure<Boolean> procedure) {
4861                 forHasStatement(subject, relation, object,
4862                                 new NoneToAsyncProcedure<Boolean>(procedure));
4863         }
4864
4865         @Override
4866         public void forHasValue(Resource subject, AsyncListener<Boolean> listener) {
4867                 asyncRequest(new HasValue(subject), listener);
4868         }
4869
4870         @Override
4871         public void forHasValue(Resource subject, SyncListener<Boolean> listener) {
4872                 asyncRequest(new HasValue(subject), listener);
4873         }
4874
4875         @Override
4876         public void forHasValue(Resource subject, Listener<Boolean> listener) {
4877                 asyncRequest(new HasValue(subject), listener);
4878         }
4879
4880         @Override
4881         final public void forHasValue(final Resource subject,
4882                         final AsyncProcedure<Boolean> procedure) {
4883
4884                 assert (subject != null);
4885                 assert (procedure != null);
4886
4887                 processor.forValue(this, subject, new AsyncProcedure<byte[]>() {
4888
4889                         @Override
4890                         public void execute(AsyncReadGraph graph, byte[] result) {
4891                                 try {
4892                                         if (result == null)
4893                                                 procedure.execute(graph, false);
4894                                         else
4895                                                 procedure.execute(graph, true);
4896                                 } catch (Throwable t) {
4897                                 Logger.defaultLogError(t);
4898                                 }
4899                         }
4900
4901                         @Override
4902                         public void exception(AsyncReadGraph graph, Throwable t) {
4903                                 try {
4904                                         procedure.exception(graph, t);
4905                                 } catch (Throwable t2) {
4906                                 Logger.defaultLogError(t2);
4907                                 }
4908                         }
4909
4910                         @Override
4911                         public String toString() {
4912                                 return "forHasValue -> " + procedure;
4913                         }
4914
4915                 });
4916
4917         }
4918
4919         @Override
4920         public void forHasValue(Resource subject, SyncProcedure<Boolean> procedure) {
4921                 forHasValue(subject, new SyncToAsyncProcedure<Boolean>(procedure));
4922         }
4923
4924         @Override
4925         public void forHasValue(Resource subject, Procedure<Boolean> procedure) {
4926                 forHasValue(subject, new NoneToAsyncProcedure<Boolean>(procedure));
4927         }
4928
4929         @Override
4930         public void forOrderedSet(Resource subject,
4931                         AsyncMultiListener<Resource> listener) {
4932                 asyncRequest(new OrderedSet(subject), listener);
4933         }
4934
4935         @Override
4936         public void forOrderedSet(Resource subject,
4937                         SyncMultiListener<Resource> listener) {
4938                 asyncRequest(new OrderedSet(subject), listener);
4939         }
4940
4941         @Override
4942         public void forOrderedSet(Resource subject, MultiListener<Resource> listener) {
4943                 asyncRequest(new OrderedSet(subject), listener);
4944         }
4945
4946         @Override
4947         final public void forOrderedSet(final Resource subject,
4948                         final AsyncMultiProcedure<Resource> procedure) {
4949
4950                 assert (subject != null);
4951                 assert (procedure != null);
4952
4953                 processor.forOrderedSet(this, subject,
4954                                 new AsyncMultiProcedure<Resource>() {
4955
4956                                         @Override
4957                                         public void finished(AsyncReadGraph graph) {
4958                                                 try {
4959                                                         procedure.finished(graph);
4960                                                 } catch (Throwable t) {
4961                                                 Logger.defaultLogError(t);
4962                                                 }
4963                                         }
4964
4965                                         @Override
4966                                         public void execute(AsyncReadGraph graph, Resource result) {
4967                                                 try {
4968                                                         procedure.execute(graph, result);
4969                                                 } catch (Throwable t) {
4970                                                 Logger.defaultLogError(t);
4971                                                 }
4972                                         }
4973
4974                                         @Override
4975                                         public void exception(AsyncReadGraph graph, Throwable t) {
4976                                                 try {
4977                                                         procedure.exception(graph, t);
4978                                                 } catch (Throwable t2) {
4979                                                 Logger.defaultLogError(t2);
4980                                                 }
4981                                         }
4982
4983                                         @Override
4984                                         public String toString() {
4985                                                 return "forOrderedSet -> " + procedure;
4986                                         }
4987
4988                                 });
4989
4990         }
4991
4992         @Override
4993         public void forOrderedSet(Resource subject,
4994                         SyncMultiProcedure<Resource> procedure) {
4995                 forOrderedSet(subject, new SyncToAsyncMultiProcedure<Resource>(
4996                                 procedure));
4997         }
4998
4999         @Override
5000         public void forOrderedSet(Resource subject,
5001                         MultiProcedure<Resource> procedure) {
5002                 forOrderedSet(subject, new NoneToAsyncMultiProcedure<Resource>(
5003                                 procedure));
5004         }
5005
5006         @Override
5007         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5008                         AsyncListener<T> listener) {
5009                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5010         }
5011
5012         @Override
5013         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5014                         SyncListener<T> listener) {
5015                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5016         }
5017
5018         @Override
5019         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5020                         Listener<T> listener) {
5021                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5022         }
5023
5024         @Override
5025         final public <T> void forPossibleAdapted(final Resource resource,
5026                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
5027
5028                 assert (resource != null);
5029                 assert (clazz != null);
5030                 assert (procedure != null);
5031
5032                 final AdaptionService service = getSession().peekService(AdaptionService.class);
5033                 if (service == null)
5034                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
5035                 else
5036                         service.adapt(this, resource, resource, Resource.class, clazz, true, procedure);
5037         }
5038
5039         @Override
5040         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5041                         SyncProcedure<T> procedure) {
5042                 forPossibleAdapted(resource, clazz, new SyncToAsyncProcedure<T>(
5043                                 procedure));
5044         }
5045
5046         @Override
5047         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5048                         Procedure<T> procedure) {
5049                 forPossibleAdapted(resource, clazz, new NoneToAsyncProcedure<T>(
5050                                 procedure));
5051         }
5052
5053         @Override
5054         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5055                         AsyncListener<T> listener) {
5056                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5057         }
5058
5059         @Override
5060         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5061                         SyncListener<T> listener) {
5062                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5063         }
5064
5065         @Override
5066         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5067                         Listener<T> listener) {
5068                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5069         }
5070
5071         @Override
5072         final public <T> void forPossibleUniqueAdapted(final Resource resource,
5073                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
5074
5075                 assert (resource != null);
5076                 assert (clazz != null);
5077                 assert (procedure != null);
5078
5079                 final AdaptionService service = getSession().peekService(AdaptionService.class);
5080                 if (service == null)
5081                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
5082                 else
5083                         service.adaptNew(this, resource, clazz, true, procedure);
5084
5085         }
5086
5087         @Override
5088         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5089                         SyncProcedure<T> procedure) {
5090                 forPossibleUniqueAdapted(resource, clazz, new SyncToAsyncProcedure<T>(
5091                                 procedure));
5092         }
5093
5094         @Override
5095         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5096                         Procedure<T> procedure) {
5097                 forPossibleUniqueAdapted(resource, clazz, new NoneToAsyncProcedure<T>(
5098                                 procedure));
5099         }
5100
5101         /*
5102          * Implementation of the interface AsyncRequestProcessor
5103          */
5104
5105         @Override
5106         final public Session getSession() {
5107                 return processor.getSession();
5108         }
5109
5110         @Override
5111         public <T> void asyncRequest(final Read<T> request) {
5112
5113                 asyncRequest(request, new AsyncProcedure<T>() {
5114
5115                         @Override
5116                         public void execute(AsyncReadGraph graph, T result) {
5117                         }
5118
5119                         @Override
5120                         public void exception(AsyncReadGraph graph, Throwable t) {
5121                                 Logger.defaultLogError(t);
5122                         }
5123
5124                         @Override
5125                         public String toString() {
5126                                 return "asyncRequest(Read) -> " + request;
5127                         }
5128
5129                 });
5130
5131         }
5132
5133         @Override
5134         public <T> void asyncRequest(Read<T> request, AsyncListener<T> procedure) {
5135                 asyncRequest(request, (AsyncProcedure<T>) procedure);
5136         }
5137
5138         @Override
5139         public <T> void asyncRequest(Read<T> request,
5140                         final SyncListener<T> procedure) {
5141                 asyncRequest(request, new SyncToAsyncListener<T>(procedure));
5142         }
5143
5144         @Override
5145         public <T> void asyncRequest(Read<T> request, final Listener<T> procedure) {
5146                 asyncRequest(request, new NoneToAsyncListener<T>(procedure));
5147         }
5148
5149         @Override
5150         public <T> void asyncRequest(final Read<T> request, final AsyncProcedure<T> procedure) {
5151
5152                 assert (request != null);
5153                 assert (procedure != null);
5154         
5155                 processor.schedule(new SessionTask(this) {
5156
5157                         @Override
5158                         public void run0(int thread) {
5159                                 try {
5160                                         final ListenerBase listener = getListenerBase(procedure);
5161                                         QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
5162                                 } catch (DatabaseException e) {
5163                                         Logger.defaultLogError(e);
5164                                 }
5165                         }
5166                         
5167                 });
5168
5169         }
5170
5171     public static ReadGraphImpl createAsync(QueryProcessor support) {
5172         return new ReadGraphImpl(null, null, support);
5173     }
5174
5175         @Override
5176         public <T> void asyncRequest(Read<T> request, SyncProcedure<T> procedure) {
5177                 asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
5178         }
5179
5180         @Override
5181         public <T> void asyncRequest(Read<T> request, final Procedure<T> procedure) {
5182                 asyncRequest(request, new NoneToAsyncProcedure<T>(procedure));
5183         }
5184
5185         @Override
5186         final public <T> void asyncRequest(final AsyncRead<T> request) {
5187
5188                 assert (request != null);
5189
5190                 asyncRequest(request, new AsyncProcedure<T>() {
5191
5192                         @Override
5193                         public void execute(AsyncReadGraph graph, T result) {
5194                         }
5195
5196                         @Override
5197                         public void exception(AsyncReadGraph graph, Throwable t) {
5198                         Logger.defaultLogError(t);
5199                         }
5200
5201                         @Override
5202                         public String toString() {
5203                                 return "asyncRequest(AsyncRead) -> " + request;
5204                         }
5205
5206                 });
5207
5208         }
5209
5210         @Override
5211         public <T> void asyncRequest(AsyncRead<T> request,
5212                         AsyncListener<T> procedure) {
5213                 asyncRequest(request, (AsyncProcedure<T>) procedure);
5214         }
5215
5216         @Override
5217         final public <T> void asyncRequest(AsyncRead<T> request,
5218                         final SyncListener<T> procedure) {
5219                 asyncRequest(request, new SyncToAsyncListener<T>(procedure));
5220         }
5221
5222         @Override
5223         final public <T> void asyncRequest(AsyncRead<T> request,
5224                         final Listener<T> procedure) {
5225                 asyncRequest(request, new NoneToAsyncListener<T>(procedure));
5226         }
5227
5228         @Override
5229         final public <T> void asyncRequest(final AsyncRead<T> request,
5230                         final AsyncProcedure<T> procedure) {
5231
5232                 assert (request != null);
5233                 assert (procedure != null);
5234
5235                 processor.schedule(new SessionTask(this) {
5236
5237                         @Override
5238                         public void run0(int thread) {
5239                                 try {
5240                                         final ListenerBase listener = getListenerBase(procedure);
5241                                         QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
5242                                 } catch (DatabaseException e) {
5243                                         Logger.defaultLogError(e);
5244                                 }
5245                         }
5246                         
5247                 });
5248
5249         }
5250
5251         @Override
5252         public <T> void asyncRequest(AsyncRead<T> request,
5253                         SyncProcedure<T> procedure) {
5254                 asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
5255         }
5256
5257         @Override
5258         final public <T> void asyncRequest(final AsyncRead<T> request,
5259                         final Procedure<T> procedure) {
5260                 asyncRequest(request, new NoneToAsyncProcedure<T>(procedure));
5261         }
5262
5263         @Override
5264         public <T> void asyncRequest(final MultiRead<T> request) {
5265
5266                 assert (request != null);
5267
5268                 asyncRequest(request, new SyncMultiProcedureAdapter<T>() {
5269                         @Override
5270                         public void exception(ReadGraph graph, Throwable t) {
5271                         Logger.defaultLogError(t);
5272                         }
5273
5274                         @Override
5275                         public String toString() {
5276                                 return "asyncRequest(MultiRead) -> " + request;
5277                         }
5278                 });
5279
5280         }
5281
5282         @Override
5283         public <T> void asyncRequest(MultiRead<T> request,
5284                         SyncMultiListener<T> procedure) {
5285                 asyncRequest(request, (SyncMultiProcedure<T>)procedure);
5286         }
5287
5288         @Override
5289         public <T> void asyncRequest(MultiRead<T> request,
5290                         MultiListener<T> procedure) {
5291                 asyncRequest(request, new NoneToSyncMultiListener<T>(procedure));
5292         }
5293
5294         
5295         @Override
5296         public <T> void asyncRequest(final MultiRead<T> request,
5297                         final SyncMultiProcedure<T> procedure) {
5298
5299                 assert (request != null);
5300                 assert (procedure != null);
5301
5302                 final ListenerBase listener = getListenerBase(procedure);
5303
5304                 if (parent != null || listener != null) {
5305
5306 //                  final ReadGraphImpl newGraph = newSync();
5307                     processor.query(this, request, parent, procedure,listener);
5308
5309                 } else {
5310
5311 //                  final ReadGraphImpl newGraph = newSync();
5312
5313                     try {
5314
5315                         request.perform(this, procedure);
5316
5317                     } catch (Throwable t) {
5318
5319                         try {
5320                                         procedure.exception(this, t);
5321                                 } catch (DatabaseException e) {
5322                                         LOGGER.error("Unexpected exception while handling exception", e);
5323                                 }
5324
5325                     }                           
5326
5327                 }
5328
5329         }
5330
5331         @Override
5332         public <T> void asyncRequest(MultiRead<T> request,
5333                         MultiProcedure<T> procedure) {
5334                 asyncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
5335         }
5336
5337         @Override
5338         final public <T> void asyncRequest(final AsyncMultiRead<T> request) {
5339
5340                 assert (request != null);
5341
5342                 asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
5343                         @Override
5344                         public void exception(AsyncReadGraph graph, Throwable t) {
5345                         Logger.defaultLogError(t);
5346                         }
5347
5348                         @Override
5349                         public String toString() {
5350                                 return "asyncRequest(AsyncMultiRead) -> " + request;
5351                         }
5352                 });
5353
5354         }
5355
5356         @Override
5357         public <T> void asyncRequest(AsyncMultiRead<T> request,
5358                         AsyncMultiListener<T> procedure) {
5359                 asyncRequest(request, (AsyncMultiProcedure<T>) procedure);
5360         }
5361
5362         @Override
5363         public <T> void asyncRequest(AsyncMultiRead<T> request,
5364                         SyncMultiListener<T> procedure) {
5365                 asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
5366         }
5367
5368         @Override
5369         public <T> void asyncRequest(AsyncMultiRead<T> request,
5370                         MultiListener<T> procedure) {
5371                 asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
5372         }
5373
5374         @Override
5375         final public <T> void asyncRequest(AsyncMultiRead<T> request,
5376                         final AsyncMultiProcedure<T> procedure) {
5377
5378                 assert (request != null);
5379                 assert (procedure != null);
5380
5381                 ListenerBase listener = getListenerBase(procedure);
5382
5383                 if (parent != null || listener != null) {
5384
5385                         processor.query(this, request, parent, procedure, listener);
5386
5387                 } else {
5388
5389                         try {
5390
5391                                 request.perform(this, new AsyncMultiProcedure<T>() {
5392
5393                                         @Override
5394                                         public void execute(AsyncReadGraph graph, T result) {
5395                                                 procedure.execute(graph, result);
5396                                         }
5397
5398                                         @Override
5399                                         public void finished(AsyncReadGraph graph) {
5400                                                 procedure.finished(graph);
5401                                         }
5402
5403                                         @Override
5404                                         public void exception(AsyncReadGraph graph, Throwable t) {
5405                                                 procedure.exception(graph, t);
5406                                         }
5407
5408                                         @Override
5409                                         public String toString() {
5410                                                 return "asyncRequest(AsyncMultiRead) -> " + procedure;
5411                                         }
5412
5413                                 });
5414
5415                         } catch (Throwable t) {
5416
5417                                 procedure.exception(this, new DatabaseException(t));
5418
5419                         }
5420                 }
5421
5422         }
5423
5424         @Override
5425         public <T> void asyncRequest(AsyncMultiRead<T> request,
5426                         SyncMultiProcedure<T> procedure) {
5427                 asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
5428         }
5429
5430         @Override
5431         final public <T> void asyncRequest(AsyncMultiRead<T> request,
5432                         final MultiProcedure<T> procedure) {
5433                 asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
5434         }
5435
5436         @Override
5437         final public <T> void asyncRequest(final ExternalRead<T> request) {
5438
5439                 assert (request != null);
5440
5441                 asyncRequest(request, new Procedure<T>() {
5442
5443                         @Override
5444                         public void execute(T result) {
5445                         }
5446
5447                         @Override
5448                         public void exception(Throwable t) {
5449                         Logger.defaultLogError(t);
5450                         }
5451
5452                         @Override
5453                         public String toString() {
5454                                 return "asyncRequest(PrimitiveRead) -> " + request;
5455                         }
5456
5457                 });
5458
5459         }
5460
5461         @Override
5462         public <T> void asyncRequest(ExternalRead<T> request,
5463                         final Listener<T> procedure) {
5464                 asyncRequest(request, (Procedure<T>) procedure);
5465         }
5466
5467         @Override
5468         final public <T> void asyncRequest(final ExternalRead<T> request,
5469                         final Procedure<T> procedure) {
5470
5471                 assert (request != null);
5472                 assert (procedure != null);
5473
5474                 final ListenerBase listener = getListenerBase(procedure);
5475
5476                 if (parent != null || listener != null) {
5477
5478                         try {
5479                                 QueryCacheBase.resultExternalReadEntry(this, request, parent, listener, procedure);
5480                         } catch (DatabaseException e) {
5481                                 Logger.defaultLogError(e);
5482                                 // This throwable has already been transferred to procedure at this point - do nothing about it
5483                         }
5484
5485                 } else {
5486
5487                         request.register(this, new Listener<T>() {
5488                                 @Override
5489                                 public void execute(T result) {
5490                                         procedure.execute(result);
5491                                 }
5492
5493                                 @Override
5494                                 public void exception(Throwable t) {
5495                                         procedure.exception(t);
5496                                 }
5497
5498                                 @Override
5499                                 public String toString() {
5500                                         return "asyncRequest(PrimitiveRead) -> " + request;
5501                                 }
5502
5503                                 @Override
5504                                 public boolean isDisposed() {
5505                                         return true;
5506                                 }
5507
5508                         });
5509
5510                 }
5511
5512         }
5513
5514         @Override
5515         public void asyncRequest(final Write request) {
5516
5517                 assert (request != null);
5518                 
5519                 getSession().asyncRequest(request);
5520
5521 //              processor.asyncWrite(request);
5522
5523         }
5524
5525         @Override
5526         public <T> void asyncRequest(final WriteResult<T> request, Procedure<T> procedure) {
5527                 throw new Error("Not implemented.");
5528         }
5529         
5530         @Override
5531         public void asyncRequest(Write request, Consumer<DatabaseException> callback) {
5532                 
5533                 assert (request != null);
5534                 
5535                 getSession().asyncRequest(request, callback);
5536                 
5537         }
5538
5539         @Override
5540         public void asyncRequest(final DelayedWrite request) {
5541
5542                 assert (request != null);
5543
5544                 getSession().asyncRequest(request);
5545
5546         }
5547
5548         @Override
5549         public <T> void asyncRequest(final DelayedWriteResult<T> request, Procedure<T> procedure) {
5550                 throw new Error("Not implemented.");
5551         }
5552         
5553         @Override
5554         public void asyncRequest(DelayedWrite r,
5555                         Consumer<DatabaseException> callback) {
5556                 throw new Error("Not implemented.");
5557         }
5558
5559         @Override
5560         public void asyncRequest(final WriteOnly request) {
5561
5562                 assert (request != null);
5563
5564                 getSession().asyncRequest(request);
5565
5566         }
5567
5568         @Override
5569         public <T> void asyncRequest(final WriteOnlyResult<T> request, Procedure<T> procedure) {
5570                 throw new Error("Not implemented.");
5571         }
5572         
5573         @Override
5574         public void asyncRequest(WriteOnly r, Consumer<DatabaseException> callback) {
5575                 throw new Error("Not implemented.");
5576         }
5577
5578         /*
5579          * Implementation of the interface ServiceLocator
5580          */
5581
5582         @Override
5583         public <T> T getService(Class<T> api) {
5584             if(WriteSupport.class == api) {
5585                 if(this instanceof WriteGraphImpl) {
5586                     WriteGraphImpl impl = (WriteGraphImpl)this;
5587                     return (T)impl.writeSupport;
5588                 }
5589             }
5590                 return getSession().getService(api);
5591         }
5592
5593         @Override
5594         public <T> T peekService(Class<T> api) {
5595                 return getSession().peekService(api);
5596         }
5597
5598         @Override
5599         public boolean hasService(Class<?> api) {
5600                 return getSession().hasService(api);
5601         }
5602
5603         @Override
5604         public <T> void registerService(Class<T> api, T service) {
5605                 getSession().registerService(api, service);
5606         }
5607         
5608         @Override
5609         public boolean isImmutable(Resource resource) throws DatabaseException {
5610                 ResourceImpl impl = (ResourceImpl)resource;
5611                 return processor.isImmutable(impl.id);
5612         }
5613
5614         /*
5615          * Internal routines
5616          */
5617
5618         protected static String INTERNAL_ERROR_STRING = "Transaction aborted due to internal client error.";
5619
5620         /*
5621          * callerThread is the currently running thread state.syncThread is blocking for
5622          * this execution state.syncParent is the blocking request
5623          */
5624
5625         ReadGraphImpl(ReadGraphImpl parentGraph, CacheEntry parent, QueryProcessor support) {
5626                 this.parentGraph = parentGraph;
5627                 this.parent = parent;
5628                 this.processor = support;
5629                 this.asyncBarrier = new AsyncBarrierImpl(parentGraph != null ? parentGraph.asyncBarrier : null, parent);
5630         }
5631
5632         ReadGraphImpl(ReadGraphImpl graph, CacheEntry parent) {
5633                 this(graph, parent, graph.processor);
5634         }
5635
5636         ReadGraphImpl(ReadGraphImpl graph) {
5637                 this(graph, graph.parent);
5638         }
5639
5640         public ReadGraphImpl withParent(CacheEntry parent) {
5641                 return new ReadGraphImpl(this, parent);
5642         }
5643
5644         public ReadGraphImpl forRecompute(CacheEntry parent) {
5645                 return new ReadGraphImpl(null, parent, processor);
5646         }
5647
5648         public static ReadGraphImpl create(QueryProcessor support) {
5649                 return new ReadGraphImpl(null, null, support);
5650         }
5651
5652         public ReadGraphImpl newRestart(ReadGraphImpl impl) {
5653
5654                 WriteGraphImpl write = processor.getSession().getService(
5655                                 WriteGraphImpl.class);
5656
5657                 return write;
5658
5659         }
5660
5661         final private ListenerBase getListenerBase(final Object procedure) {
5662                 if (procedure instanceof ListenerBase)
5663                         return (ListenerBase) procedure;
5664                 else
5665                         return null;
5666         }
5667
5668         public <T> void waitAsyncProcedure(AsyncMultiReadProcedure<T> procedure) {
5669                 
5670                 assert(procedure.done());
5671                 
5672         }
5673
5674         public <T> void waitAsyncProcedure(AsyncReadProcedure<T> procedure) {
5675                 
5676                 assert(procedure.done());
5677                 
5678         }
5679
5680         public boolean resumeTasks() {
5681                 return processor.resumeTasks(this);
5682         }
5683
5684         Class<?> singleClass(Set<Resource> types) {
5685                 Class<?> result = null;
5686                 for (Resource type : types) {
5687                         Class<?> clazz = processor.getBuiltinValue(type);
5688                         if (clazz != null) {
5689                                 if (result != null)
5690                                         return null;
5691                                 else
5692                                         result = clazz;
5693                         }
5694                 }
5695                 return result;
5696         }
5697
5698         private String debugString(Resource r) {
5699                 String name = null;
5700                 try {
5701                         name = getPossibleRelatedValue(r, processor.getL0(this).HasName);
5702                 } catch (ManyObjectsForFunctionalRelationException e) {
5703                 Logger.defaultLogError(e);
5704                 } catch (ServiceException e) {
5705                 Logger.defaultLogError(e);
5706                 }
5707                 return "[" + name + " - " + r + "]";
5708         }
5709
5710         @Override
5711         public String toString() {
5712                 return "ReadGraphImpl[thread=" + Thread.currentThread() + "]";
5713         }
5714
5715         @Override
5716         final public int thread() {
5717                 return 0;
5718         }
5719         
5720     static class MultiTripleIntProcedure implements TripleIntProcedure {
5721
5722         final private AsyncMultiProcedure<Statement> procedure;
5723         final private ReadGraphImpl impl;
5724         final private QuerySupport support;
5725         
5726         public MultiTripleIntProcedure(AsyncMultiProcedure<Statement> procedure, ReadGraphImpl impl, QuerySupport support) {
5727                 this.procedure = procedure;
5728                 this.impl = impl;
5729                 this.support = support;
5730         }
5731         
5732         @Override
5733         public void execute(ReadGraphImpl graph, int s, int p, int o) {
5734                 try {
5735                         procedure.execute(graph, support.getStatement(s, p, o));
5736                 } catch (Throwable t2) {
5737                         Logger.defaultLogError(t2);
5738                 }
5739         }
5740
5741         @Override
5742         public void finished(ReadGraphImpl graph) {
5743                 try {
5744                         procedure.finished(graph);
5745 //                      impl.state.barrier.dec("ReadGraphSupportImpl.516");
5746                 } catch (Throwable t2) {
5747                         Logger.defaultLogError(t2);
5748                 }
5749         }
5750
5751         @Override
5752         public void exception(ReadGraphImpl graph, Throwable t) {
5753                 try {
5754                         procedure.exception(graph, t);
5755                 } catch (Throwable t2) {
5756                         Logger.defaultLogError(t2);
5757                 }
5758 //              impl.state.barrier.dec("ReadGraphSupportImpl.516");
5759         }
5760
5761         @Override
5762         public String toString() {
5763                 return "forEachObject with " + procedure;
5764         }
5765         
5766     }
5767
5768 //    private AsyncMultiProcedure<Resource> cacheKey = null;
5769 //    private MultiIntProcedure cacheResult = null;
5770 //    
5771 //    final IntProcedure forMultiProcedure(final AsyncMultiProcedure<Resource> procedure) {
5772 //      
5773 //      if(procedure == cacheKey) return cacheResult; 
5774 //      
5775 //      cacheResult = new MultiIntProcedure(procedure, this, processor.support);
5776 //      cacheKey = procedure;
5777 //      
5778 //      return cacheResult;
5779 //      
5780 //    }
5781 //
5782 //    private AsyncMultiProcedure<Statement> cacheKey2 = null;
5783 //    private MultiTripleIntProcedure cacheResult2 = null;
5784 //
5785 //    final synchronized TripleIntProcedure forMultiProcedure(final AsyncMultiProcedure<Statement> procedure) {
5786 //      
5787 //      if(procedure == cacheKey2) return cacheResult2; 
5788 //      
5789 //      cacheResult2 = new MultiTripleIntProcedure(procedure, this, processor.support);
5790 //      cacheKey2 = procedure;
5791 //      
5792 //      return cacheResult2;
5793 //      
5794 //    }
5795     
5796     @Override
5797     public Datatype getDataType(Resource subject) throws DatabaseException {
5798         for(Resource dataTypeResource : getObjects(subject, processor.getL0(this).HasDataType))
5799                 return getValue(dataTypeResource, Bindings.getBindingUnchecked(Datatype.class));
5800         throw new DoesNotContainValueException("The literal has no data type.");
5801     }
5802     
5803     protected <T extends Accessor> T getAccessor4File(Resource subject)
5804     throws DatabaseException {
5805         return null;
5806         /*        
5807         byte[]  bytes = processor.support.getValue(g, subject);
5808         if (null == bytes)
5809             return null;
5810         try {
5811             BinaryVariant va = (BinaryVariant) Accessors.getAccessor(bytes, Datatypes.VARIANT);
5812             Accessor ca = va.getContentAccessor();
5813             return (T)ca;
5814         } catch (AccessorConstructionException e) {
5815             throw new DatabaseException(e);
5816         }
5817         */
5818         /*
5819         if (null == bytes)
5820             return null;
5821         Binding datatype_binding = Bindings.getBindingUnchecked(DataType.class);
5822         Serializer datatype_serializer = datatype_binding.serializer();
5823         DataType datatype;
5824         try {
5825             BinaryMemory in = new BinaryMemory(ByteBuffer.wrap(bytes));
5826             datatype = (DataType)datatype_serializer.deserialize(in);
5827             Binding data_binding = Bindings.getBinding(datatype);
5828             Serializer data_serializer = data_binding.serializer(BinarySerializationFormat.INSTANCE);
5829             Object o = data_serializer.deserialize(in);
5830             try {
5831                 return (T)Accessors.getAccessor(data_binding, o);
5832             } catch(AccessorConstructionException e) {
5833                 return null;
5834             }
5835         } catch (Exception e) {
5836             throw new DatabaseException(e);
5837         }*/
5838     }
5839     @SuppressWarnings("unchecked")
5840     @Override
5841     public <T extends Accessor> T getAccessor(Resource subject) throws DatabaseException {
5842         RandomAccessBinary rab = getRandomAccessBinary(subject);
5843         try {
5844             return (T)Accessors.getAccessor(rab, getDataType(subject));
5845         } catch(AccessorConstructionException e) {
5846             throw new DatabaseException(e);
5847         }
5848     }
5849     @SuppressWarnings("unchecked")
5850     protected <T extends Accessor> T createAccessor(Resource resource, Datatype datatype, Object intialValue)
5851     throws DatabaseException {
5852         RandomAccessBinary rab = createRandomAccessBinary(resource, datatype, intialValue);
5853         try {
5854             return (T)Accessors.getAccessor(rab, datatype);
5855         } catch(AccessorConstructionException e) {
5856             throw new DatabaseException(e);
5857         }
5858     }
5859     @Override
5860     public RandomAccessBinary getRandomAccessBinary(Resource subject) throws DatabaseException {
5861         RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class);
5862         ResourceData rd = ravs.get(subject);
5863         if (null != rd)
5864             return rd;
5865         try {
5866             ExternalValueSupport evs = getService(ExternalValueSupport.class);
5867             long size = evs.getValueSize(this, subject); // Throws DatabaseException if no old external value.
5868             try {
5869                 File platform = Platform.getLocation().toFile();
5870                 File tempFiles = new File(platform, "tempFiles");
5871                 File dbDir = new File(tempFiles, "db");
5872                 dbDir.mkdirs();
5873                 File file = new File(dbDir, "ResourceFile" + subject.getResourceId());
5874                 rd = new ResourceData(new BinaryFile(file), true); // Old external value.
5875                 final int N = 1<<20;
5876                 long left = size;
5877                 long offset = 0;
5878                 while (left > 0) {
5879                     int length = N < left ? N : (int)left;
5880                     byte[] bytes = evs.readValue(this, subject, offset, length);
5881                     offset += bytes.length;
5882                     left -= bytes.length;
5883                     rd.binaryFile.write(bytes);
5884                 }
5885                 ravs.put(subject, rd);
5886                 return rd;
5887             } catch (Exception e) {
5888                 throw new DatabaseException("Resource " + subject + " have value but there was problem with accessing value data.", e);
5889             }
5890         } catch (Exception e) {
5891             if(Development.DEVELOPMENT) {
5892                 if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
5893                     e.printStackTrace();
5894                 }
5895             }
5896         }
5897         Datatype datatype = getDataType(subject);
5898         Object value = getPossibleValue(subject, Bindings.getBinding(datatype));
5899         return createRandomAccessBinary(subject, datatype, value);
5900     }
5901     public RandomAccessBinary createRandomAccessBinary(Resource resource, Datatype datatype, Object initialValue)
5902     throws DatabaseException {
5903         RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class);
5904         try {
5905             File platform = Platform.getLocation().toFile();
5906             File tempFiles = new File(platform, "tempFiles");
5907             File dbDir = new File(tempFiles, "db");
5908             dbDir.mkdirs();
5909             File file = new File(dbDir, "ResourceFile" + resource.getResourceId());
5910             ResourceData rd = new ResourceData(new BinaryFile(file), false);
5911             Binding binding = Bindings.getBinding(datatype);
5912             if (null == initialValue) {
5913                 initialValue = binding.createDefault();
5914             }
5915             Serializer serializer = binding.serializer();
5916             byte[] bytes = serializer.serialize(initialValue);
5917             // In case the file has been previously accessed and was larger we set the correct size now
5918             rd.binaryFile.setLength(bytes.length);
5919             rd.binaryFile.write(bytes);
5920             ravs.put(resource, rd);
5921             return rd;
5922         } catch (Exception e) {
5923             if (e instanceof DatabaseException)
5924                 throw (DatabaseException)e;
5925             else
5926                 throw new DatabaseException(e);
5927         }
5928     }
5929
5930 //    static class ExternalValueRequest<T> extends ResourceRead<T> {
5931 //
5932 //              public ExternalValueRequest(Resource resource) {
5933 //                      super(resource);
5934 //              }
5935 //
5936 //              @SuppressWarnings("unchecked")
5937 //              @Override
5938 //              public T perform(ReadGraph graph) throws DatabaseException {
5939 //              try {
5940 //                      
5941 //                      String uri = graph.getURI(resource);
5942 //                      if(Layer0.URIs.Functions_functionApplication.equals(uri)) return (T)functionApplication;
5943 //                      
5944 //                      return (T)ReflectionUtils.getValue(uri).getValue();
5945 //                      
5946 //              } catch(ValueNotFoundException e) {
5947 //                      throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e);
5948 //              } catch(ClassCastException e) {
5949 //                      throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e);
5950 //              }
5951 //              }
5952 //      
5953 //    }
5954     
5955     @SuppressWarnings("unchecked")
5956     @Override
5957     public <T> T getValue2(Resource r, Object context) throws DatabaseException {
5958         Layer0 L0 = processor.getL0(this);
5959         Set<Resource> types = getTypes(r);
5960         
5961         if(types.contains(L0.Literal)) {
5962                 if(isImmutable(r)) {
5963                         return syncRequest(new ValueImplied<T>(r));
5964                 } else {
5965                         return getValue(r);
5966                 }
5967         }
5968         else if(types.contains(L0.ExternalValue)) {
5969                 return (T)syncRequest(new AdaptValue(r), TransientCacheListener.<Object>instance());
5970         }
5971         else {
5972
5973             Function3<ReadGraph,Resource,Object,T> function = requestValueFunction(r);
5974             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r);
5975             try {
5976                 return function.apply(this, r, context);
5977             } catch(RuntimeException e) {
5978                 DatabaseException dte = findPossibleRootException(e);
5979                 if(dte != null) throw dte;
5980                 else throw new DatabaseException(e);
5981             }
5982                 
5983         }
5984     }
5985
5986     @Override
5987     public Variant getVariantValue2(Resource r, Object context) throws DatabaseException {
5988         Layer0 L0 = processor.getL0(this);
5989         Set<Resource> types = getTypes(r);
5990         
5991         if(types.contains(L0.Literal)) {
5992             if(isImmutable(r)) {
5993                 return syncRequest(new VariantValueImplied(r));
5994             } else {
5995                 return getVariantValue(r);
5996             }
5997         }
5998         else if(types.contains(L0.ExternalValue)) {
5999             Object value = syncRequest(new AdaptValue(r), TransientCacheListener.<Object>instance());
6000             try {
6001                 return new Variant(Bindings.OBJECT.getContentBinding(value), value);
6002             } catch ( org.simantics.databoard.binding.error.BindingException e ) {
6003                 throw new BindingException( "No binding found for class " + value.getClass().getName(), e );
6004             }
6005         }
6006         else {
6007
6008             Function3<ReadGraph,Resource,Object,Object> function = requestValueFunction(r);
6009             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r);
6010             try {
6011                 Object value = function.apply(this, r, context);
6012                 try {
6013                     return new Variant(Bindings.OBJECT.getContentBinding(value), value);
6014                 } catch ( org.simantics.databoard.binding.error.BindingException e ) {
6015                     throw new BindingException( "No binding found for class " + value.getClass().getName(), e );
6016                 }
6017             } catch(RuntimeException e) {
6018                 DatabaseException dte = findPossibleRootException(e);
6019                 if(dte != null) throw dte;
6020                 else throw new DatabaseException(e);
6021             }
6022         }
6023     }
6024     
6025     @Override
6026     public <T> T getPossibleValue2(Resource subject, Object context) throws DatabaseException {
6027         try {
6028                 return getValue2(subject, context);
6029         } catch (DatabaseException e) {
6030                 return null;
6031         }
6032     }
6033
6034     static class PossibleConverterFunction<T> extends ResourceRead<Function3<ReadGraph,Resource,Object,T>> {
6035         
6036         public PossibleConverterFunction(Resource resource) {
6037                         super(resource);
6038                 }
6039
6040         @Override
6041         public Function3<ReadGraph,Resource,Object,T> perform(ReadGraph graph) throws DatabaseException {
6042                 return compute(graph, resource);
6043         }
6044         
6045         @SuppressWarnings("unchecked")
6046                 public static <T> Function3<ReadGraph,Resource,Object,T> compute(ReadGraph graph, Resource resource) throws DatabaseException {
6047             Layer0 L0 = Layer0.getInstance(graph);
6048             for(Resource converter : graph.getObjects(resource, L0.ConvertsToValueWith)) {
6049                 try {
6050                         if(L0.Functions_functionApplication.equals(converter)) {
6051                                 return (Function3<ReadGraph,Resource,Object,T>)graph.syncRequest(new AdaptValue(resource));
6052                         } else {
6053                                 return graph.getValue2(converter, resource);
6054                         }
6055                 } catch(RuntimeException e) {
6056                     DatabaseException dte = findPossibleRootException(e);
6057                     if(dte != null) throw dte;
6058                     else throw new DatabaseException(e);
6059                 }
6060             }
6061             return null;
6062         }
6063         
6064     }
6065     
6066     <T> Function3<ReadGraph,Resource,Object,T> requestValueFunction(Resource r) throws DatabaseException {
6067         if(isImmutable(r))
6068                 return syncRequest(new PossibleConverterFunction<T>(r), TransientCacheAsyncListener.<Function3<ReadGraph,Resource,Object,T>>instance());
6069         else
6070                 return syncRequest(new PossibleConverterFunction<T>(r));
6071     }
6072     
6073     /**
6074      * Get a value associated with a graph {@link Resource}, using a possible context object and
6075      * a desired value binding. The following methods are tried in order to retreive the value:
6076      * <ol>
6077      *   <li>If the given resource is a {@code L0.Literal}, the value of the literal is returned, using the binding specified by {@code binding}.</li>
6078      *   <li>If the resource is a {@code L0.ExternalValue}, the value is acquired using
6079      *       {@link ReflectionUtils#getValue(String)}.</li>
6080      *   <li>If the resource is associated with a suitable value converter with relation {@code L0.ConvertsToValueWith}
6081      *       (see {@link #requestValueFunction(Resource)}), the value function is called with the graph, the resource
6082      *       and the context object.</li>
6083      * </ul>
6084      * 
6085      * @param r  A graph resource with which the value is associated
6086      * @param context  A context object that is used for acquiring the value (only applied in case 3)
6087      * @param binding  A binding for the value type (only applied in case 1)
6088      * @return  The value of the graph node.
6089      * @throws DoesNotContainValueException  No value is associated with the graph node.
6090      * @throws DatabaseException  Other errors, such as an error in casting the value to the return type or
6091      *         a runtime error in the value function.
6092      */
6093     @SuppressWarnings("unchecked")
6094         @Override
6095     public <T> T getValue2(Resource r, Object context, Binding binding) throws DatabaseException {
6096         if (binding instanceof ObjectVariantBinding)
6097                 return getValue2(r, context);
6098         
6099         Layer0 L0 = processor.getL0(this);
6100         Set<Resource> types = getTypes(r);
6101         if(types.contains(L0.Literal)) {
6102                 if(isImmutable(r)) {
6103                         return syncRequest(new Value<T>(r, binding));
6104                 } else {
6105                         return getValue(r, binding);
6106                 }
6107         } else if(types.contains(L0.ExternalValue)) {
6108                 ComputationalValue cv = syncRequest(new PossibleAdapter<ComputationalValue>(r, ComputationalValue.class), TransientCacheAsyncListener.instance());
6109                 if(cv != null) {
6110                         return cv.getValue(this, r);
6111                 } else {
6112                         // This should not even be possible since L0 defines an adapter for all values
6113                         try {
6114                                 return (T)ReflectionUtils.getValue(getURI(r)).getValue();
6115                         } catch(ValueNotFoundException e) {
6116                                 throw new DatabaseException(e);
6117                         } catch(ClassCastException e) {
6118                                 throw new DatabaseException(e);
6119                         }
6120                 }
6121         }
6122         else {
6123             Function3<ReadGraph,Resource,Object,T> function = requestValueFunction(r);
6124             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function.");
6125             try {
6126                 Object value = function.apply(this, r, context);
6127                 if(binding.isInstance(value)) return (T)value;
6128                 Binding srcBinding = Bindings.OBJECT.getContentBinding(value);
6129                 return (T)Bindings.adapt(value, srcBinding, binding);
6130             } catch(RuntimeException e) {
6131                 DatabaseException dte = findPossibleRootException(e);
6132                 if(dte != null) throw dte;
6133                 else throw new DatabaseException(e);
6134             } catch (AdaptException e) {
6135                 throw new DatabaseException(e);
6136                         } catch (org.simantics.databoard.binding.error.BindingException e) {
6137                 throw new DatabaseException(e);
6138                         }
6139         }
6140     }
6141     
6142     @Override
6143     public <T> T getPossibleValue2(Resource subject, Object context, Binding binding) throws DatabaseException {
6144         try {
6145                 return getValue2(subject, context, binding);
6146         } catch (DatabaseException e) {
6147                 return null;
6148         }
6149     }
6150     
6151         private static DatabaseException findPossibleRootException(Throwable t) {
6152                 if(t == null) return null;
6153                 if(t instanceof DatabaseException) return (DatabaseException)t;
6154                 if(t instanceof RuntimeException || t instanceof InvocationTargetException) {
6155                         return findPossibleRootException(t.getCause());
6156                 }
6157                 return null;
6158         }
6159     
6160     @Override
6161     public <T> T getRelatedValue2(Resource subject, Resource relation) throws DatabaseException {
6162         return getRelatedValue2(subject, relation, subject);
6163     }
6164     
6165     @Override
6166     public Variant getRelatedVariantValue2(Resource subject, Resource relation) throws DatabaseException {
6167         return getRelatedVariantValue2(subject, relation, subject);
6168     }
6169     
6170     @Override
6171     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation) throws DatabaseException {
6172         try {
6173                 Resource object = getPossibleObject(subject, relation);
6174                 if(object == null) return null;
6175                 else return getValue2(object, subject);
6176         } catch (DatabaseException e) {
6177                 return null;
6178         }
6179     }
6180
6181     @Override
6182     public <T> T getRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6183                 if(Development.DEVELOPMENT) {
6184                         if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
6185                                 String error = L0Validations.checkValueType(this, subject, relation);
6186                                 if(error != null) {
6187                                         Logger.defaultLogError(new ValidationException(error));
6188                                         throw new ValidationException(error);
6189                                 }
6190                         }
6191                 }
6192         return getValue2(getSingleObject(subject, relation), context);
6193     }
6194     
6195     @Override
6196     public Variant getRelatedVariantValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6197         if(Development.DEVELOPMENT) {
6198                         if(Development.<Boolean>getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) {
6199                                 String error = L0Validations.checkValueType(this, subject, relation);
6200                                 if(error != null) {
6201                                         Logger.defaultLogError(new ValidationException(error));
6202                                         throw new ValidationException(error);
6203                                 }
6204                         }
6205         }
6206         return getVariantValue2(getSingleObject(subject, relation), context);
6207     }
6208     
6209     @Override
6210     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6211         try {
6212                 Resource object = getPossibleObject(subject, relation);
6213                 if(object == null) return null;
6214                 else return getValue2(object, context);
6215         } catch (DatabaseException e) {
6216                 return null;
6217         }
6218     }
6219
6220     @Override
6221     public <T> T getRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException {
6222         return getRelatedValue2(subject, relation, subject, binding);
6223     }
6224     
6225     @Override
6226     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException {
6227         try {
6228                 Resource object = getPossibleObject(subject, relation);
6229                 if(object == null) return null;
6230                 return getValue2(object, subject, binding);
6231         } catch (DatabaseException e) {
6232                 return null;
6233         }
6234     }
6235
6236     @Override
6237     public <T> T getRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException {
6238         return getValue2(getSingleObject(subject, relation), context, binding);
6239     }
6240     
6241     @Override
6242     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException {
6243         try {
6244                 Resource object = getPossibleObject(subject, relation);
6245                 if(object == null) return null;
6246                 else return getValue2(object, context, binding);
6247         } catch (DatabaseException e) {
6248                 return null;
6249         }
6250     }
6251     
6252     @Override
6253     public Type getRelatedValueType(Resource subject, Resource relation) throws DatabaseException {
6254         Layer0 L0 = processor.getL0(this);
6255         Resource property = getSingleObject(subject, relation);
6256         String typeText = (String)getRelatedValue(property, L0.HasValueType, Bindings.STRING);
6257         try {
6258             return org.simantics.scl.compiler.types.Types.parseType(typeText);
6259         } catch (SCLTypeParseException e) {
6260             throw new DatabaseException(e);
6261         }
6262     }
6263
6264     private static ThreadLocal<Boolean> syncGraph = new ThreadLocal<Boolean>() {
6265         protected Boolean initialValue() {
6266             return true;
6267         }
6268     };
6269
6270     @Override
6271     public boolean setSynchronous(boolean value) {
6272         boolean old = getSynchronous();
6273         syncGraph.set(value);
6274         return old;
6275     }
6276
6277     @Override
6278     public boolean getSynchronous() {
6279         return syncGraph.get();
6280     }
6281     
6282     public void ensureLoaded(int resource) {
6283         processor.querySupport.ensureLoaded(this, resource);
6284     }
6285     
6286     public void ensureLoaded(int resource, int predicate) {
6287         processor.querySupport.ensureLoaded(this, resource, predicate);
6288     }
6289
6290     public byte[] getValue(int resource) {
6291         return processor.querySupport.getValue(this, resource);
6292     }
6293     
6294     public int thread(int resource) {
6295         return (resource >>> 16) & processor.THREAD_MASK;
6296     }
6297
6298     public int thread(Resource resource) {
6299         return (((ResourceImpl)resource).id >>> 16) & processor.THREAD_MASK;
6300     }
6301     
6302     public ResourceSupport getResourceSupport() {
6303         return processor.getResourceSupport();
6304     }
6305     
6306     @Override
6307     public Object getModificationCounter() {
6308         return processor.getSession().getModificationCounter();
6309     }
6310
6311     @Override
6312     public boolean performPending() {
6313         return processor.performPending(this);
6314     }
6315
6316     public Set<ReadGraphImpl> ancestorSet() {
6317         HashSet<ReadGraphImpl> result = new HashSet<>();
6318         ReadGraphImpl g = this;
6319         while(g != null) {
6320             result.add(g);
6321             g = g.parentGraph;
6322         }
6323         return result;
6324     }
6325
6326 }