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