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