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