]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
d6a0aa9f45dea69a4cbb87efa7be87e77df59745
[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.RelationInfo;
52 import org.simantics.db.Resource;
53 import org.simantics.db.Session;
54 import org.simantics.db.Statement;
55 import org.simantics.db.adaption.AdaptionService;
56 import org.simantics.db.common.primitiverequest.Adapter;
57 import org.simantics.db.common.primitiverequest.Builtin;
58 import org.simantics.db.common.primitiverequest.DatatypeBinding;
59 import org.simantics.db.common.primitiverequest.ForEachAssertedObject;
60 import org.simantics.db.common.primitiverequest.ForEachAssertedStatement;
61 import org.simantics.db.common.primitiverequest.HasStatement;
62 import org.simantics.db.common.primitiverequest.HasStatementSubject;
63 import org.simantics.db.common.primitiverequest.HasStatementSubjectObject;
64 import org.simantics.db.common.primitiverequest.HasValue;
65 import org.simantics.db.common.primitiverequest.Inverse;
66 import org.simantics.db.common.primitiverequest.IsInheritedFrom;
67 import org.simantics.db.common.primitiverequest.IsInstanceOf;
68 import org.simantics.db.common.primitiverequest.IsSubrelationOf;
69 import org.simantics.db.common.primitiverequest.OrderedSet;
70 import org.simantics.db.common.primitiverequest.PossibleAdapter;
71 import org.simantics.db.common.primitiverequest.PossibleInverse;
72 import org.simantics.db.common.primitiverequest.PossibleObject;
73 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
74 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied;
75 import org.simantics.db.common.primitiverequest.PossibleStatement;
76 import org.simantics.db.common.primitiverequest.PossibleType;
77 import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter;
78 import org.simantics.db.common.primitiverequest.PossibleValue;
79 import org.simantics.db.common.primitiverequest.PossibleValueImplied;
80 import org.simantics.db.common.primitiverequest.RelatedValue;
81 import org.simantics.db.common.primitiverequest.RelatedValueImplied;
82 import org.simantics.db.common.primitiverequest.SingleObject;
83 import org.simantics.db.common.primitiverequest.SingleStatement;
84 import org.simantics.db.common.primitiverequest.SingleType;
85 import org.simantics.db.common.primitiverequest.SingleTypeAny;
86 import org.simantics.db.common.primitiverequest.Types;
87 import org.simantics.db.common.primitiverequest.UniqueAdapter;
88 import org.simantics.db.common.primitiverequest.Value;
89 import org.simantics.db.common.primitiverequest.ValueImplied;
90 import org.simantics.db.common.primitiverequest.VariantValueImplied;
91 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
92 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
93 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
94 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
95 import org.simantics.db.common.procedure.single.SyncReadProcedure;
96 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrErrorProcedure;
97 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure;
98 import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure;
99 import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure;
100 import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure;
101 import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure;
102 import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure;
103 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
104 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
105 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
106 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
107 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
108 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
109 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
110 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
111 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
112 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
113 import org.simantics.db.common.request.AdaptValue;
114 import org.simantics.db.common.request.ResourceRead;
115 import org.simantics.db.common.utils.Logger;
116 import org.simantics.db.common.utils.NameUtils;
117 import org.simantics.db.common.validation.L0Validations;
118 import org.simantics.db.exception.AdaptionException;
119 import org.simantics.db.exception.ArgumentException;
120 import org.simantics.db.exception.AssumptionException;
121 import org.simantics.db.exception.BindingException;
122 import org.simantics.db.exception.DatabaseException;
123 import org.simantics.db.exception.DoesNotContainValueException;
124 import org.simantics.db.exception.EmptyResourceException;
125 import org.simantics.db.exception.InternalException;
126 import org.simantics.db.exception.InvalidLiteralException;
127 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
128 import org.simantics.db.exception.NoInverseException;
129 import org.simantics.db.exception.NoSingleResultException;
130 import org.simantics.db.exception.ResourceNotFoundException;
131 import org.simantics.db.exception.ServiceException;
132 import org.simantics.db.exception.ValidationException;
133 import org.simantics.db.impl.RelationContextImpl;
134 import org.simantics.db.impl.ResourceImpl;
135 import org.simantics.db.impl.internal.RandomAccessValueSupport;
136 import org.simantics.db.impl.internal.ResourceData;
137 import org.simantics.db.impl.procedure.CallWrappedSingleQueryProcedure4;
138 import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4;
139 import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4;
140 import org.simantics.db.impl.query.CacheEntry;
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                         SyncReadProcedure<RelationInfo> procedure = new SyncReadProcedure<RelationInfo>();
1822                         processor.forRelationInfo(this, relation, procedure);
1823                         Collection<Resource> predicates = getPredicates(subject);
1824                         
1825                         if(procedure.result.isFinal) {
1826                                 
1827                                 return predicates.contains(relation);
1828                                 
1829                         } else if (procedure.result.isFunctional) {
1830
1831                                 try {
1832                                         int result = processor.getSingleObject(this, subject, relation);
1833                                         return result != 0;
1834                                 } catch (ManyObjectsForFunctionalRelationException e) {
1835                                         return true;
1836                                 } catch (DatabaseException e) {
1837                                         throw new ServiceException(e);
1838                                 }
1839                                 
1840                         } else {
1841
1842                                 for(Resource predicate : getPredicates(subject)) {
1843                                         if(isSubrelationOf(predicate, relation))
1844                                                 return true;
1845                                 }
1846                                 
1847                         }
1848                         
1849                         return false;
1850
1851                 } catch (ServiceException e) {
1852
1853                         throw new ServiceException(e);
1854
1855                 } 
1856                 
1857         }
1858
1859         @Override
1860         final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1861
1862                 assert (subject != null);
1863                 assert (relation != null);
1864                 assert (object != null);
1865
1866                 try {
1867
1868                         for(Resource o : getObjects(subject, relation)) {
1869                                 if(object.equals(o)) return true;
1870                         }
1871                         
1872                         return false;
1873
1874                 } catch (ServiceException e) {
1875
1876                         throw new ServiceException(e);
1877
1878                 }
1879
1880         }
1881
1882         @Override
1883         final public boolean hasValue(final Resource subject) throws ServiceException {
1884
1885                 assert (subject != null);
1886
1887                 try {
1888
1889                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1890                         processor.forHasValue(this, subject, procedure);
1891                         procedure.checkAndThrow();
1892                         return procedure.result;
1893
1894                 } catch (ServiceException e) {
1895
1896                         throw new ServiceException(e);
1897
1898                 } catch (DatabaseException e) {
1899
1900                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1901
1902                 }
1903
1904         }
1905
1906         final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1907
1908                 @Override
1909                 public void execute(AsyncReadGraph graph, Object result) {
1910                 }
1911
1912                 @Override
1913                 public void exception(AsyncReadGraph graph, Throwable throwable) {
1914                 }
1915                 
1916         };
1917         
1918         /*
1919          * Implementation of the interface RequestProcessor
1920          */
1921
1922         @Override
1923         public <T> T syncRequest(final Read<T> request) throws DatabaseException {
1924
1925                 assert (request != null);
1926
1927                 if (parent != null) {
1928
1929                         try {
1930                                 return processor.queryRead(this, request, parent, null, null);
1931                         } catch (Throwable e) {
1932                                 if(e instanceof DatabaseException) throw (DatabaseException)e;
1933                                 else throw new DatabaseException(e);
1934                         }
1935
1936                 } else {
1937
1938                         try {
1939
1940                                 return processor.tryQuery(this, request);
1941
1942                         } catch (Throwable throwable) {
1943
1944                                 //Logger.defaultLogError("Internal read request failure", throwable);
1945
1946                                 if (throwable instanceof DatabaseException)
1947                                         throw (DatabaseException) throwable;
1948                                 else
1949                                         throw new DatabaseException(
1950                                                         "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
1951                                                         throwable);
1952
1953                         }
1954
1955                 }
1956                 
1957         }
1958
1959         @Override
1960         public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1961                         throws DatabaseException {
1962                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1963         }
1964
1965         @Override
1966         public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1967                         throws DatabaseException {
1968                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1969         }
1970
1971         @Override
1972         public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1973
1974                 assert (request != null);
1975
1976                 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1977
1978                 if (parent != null || listener != null) {
1979                         
1980                         try {
1981                 return processor.queryRead(this, request, parent, procedure, listener);
1982             } catch (Throwable e) {
1983                 if(e instanceof DatabaseException) throw (DatabaseException)e;
1984                 else throw new DatabaseException(e);
1985             }
1986
1987                 } else {
1988
1989                         try {
1990
1991                                 T t = processor.tryQuery(this, request);
1992                                 if(procedure != null)
1993                                         procedure.execute(this, t);
1994
1995                                 return t;
1996
1997                         } catch (Throwable throwable) {
1998
1999                                 Logger.defaultLogError("Internal read request failure", throwable);
2000
2001                                 if(procedure != null)
2002                                         procedure.exception(this, throwable);
2003                                 
2004                                 if (throwable instanceof DatabaseException)
2005                                         throw (DatabaseException) throwable;
2006                                 else
2007                                         throw new DatabaseException(
2008                                                         "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
2009                                                         throwable);
2010
2011                         }
2012
2013                 }
2014
2015         }
2016
2017         @Override
2018         public <T> T syncRequest(final Read<T> request,
2019                         final SyncProcedure<T> procedure) throws DatabaseException {
2020                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2021         }
2022
2023         @Override
2024         public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
2025                         throws DatabaseException {
2026                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2027         }
2028
2029         static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
2030
2031                 private static Throwable DONE = new Throwable();
2032                 
2033                 T result = null;
2034                 Throwable exception = null;
2035                 
2036                 @Override
2037                 public void execute(AsyncReadGraph graph, T t) {
2038                         result = t;
2039                         exception = DONE;
2040                 }
2041
2042                 @Override
2043                 public void exception(AsyncReadGraph graph, Throwable t) {
2044                         exception = t;
2045                 }
2046                 
2047                 public void checkAndThrow() throws DatabaseException {
2048                         if(exception != DONE) {
2049                                 if (exception instanceof DatabaseException)
2050                                         throw (DatabaseException) exception;
2051                                 else
2052                                         throw new DatabaseException(
2053                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2054                                                         exception);
2055                         }
2056                 }
2057                 
2058                 public boolean done() {
2059                         return exception != null;
2060                 }
2061                 
2062         }
2063         
2064         @Override
2065         public <T> T syncRequest(final AsyncRead<T> request)
2066                         throws DatabaseException {
2067
2068                 assert (request != null);
2069                 AsyncReadProcedure<T> procedure = new AsyncReadProcedure<T>();
2070                 syncRequest(request, procedure);
2071                 procedure.checkAndThrow();
2072                 return procedure.result;
2073                 
2074 //              return syncRequest(request, new AsyncProcedureAdapter<T>());
2075
2076         }
2077
2078         @Override
2079         public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2080                         throws DatabaseException {
2081                 return syncRequest(request, (AsyncProcedure<T>) procedure);
2082         }
2083
2084         @Override
2085         public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2086                         throws DatabaseException {
2087                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2088         }
2089
2090         @Override
2091         public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2092                         throws DatabaseException {
2093                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2094         }
2095
2096         @Override
2097         final public <T> T syncRequest(final AsyncRead<T> request,
2098                         final AsyncProcedure<T> procedure) throws DatabaseException {
2099
2100                 assert (request != null);
2101
2102                 // System.out.println("syncRequest " + request + " syncParent=" +
2103                 // syncParent);
2104
2105                 ListenerBase listener = getListenerBase(procedure);
2106
2107                 if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
2108
2109 //                      Object syncParent = request;
2110
2111 //                      final ReadGraphImpl newGraph = newSync();
2112
2113                         final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
2114                                         procedure, request);
2115                         
2116                         processor.query(this, request, parent, wrapper, listener);
2117
2118 //                      newGraph.waitAsync(syncParent);
2119                         
2120                         Throwable e = wrapper.getException();
2121                         if (e != null) {
2122                                 // The request was async - produce meaningful stack trace by
2123                                 // wrapping
2124                                 if (e instanceof DatabaseException)
2125                                         throw (DatabaseException) e;
2126                                 else
2127                                         throw new DatabaseException(e);
2128                         }
2129                         
2130                         return wrapper.getResult();
2131
2132                 } else {
2133
2134                         // System.out.println("direct call " + request );
2135
2136                         // Do not set the sync state.parent for external threads
2137 //                      Object syncParent = request;
2138
2139 //                      final ReadGraphImpl newGraph = newSync();
2140
2141                         final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
2142                                         procedure, request);
2143
2144                         try {
2145
2146                                 processor.tryQuery(this, request, wrapper);
2147
2148                         } catch (Throwable t) {
2149
2150                                 wrapper.exception(this, t);
2151
2152                         }
2153
2154                         Throwable e = wrapper.getException();
2155                         if (e != null) {
2156                                 // The request was async - produce meaningful stack trace by
2157                                 // wrapping
2158                                 if (e instanceof DatabaseException)
2159                                         throw (DatabaseException) e;
2160                                 else
2161                                         throw new DatabaseException(e);
2162                         }
2163                         
2164                         return wrapper.getResult();
2165
2166                 }
2167
2168         }
2169
2170         final private <T> void syncRequest(final AsyncRead<T> request, final AsyncReadProcedure<T> procedure) throws DatabaseException {
2171
2172                 assert (request != null);
2173
2174                 // System.out.println("syncRequest " + request + " syncParent=" +
2175                 // syncParent);
2176
2177                 ListenerBase listener = getListenerBase(procedure);
2178
2179                 if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
2180
2181 //                      final ReadGraphImpl newGraph = newSync();
2182
2183                         final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
2184                                         procedure, request);
2185
2186                         processor.query(this, request, parent, wrapper, listener);
2187
2188                 } else {
2189
2190                         try {
2191
2192 //                              final ReadGraphImpl newGraph = newSync();
2193                                 processor.tryQuery(this, request, procedure);
2194 //                              newGraph.waitAsync(null);
2195                                 waitAsyncProcedure(procedure);
2196
2197                         } catch (Throwable t) {
2198                                 if(Development.DEVELOPMENT) {
2199                                         if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
2200                                         t.printStackTrace();
2201                                         }
2202                                 }
2203                                 procedure.exception(this, t);
2204                                 waitAsyncProcedure(procedure);
2205                         }
2206
2207                 }
2208
2209         }
2210
2211         @Override
2212         public <T> T syncRequest(AsyncRead<T> request,
2213                         final SyncProcedure<T> procedure) throws DatabaseException {
2214                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2215         }
2216
2217         @Override
2218         final public <T> T syncRequest(final AsyncRead<T> request,
2219                         final Procedure<T> procedure) throws DatabaseException {
2220                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2221         }
2222
2223         @Override
2224         public <T> Collection<T> syncRequest(final MultiRead<T> request)
2225                         throws DatabaseException {
2226
2227                 assert (request != null);
2228
2229                 final ArrayList<T> result = new ArrayList<T>();
2230                 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2231
2232                 syncRequest(request, new AsyncMultiProcedure<T>() {
2233
2234                         @Override
2235                         public void execute(AsyncReadGraph graph, T t) {
2236                                 synchronized (result) {
2237                                         result.add(t);
2238                                 }
2239                         }
2240
2241                         @Override
2242                         public void finished(AsyncReadGraph graph) {
2243                         }
2244
2245                         @Override
2246                         public void exception(AsyncReadGraph graph, Throwable t) {
2247                                 exception.set(t);
2248                         }
2249
2250                         @Override
2251                         public String toString() {
2252                                 return "syncRequest(MultiRead) -> " + request;
2253                         }
2254
2255                 });
2256
2257                 Throwable t = exception.get();
2258                 if (t != null) {
2259                         if (t instanceof DatabaseException)
2260                                 throw (DatabaseException) t;
2261                         else
2262                                 throw new DatabaseException(
2263                                                 "Unexpected exception in ReadGraph.syncRequest(Read)",
2264                                                 t);
2265                 }
2266
2267                 return result;
2268
2269         }
2270
2271         @Override
2272         public <T> Collection<T> syncRequest(MultiRead<T> request,
2273                         AsyncMultiListener<T> procedure) {
2274                 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2275         }
2276
2277         @Override
2278         public <T> Collection<T> syncRequest(MultiRead<T> request,
2279                         SyncMultiListener<T> procedure) {
2280                 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2281         }
2282
2283         @Override
2284         public <T> Collection<T> syncRequest(MultiRead<T> request,
2285                         MultiListener<T> procedure) {
2286                 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2287         }
2288
2289         @Override
2290         public <T> Collection<T> syncRequest(MultiRead<T> request,
2291                         AsyncMultiProcedure<T> procedure) {
2292
2293                 assert (request != null);
2294
2295                 ListenerBase listener = getListenerBase(procedure);
2296
2297                 if (parent != null || listener != null) {
2298
2299 //                      Object syncParent = request;
2300
2301 //                      final ReadGraphImpl newGraph = newSync();
2302
2303                         processor.query(this, request, parent, procedure, listener);
2304
2305 //                      newGraph.waitAsync(syncParent);
2306
2307                 } else {
2308
2309 //                      Object syncParent = request;
2310
2311 //                      final ReadGraphImpl newGraph = newSync();
2312
2313                         final ResultCallWrappedQueryProcedure4<T> wrapper = new ResultCallWrappedQueryProcedure4<T>(procedure);
2314
2315                         try {
2316
2317                                 request.perform(this, wrapper);
2318
2319                         } catch (Throwable t) {
2320
2321                                 wrapper.exception(this, t);
2322 //                              newGraph.waitAsync(syncParent);
2323
2324                         }
2325
2326                 }
2327
2328                 // TODO
2329                 return null;
2330
2331         }
2332
2333         @Override
2334         public <T> Collection<T> syncRequest(MultiRead<T> request,
2335                         SyncMultiProcedure<T> procedure) {
2336                 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2337         }
2338
2339         @Override
2340         public <T> Collection<T> syncRequest(MultiRead<T> request,
2341                         MultiProcedure<T> procedure) {
2342                 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2343         }
2344
2345         static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2346
2347                 private static Throwable DONE = new Throwable();
2348                 
2349                 private static final long serialVersionUID = -6494230465108115812L;
2350                 
2351                 Throwable exception = null;
2352                 
2353                 @Override
2354                 public synchronized void execute(AsyncReadGraph graph, T t) {
2355                         add(t);
2356                 }
2357
2358                 @Override
2359                 public void finished(AsyncReadGraph graph) {
2360                         exception = DONE;
2361                 }
2362
2363                 @Override
2364                 public void exception(AsyncReadGraph graph, Throwable t) {
2365                         exception = t;
2366                 }
2367                 
2368                 public void checkAndThrow() throws DatabaseException {
2369                         if(exception != DONE) {
2370                                 if (exception instanceof DatabaseException)
2371                                         throw (DatabaseException) exception;
2372                                 else
2373                                         throw new DatabaseException(
2374                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2375                                                         exception);
2376                         }
2377                 }
2378                 
2379                 public boolean done() {
2380                         return exception != null;
2381                 }
2382                 
2383         }
2384
2385         @Override
2386         final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2387                         throws DatabaseException {
2388
2389                 assert (request != null);
2390
2391                 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2392                 
2393                 syncRequest(request, procedure);
2394                 
2395                 procedure.checkAndThrow();
2396                 return procedure;
2397
2398         }
2399
2400         @Override
2401         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2402                         AsyncMultiListener<T> procedure) {
2403                 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2404         }
2405
2406         @Override
2407         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2408                         SyncMultiListener<T> procedure) {
2409                 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2410         }
2411
2412         @Override
2413         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2414                         MultiListener<T> procedure) {
2415                 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2416         }
2417
2418         final private <T> void syncRequest(final AsyncMultiRead<T> request,
2419                         final AsyncMultiReadProcedure<T> procedure) {
2420
2421                 assert (request != null);
2422                 assert (procedure != null);
2423
2424                 ListenerBase listener = getListenerBase(procedure);
2425
2426                 if (parent != null || listener != null) {
2427
2428 //                      Object syncParent = request;
2429
2430 //                      final ReadGraphImpl newGraph = newSync();
2431
2432                         processor.query(this, request, parent, procedure, listener);
2433
2434 //                      newGraph.waitAsync(syncParent);
2435                         waitAsyncProcedure(procedure);
2436
2437                 } else {
2438
2439 //                      Object syncParent = callerThread == Integer.MIN_VALUE ? null
2440 //                                      : request;
2441 //
2442 //                      final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2443
2444                         try {
2445
2446 //                              inc();
2447 //                              ReadGraphImpl sync = newSync();
2448                                 request.perform(this, procedure);
2449 //                              sync.waitAsync(null);
2450                                 waitAsyncProcedure(procedure);
2451 //                              dec();
2452
2453                         } catch (Throwable t) {
2454
2455                                 waitAsyncProcedure(procedure);
2456 //                              dec();
2457
2458                         }
2459
2460                 }
2461
2462         }
2463         
2464         
2465         @Override
2466         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2467                         final AsyncMultiProcedure<T> procedure) {
2468
2469                 assert (request != null);
2470                 assert (procedure != null);
2471
2472                 ListenerBase listener = getListenerBase(procedure);
2473
2474                 if (parent != null || listener != null) {
2475
2476 //                      Object syncParent = request;
2477
2478 //                      final ReadGraphImpl newGraph = newSync();
2479
2480                         processor.query(this, request, parent, procedure, listener);
2481
2482 //                      newGraph.waitAsync(syncParent);
2483
2484                 } else {
2485
2486 //                      Object syncParent = request;
2487
2488 //                      final ReadGraphImpl newGraph = newSync();
2489
2490                         try {
2491
2492                                 request.perform(this, new AsyncMultiProcedure<T>() {
2493
2494                                         @Override
2495                                         public void execute(AsyncReadGraph graph, T result) {
2496                                                 procedure.execute(graph, result);
2497                                         }
2498
2499                                         @Override
2500                                         public void finished(AsyncReadGraph graph) {
2501                                                 procedure.finished(graph);
2502                                         }
2503
2504                                         @Override
2505                                         public void exception(AsyncReadGraph graph, Throwable t) {
2506                                                 procedure.exception(graph, t);
2507                                         }
2508
2509                                         @Override
2510                                         public String toString() {
2511                                                 return "syncRequest(AsyncMultiRead) -> " + procedure;
2512                                         }
2513
2514                                 });
2515
2516                         } catch (Throwable t) {
2517
2518                         }
2519
2520                 }
2521
2522                 // TODO!!
2523                 return null;
2524
2525         }
2526
2527         @Override
2528         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2529                         final SyncMultiProcedure<T> procedure) {
2530                 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2531         }
2532
2533         @Override
2534         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2535                         final MultiProcedure<T> procedure) {
2536                 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2537         }
2538
2539         @Override
2540         public <T> T syncRequest(final ExternalRead<T> request)
2541                         throws DatabaseException {
2542
2543                 assert (request != null);
2544
2545                 return syncRequest(request, new Procedure<T>() {
2546
2547                         @Override
2548                         public void execute(T t) {
2549                         }
2550
2551                         @Override
2552                         public void exception(Throwable t) {
2553                         }
2554
2555                         @Override
2556                         public String toString() {
2557                                 return "syncRequest(AsyncRead) -> " + request;
2558                         }
2559
2560                 });
2561
2562         }
2563
2564         @Override
2565         public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2566                 return syncRequest(request, (Procedure<T>) procedure);
2567         }
2568
2569         @Override
2570         final public <T> T syncRequest(final ExternalRead<T> request,
2571                         final Procedure<T> procedure) throws DatabaseException {
2572
2573                 assert (request != null);
2574
2575                 ListenerBase listener = getListenerBase(procedure);
2576
2577                 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2578                 final DataContainer<T> result = new DataContainer<T>();
2579
2580                 if (parent != null || listener != null) {
2581
2582 //                      final ReadGraphImpl newGraph = newSync();
2583                         
2584                         processor.query(this, request, parent, new Procedure<T>() {
2585
2586                                 @Override
2587                                 public void exception(Throwable throwable) {
2588                                         exception.set(throwable);
2589                                         procedure.exception(throwable);
2590                                 }
2591
2592                                 @Override
2593                                 public void execute(T t) {
2594                                         result.set(t);
2595                                         procedure.execute(t);
2596                                 }
2597
2598                         }, listener);
2599
2600 //                      newGraph.waitAsync(request);
2601
2602                 } else {
2603
2604                         try {
2605
2606                                 T t = processor.tryQuery(this, request);
2607                                 result.set(t);
2608                                 procedure.execute(t);
2609
2610                         } catch (Throwable t) {
2611
2612                             if (t instanceof DatabaseException) {
2613                                 exception.set((DatabaseException)t);
2614                                 procedure.exception(exception.get());
2615                             } else {
2616                                 exception.set(new DatabaseException(
2617                                         "Unexpected exception in ReadGraph.syncRequest(Read)",
2618                                         t));
2619                                 procedure.exception(exception.get());
2620                             }
2621
2622                         }
2623
2624                 }
2625
2626                 Throwable t = exception.get();
2627                 if (t != null) {
2628                         if (t instanceof DatabaseException)
2629                                 throw (DatabaseException) t;
2630                         else
2631                                 throw new DatabaseException(
2632                                                 "Unexpected exception in ReadGraph.syncRequest(Read)",
2633                                                 t);
2634                 }
2635
2636                 return result.get();            
2637
2638         }
2639
2640         @Override
2641         public void syncRequest(final Write request) throws DatabaseException {
2642
2643                 assert (request != null);
2644
2645                 throw new DatabaseException(
2646                                 "Write operations are not supported during read transactions!");
2647
2648         }
2649
2650         @Override
2651         public <T> T syncRequest(final WriteResult<T> request) throws DatabaseException {
2652
2653                 assert (request != null);
2654
2655                 throw new DatabaseException(
2656                                 "Write operations are not supported during read transactions!");
2657
2658         }
2659
2660         @Override
2661         public void syncRequest(final DelayedWrite request)
2662                         throws DatabaseException {
2663
2664                 assert (request != null);
2665
2666                 throw new DatabaseException(
2667                                 "Write operations are not supported during read transactions!");
2668
2669         }
2670
2671         @Override
2672         public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {
2673
2674                 assert (request != null);
2675
2676                 throw new DatabaseException(
2677                                 "Write operations are not supported during read transactions!");
2678
2679         }
2680         
2681         @Override
2682         public void syncRequest(final WriteOnly request) throws DatabaseException {
2683
2684                 assert (request != null);
2685
2686                 throw new DatabaseException(
2687                                 "Write operations are not supported during read transactions!");
2688
2689         }
2690
2691         @Override
2692         public <T> T syncRequest(final WriteOnlyResult<T> request) throws DatabaseException {
2693
2694                 assert (request != null);
2695
2696                 throw new DatabaseException(
2697                                 "Write operations are not supported during read transactions!");
2698
2699         }
2700         
2701         @Override
2702         public <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure) {
2703                 r.request(this, procedure);
2704         }
2705         
2706         @Override
2707         public <T> void async(ReadInterface<T> r, Procedure<T> procedure) {
2708                 r.request(this, procedure);
2709         }
2710         
2711         @Override
2712         public <T> void async(ReadInterface<T> r, SyncProcedure<T> procedure) {
2713                 r.request(this, procedure);
2714         }
2715         
2716         @Override
2717         public <T> void async(ReadInterface<T> r, AsyncListener<T> procedure) {
2718                 r.request(this, procedure);
2719         }
2720         
2721         @Override
2722         public <T> void async(ReadInterface<T> r, Listener<T> procedure) {
2723                 r.request(this, procedure);
2724         }
2725         
2726         @Override
2727         public <T> void async(ReadInterface<T> r, SyncListener<T> procedure) {
2728                 r.request(this, procedure);
2729         }
2730
2731         @Override
2732         public <T> T sync(ReadInterface<T> r) throws DatabaseException {
2733                 return r.request(this);
2734         }
2735         
2736         @Override
2737         public <T> T sync(WriteInterface<T> r) throws DatabaseException {
2738                 return r.request(this);
2739         }
2740         
2741         @Override
2742         public <T> void async(WriteInterface<T> r, Procedure<T> procedure) {
2743                 r.request(this, procedure);
2744         }
2745
2746         @Override
2747         public <T> void async(WriteInterface<T> r) {
2748                 r.request(this, new ProcedureAdapter<T>());
2749         }
2750
2751         /*
2752          * Implementation of the interface AsyncReadGraph
2753          */
2754
2755         @Override
2756         public void forURI(Resource resource, AsyncListener<String> listener) {
2757                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2758                                 listener);
2759         }
2760
2761         @Override
2762         public void forURI(Resource resource, SyncListener<String> listener) {
2763                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2764                                 listener);
2765         }
2766
2767         @Override
2768         public void forURI(Resource resource, Listener<String> listener) {
2769                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2770                                 listener);
2771         }
2772
2773         @Override
2774         final public void forURI(final Resource resource,
2775                         final AsyncProcedure<String> procedure) {
2776
2777                 assert (resource != null);
2778                 assert (procedure != null);
2779
2780                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2781                                 procedure);
2782
2783         }
2784
2785         @Override
2786         public void forURI(Resource resource, SyncProcedure<String> procedure) {
2787                 forURI(resource, new SyncToAsyncProcedure<String>(procedure));
2788         }
2789
2790         @Override
2791         public void forURI(Resource resource, Procedure<String> procedure) {
2792                 forURI(resource, new NoneToAsyncProcedure<String>(procedure));
2793         }
2794         
2795         @Override
2796         public void forResource(String id, AsyncListener<Resource> listener) {
2797                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2798                                 listener);
2799         }
2800
2801         @Override
2802         public void forResource(String id, SyncListener<Resource> listener) {
2803                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2804                                 listener);
2805         }
2806
2807         @Override
2808         public void forResource(String id, Listener<Resource> listener) {
2809                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2810                                 listener);
2811         }
2812
2813         @Override
2814         final public void forResource(final String id,
2815                         final AsyncProcedure<Resource> procedure) {
2816
2817                 assert (id != null);
2818                 assert (procedure != null);
2819
2820                 processor.forResource(this, id, procedure);
2821
2822         }
2823
2824         @Override
2825         public void forResource(String id, SyncProcedure<Resource> procedure) {
2826                 forResource(id, new SyncToAsyncProcedure<Resource>(procedure));
2827         }
2828
2829         @Override
2830         public void forResource(String id, Procedure<Resource> procedure) {
2831                 forResource(id, new NoneToAsyncProcedure<Resource>(procedure));
2832         }
2833
2834         @Override
2835         public void forBuiltin(String id, AsyncListener<Resource> listener) {
2836                 asyncRequest(new Builtin(id), listener);
2837         }
2838
2839         @Override
2840         public void forBuiltin(String id, SyncListener<Resource> listener) {
2841                 asyncRequest(new Builtin(id), listener);
2842         }
2843
2844         @Override
2845         public void forBuiltin(String id, Listener<Resource> listener) {
2846                 asyncRequest(new Builtin(id), listener);
2847         }
2848
2849         @Override
2850         final public void forBuiltin(final String id,
2851                         final AsyncProcedure<Resource> procedure) {
2852
2853                 assert (id != null);
2854                 assert (procedure != null);
2855
2856                 processor.forBuiltin(this, id, procedure);
2857
2858         }
2859
2860         @Override
2861         public void forBuiltin(String id, SyncProcedure<Resource> procedure) {
2862                 forBuiltin(id, new SyncToAsyncProcedure<Resource>(procedure));
2863         }
2864
2865         @Override
2866         public void forBuiltin(String id, Procedure<Resource> procedure) {
2867                 forBuiltin(id, new NoneToAsyncProcedure<Resource>(procedure));
2868         }
2869
2870         @Override
2871         final public void forEachStatement(Resource subject, Resource relation,
2872                         AsyncMultiProcedure<Statement> procedure) {
2873
2874                 assert (subject != null);
2875                 assert (relation != null);
2876                 assert (procedure != null);
2877
2878                 processor.forEachStatement(this, subject, relation, procedure);
2879
2880         }
2881
2882         @Override
2883         public void forEachStatement(Resource subject, Resource relation,
2884                         SyncMultiProcedure<Statement> procedure) {
2885                 forEachStatement(subject, relation,
2886                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2887         }
2888
2889         @Override
2890         final public void forEachStatement(Resource subject, Resource relation,
2891                         MultiProcedure<Statement> procedure) {
2892
2893                 assert (subject != null);
2894                 assert (relation != null);
2895                 assert (procedure != null);
2896
2897                 processor.forEachStatement(this, subject, relation, procedure);
2898
2899         }
2900
2901         @Override
2902         final public void forStatementSet(Resource subject, Resource relation,
2903                         AsyncSetListener<Statement> procedure) {
2904
2905                 assert (subject != null);
2906                 assert (relation != null);
2907                 assert (procedure != null);
2908
2909                 processor.forStatementSet(this, subject, relation, procedure);
2910
2911         }
2912
2913         @Override
2914         final public void forStatementSet(Resource subject, Resource relation,
2915                         SyncSetListener<Statement> procedure) {
2916                 forStatementSet(subject, relation,
2917                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2918         }
2919
2920         @Override
2921         public void forStatementSet(Resource subject, Resource relation,
2922                         SetListener<Statement> listener) {
2923                 forStatementSet(subject, relation,
2924                                 new NoneToAsyncSetProcedure<Statement>(listener));
2925         }
2926
2927         @Override
2928         final public void forEachAssertedStatement(final Resource subject,
2929                         final Resource relation,
2930                         final AsyncMultiProcedure<Statement> procedure) {
2931
2932                 assert (subject != null);
2933                 assert (relation != null);
2934                 assert (procedure != null);
2935
2936                 processor.forEachAssertedStatement(this, subject, relation, procedure);
2937
2938         }
2939
2940         @Override
2941         public void forEachAssertedStatement(Resource subject, Resource relation,
2942                         SyncMultiProcedure<Statement> procedure) {
2943                 forEachAssertedStatement(subject, relation,
2944                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2945         }
2946
2947         @Override
2948         public void forEachAssertedStatement(Resource subject, Resource relation,
2949                         MultiProcedure<Statement> procedure) {
2950                 forEachAssertedStatement(subject, relation,
2951                                 new NoneToAsyncMultiProcedure<Statement>(procedure));
2952         }
2953
2954         @Override
2955         public void forAssertedStatementSet(Resource subject, Resource relation,
2956                         AsyncSetListener<Statement> procedure) {
2957
2958                 assert (subject != null);
2959                 assert (relation != null);
2960                 assert (procedure != null);
2961
2962                 processor.forAssertedStatementSet(this, subject, relation, procedure);
2963
2964         }
2965
2966         @Override
2967         public void forAssertedStatementSet(Resource subject, Resource relation,
2968                         SyncSetListener<Statement> procedure) {
2969
2970                 assert (subject != null);
2971                 assert (relation != null);
2972                 assert (procedure != null);
2973
2974                 forAssertedStatementSet(subject, relation,
2975                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2976
2977         }
2978
2979         @Override
2980         public void forAssertedStatementSet(Resource subject, Resource relation,
2981                         SetListener<Statement> procedure) {
2982
2983                 assert (subject != null);
2984                 assert (relation != null);
2985                 assert (procedure != null);
2986
2987                 forAssertedStatementSet(subject, relation,
2988                                 new NoneToAsyncSetProcedure<Statement>(procedure));
2989
2990         }
2991
2992         @Override
2993         final public void forEachPredicate(final Resource subject,
2994                         final AsyncMultiProcedure<Resource> procedure) {
2995
2996                 assert (subject != null);
2997                 assert (procedure != null);
2998
2999                 processor.forEachPredicate(this, subject, procedure);
3000
3001         }
3002
3003         @Override
3004         public void forEachPredicate(Resource subject,
3005                         SyncMultiProcedure<Resource> procedure) {
3006                 forEachPredicate(subject, new SyncToAsyncMultiProcedure<Resource>(
3007                                 procedure));
3008         }
3009
3010         @Override
3011         final public void forEachPredicate(final Resource subject,
3012                         final MultiProcedure<Resource> procedure) {
3013
3014                 assert (subject != null);
3015                 assert (procedure != null);
3016
3017                 processor.forEachPredicate(this, subject, procedure);
3018
3019         }
3020
3021         @Override
3022         final public void forPredicateSet(final Resource subject,
3023                         final AsyncSetListener<Resource> procedure) {
3024
3025                 assert (subject != null);
3026                 assert (procedure != null);
3027
3028                 processor.forPredicateSet(this, subject, procedure);
3029
3030         }
3031
3032         @Override
3033         final public void forPredicateSet(final Resource subject,
3034                         final SyncSetListener<Resource> procedure) {
3035
3036                 assert (subject != null);
3037                 assert (procedure != null);
3038
3039                 forPredicateSet(subject, new SyncToAsyncSetProcedure<Resource>(
3040                                 procedure));
3041
3042         }
3043
3044         @Override
3045         final public void forPredicateSet(final Resource subject,
3046                         final SetListener<Resource> procedure) {
3047
3048                 assert (subject != null);
3049                 assert (procedure != null);
3050
3051                 forPredicateSet(subject, new NoneToAsyncSetProcedure<Resource>(
3052                                 procedure));
3053
3054         }
3055
3056         @Override
3057         final public void forEachPrincipalType(final Resource subject,
3058                         final AsyncMultiProcedure<Resource> procedure) {
3059
3060                 assert (subject != null);
3061                 assert (procedure != null);
3062
3063                 processor.forEachPrincipalType(this, subject, procedure);
3064
3065         }
3066
3067         @Override
3068         public void forEachPrincipalType(Resource subject,
3069                         SyncMultiProcedure<Resource> procedure) {
3070                 forEachPrincipalType(subject, new SyncToAsyncMultiProcedure<Resource>(
3071                                 procedure));
3072         }
3073
3074         @Override
3075         final public void forEachPrincipalType(final Resource subject,
3076                         final MultiProcedure<Resource> procedure) {
3077
3078                 assert (subject != null);
3079                 assert (procedure != null);
3080
3081                 processor.forEachPrincipalType(this, subject, procedure);
3082
3083         }
3084
3085         @Override
3086         final public void forPrincipalTypeSet(final Resource subject,
3087                         final AsyncSetListener<Resource> procedure) {
3088
3089                 assert (subject != null);
3090                 assert (procedure != null);
3091
3092                 processor.forPrincipalTypeSet(this, subject, procedure);
3093
3094         }
3095
3096         @Override
3097         final public void forPrincipalTypeSet(final Resource subject,
3098                         final SyncSetListener<Resource> procedure) {
3099
3100                 assert (subject != null);
3101                 assert (procedure != null);
3102
3103                 forPrincipalTypeSet(subject, new SyncToAsyncSetProcedure<Resource>(
3104                                 procedure));
3105
3106         }
3107
3108         @Override
3109         final public void forPrincipalTypeSet(final Resource subject,
3110                         final SetListener<Resource> procedure) {
3111
3112                 assert (subject != null);
3113                 assert (procedure != null);
3114
3115                 forPrincipalTypeSet(subject, new NoneToAsyncSetProcedure<Resource>(
3116                                 procedure));
3117
3118         }
3119
3120         @Override
3121         public void forTypes(Resource subject, AsyncListener<Set<Resource>> listener) {
3122                 asyncRequest(new Types(subject), listener);
3123         }
3124
3125         @Override
3126         public void forTypes(Resource subject, SyncListener<Set<Resource>> listener) {
3127                 asyncRequest(new Types(subject), listener);
3128         }
3129
3130         @Override
3131         public void forTypes(Resource subject, Listener<Set<Resource>> listener) {
3132                 asyncRequest(new Types(subject), listener);
3133         }
3134
3135         @Override
3136         final public void forTypes(final Resource subject,
3137                         final AsyncProcedure<Set<Resource>> procedure) {
3138
3139                 assert (subject != null);
3140                 assert (procedure != null);
3141
3142                 processor.forTypes(this, subject, procedure);
3143
3144         }
3145
3146         @Override
3147         public void forTypes(Resource subject,
3148                         SyncProcedure<Set<Resource>> procedure) {
3149                 forTypes(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
3150         }
3151
3152         @Override
3153         public void forTypes(Resource subject, Procedure<Set<Resource>> procedure) {
3154                 forTypes(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
3155         }
3156
3157         @Override
3158         public void forSupertypes(Resource subject,
3159                         AsyncListener<Set<Resource>> listener) {
3160                 asyncRequest(new Types(subject), listener);
3161         }
3162
3163         @Override
3164         public void forSupertypes(Resource subject,
3165                         SyncListener<Set<Resource>> listener) {
3166                 asyncRequest(new Types(subject), listener);
3167         }
3168
3169         @Override
3170         public void forSupertypes(Resource subject, Listener<Set<Resource>> listener) {
3171                 asyncRequest(new Types(subject), listener);
3172         }
3173
3174         @Override
3175         final public void forSupertypes(final Resource subject,
3176                         final AsyncProcedure<Set<Resource>> procedure) {
3177
3178                 assert (subject != null);
3179                 assert (procedure != null);
3180
3181                 processor.forSupertypes(this, subject, procedure);
3182
3183         }
3184
3185         @Override
3186         public void forSupertypes(Resource subject,
3187                         SyncProcedure<Set<Resource>> procedure) {
3188                 forSupertypes(subject, new SyncToAsyncProcedure<Set<Resource>>(
3189                                 procedure));
3190         }
3191
3192         @Override
3193         public void forSupertypes(Resource subject,
3194                         Procedure<Set<Resource>> procedure) {
3195                 forSupertypes(subject, new NoneToAsyncProcedure<Set<Resource>>(
3196                                 procedure));
3197         }
3198
3199         @Override
3200         public void forDirectSuperrelations(Resource subject,
3201                         AsyncMultiProcedure<Resource> procedure) {
3202                 
3203                 assert (subject != null);
3204                 assert (procedure != null);
3205
3206                 processor.forDirectSuperrelations(this, subject, procedure);
3207                 
3208         }
3209
3210         @Override
3211         public void forPossibleSuperrelation(Resource subject, AsyncProcedure<Resource> procedure) {
3212                 
3213                 assert (subject != null);
3214                 assert (procedure != null);
3215
3216                 processor.forPossibleSuperrelation(this, subject, procedure);
3217                 
3218         }
3219
3220         @Override
3221         public void forSuperrelations(Resource subject,
3222                         AsyncListener<Set<Resource>> listener) {
3223                 asyncRequest(new Types(subject), listener);
3224         }
3225
3226         @Override
3227         public void forSuperrelations(Resource subject,
3228                         SyncListener<Set<Resource>> listener) {
3229                 asyncRequest(new Types(subject), listener);
3230         }
3231
3232         @Override
3233         public void forSuperrelations(Resource subject,
3234                         Listener<Set<Resource>> listener) {
3235                 asyncRequest(new Types(subject), listener);
3236         }
3237
3238         @Override
3239         final public void forSuperrelations(final Resource subject,
3240                         final AsyncProcedure<Set<Resource>> procedure) {
3241
3242                 assert (subject != null);
3243                 assert (procedure != null);
3244
3245                 processor.forSuperrelations(this, subject, procedure);
3246
3247         }
3248
3249         @Override
3250         public void forSuperrelations(Resource subject,
3251                         SyncProcedure<Set<Resource>> procedure) {
3252                 forSuperrelations(subject, new SyncToAsyncProcedure<Set<Resource>>(
3253                                 procedure));
3254         }
3255
3256         @Override
3257         public void forSuperrelations(Resource subject,
3258                         Procedure<Set<Resource>> procedure) {
3259                 forSuperrelations(subject, new NoneToAsyncProcedure<Set<Resource>>(
3260                                 procedure));
3261         }
3262
3263         @Override
3264         final public void forEachObject(final Resource subject, final Resource relation, final AsyncMultiProcedure<Resource> procedure) {
3265                 processor.forEachObject(this, subject, relation, procedure);
3266         }
3267
3268         @Override
3269         public void forEachObject(Resource subject, Resource relation,
3270                         SyncMultiProcedure<Resource> procedure) {
3271                 forEachObject(subject, relation,
3272                                 new SyncToAsyncMultiProcedure<Resource>(procedure));
3273         }
3274
3275         @Override
3276         public void forEachObject(Resource subject, Resource relation,
3277                         MultiProcedure<Resource> procedure) {
3278
3279                 processor.forEachObject(this, subject, relation, procedure);
3280
3281         }
3282
3283 //      @Override
3284 //      final public void forEachDirectObject(final Resource subject,
3285 //                      final Resource relation,
3286 //                      final AsyncMultiProcedure<Resource> procedure) {
3287 //
3288 //              processor.forEachDirectObject(this, subject, relation, procedure);
3289 //
3290 //      }
3291 //
3292 //      @Override
3293 //      public void forEachDirectObject(Resource subject, Resource relation,
3294 //                      SyncMultiProcedure<Resource> procedure) {
3295 //              forEachDirectObject(subject, relation,
3296 //                              new SyncToAsyncMultiProcedure<Resource>(procedure));
3297 //      }
3298 //
3299 //      @Override
3300 //      public void forEachDirectObject(Resource subject, Resource relation,
3301 //                      MultiProcedure<Resource> procedure) {
3302 //              forEachDirectObject(subject, relation,
3303 //                              new NoneToAsyncMultiProcedure<Resource>(procedure));
3304 //      }
3305         
3306         @Override
3307         final public void forEachDirectPredicate(final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
3308                 processor.forEachDirectPredicate(this, subject, procedure);
3309         }
3310
3311         @Override
3312         public void forEachDirectPredicate(Resource subject, SyncMultiProcedure<Resource> procedure) {
3313                 forEachDirectPredicate(subject, new SyncToAsyncMultiProcedure<Resource>(procedure));
3314         }
3315
3316         @Override
3317         public void forEachDirectPredicate(Resource subject, MultiProcedure<Resource> procedure) {
3318                 forEachDirectPredicate(subject, new NoneToAsyncMultiProcedure<Resource>(procedure));
3319         }
3320
3321         @Override
3322         final public void forObjectSet(final Resource subject,
3323                         final Resource relation, final AsyncSetListener<Resource> procedure) {
3324
3325                 assert (subject != null);
3326                 assert (relation != null);
3327                 assert (procedure != null);
3328
3329                 processor.forObjectSet(this, subject, relation, procedure);
3330
3331         }
3332
3333         @Override
3334         final public void forObjectSet(final Resource subject,
3335                         final Resource relation, final SyncSetListener<Resource> procedure) {
3336
3337                 assert (subject != null);
3338                 assert (relation != null);
3339                 assert (procedure != null);
3340
3341                 forObjectSet(subject, relation, new SyncToAsyncSetProcedure<Resource>(
3342                                 procedure));
3343
3344         }
3345
3346         @Override
3347         final public void forObjectSet(final Resource subject,
3348                         final Resource relation, final SetListener<Resource> procedure) {
3349
3350                 assert (subject != null);
3351                 assert (relation != null);
3352                 assert (procedure != null);
3353
3354                 forObjectSet(subject, relation, new NoneToAsyncSetProcedure<Resource>(
3355                                 procedure));
3356
3357         }
3358
3359         @Override
3360         final public void forEachAssertedObject(final Resource subject,
3361                         final Resource relation,
3362                         final AsyncMultiProcedure<Resource> procedure) {
3363
3364                 assert (subject != null);
3365                 assert (relation != null);
3366                 assert (procedure != null);
3367
3368                 processor.forEachAssertedObject(this, subject, relation, procedure);
3369
3370         }
3371
3372         @Override
3373         public void forEachAssertedObject(Resource subject, Resource relation,
3374                         SyncMultiProcedure<Resource> procedure) {
3375
3376                 assert (subject != null);
3377                 assert (relation != null);
3378                 assert (procedure != null);
3379
3380                 forEachAssertedObject(subject, relation,
3381                                 new SyncToAsyncMultiProcedure<Resource>(procedure));
3382
3383         }
3384
3385         @Override
3386         public void forEachAssertedObject(Resource subject, Resource relation,
3387                         MultiProcedure<Resource> procedure) {
3388
3389                 assert (subject != null);
3390                 assert (relation != null);
3391                 assert (procedure != null);
3392
3393                 forEachAssertedObject(subject, relation,
3394                                 new NoneToAsyncMultiProcedure<Resource>(procedure));
3395
3396         }
3397
3398         @Override
3399         public void forAssertedObjectSet(Resource subject, Resource relation,
3400                         AsyncSetListener<Resource> procedure) {
3401
3402                 assert (subject != null);
3403                 assert (relation != null);
3404                 assert (procedure != null);
3405
3406                 processor.forAssertedObjectSet(this, subject, relation, procedure);
3407
3408         }
3409
3410         @Override
3411         public void forAssertedObjectSet(Resource subject, Resource relation,
3412                         SyncSetListener<Resource> procedure) {
3413
3414                 assert (subject != null);
3415                 assert (relation != null);
3416                 assert (procedure != null);
3417
3418                 forAssertedObjectSet(subject, relation,
3419                                 new SyncToAsyncSetProcedure<Resource>(procedure));
3420
3421         }
3422
3423         @Override
3424         public void forAssertedObjectSet(Resource subject, Resource relation,
3425                         SetListener<Resource> procedure) {
3426
3427                 assert (subject != null);
3428                 assert (relation != null);
3429                 assert (procedure != null);
3430
3431                 forAssertedObjectSet(subject, relation,
3432                                 new NoneToAsyncSetProcedure<Resource>(procedure));
3433
3434         }
3435
3436         @Override
3437         public void forInverse(Resource relation, AsyncListener<Resource> listener) {
3438                 asyncRequest(new Inverse(relation), listener);
3439         }
3440
3441         @Override
3442         public void forInverse(Resource relation, SyncListener<Resource> listener) {
3443                 asyncRequest(new Inverse(relation), listener);
3444         }
3445
3446         @Override
3447         public void forInverse(Resource relation, Listener<Resource> listener) {
3448                 asyncRequest(new Inverse(relation), listener);
3449         }
3450
3451         @Override
3452         final public void forInverse(final Resource relation,
3453                         final AsyncProcedure<Resource> procedure) {
3454
3455                 assert (relation != null);
3456                 assert (procedure != null);
3457
3458                 processor.forInverse(this, relation, new AsyncProcedure<Resource>() {
3459
3460                         @Override
3461                         public void execute(AsyncReadGraph graph, Resource result) {
3462                                 if (result != null)
3463                                         procedure.execute(graph, result);
3464                                 else {
3465                                         procedure.exception(graph, new NoInverseException(relation
3466                                                         .toString()));
3467                                 }
3468                         }
3469
3470                         @Override
3471                         public void exception(AsyncReadGraph graph, Throwable throwable) {
3472                                 procedure.exception(graph, throwable);
3473                         }
3474
3475                         @Override
3476                         public String toString() {
3477                                 return "forInverse -> " + procedure;
3478                         }
3479
3480                 });
3481
3482         }
3483
3484         @Override
3485         public void forInverse(Resource relation, SyncProcedure<Resource> procedure) {
3486                 forInverse(relation, new SyncToAsyncProcedure<Resource>(procedure));
3487         }
3488
3489         @Override
3490         public void forInverse(Resource relation, Procedure<Resource> procedure) {
3491                 forInverse(relation, new NoneToAsyncProcedure<Resource>(procedure));
3492         }
3493
3494         @Override
3495         public void forSingleObject(Resource subject, Resource relation,
3496                         AsyncListener<Resource> listener) {
3497                 asyncRequest(new SingleObject(subject, relation), listener);
3498         }
3499
3500         @Override
3501         public void forSingleObject(Resource subject, Resource relation,
3502                         SyncListener<Resource> listener) {
3503                 asyncRequest(new SingleObject(subject, relation), listener);
3504         }
3505
3506         @Override
3507         public void forSingleObject(Resource subject, Resource relation,
3508                         Listener<Resource> listener) {
3509                 asyncRequest(new SingleObject(subject, relation), listener);
3510         }
3511
3512         @Override
3513         final public void forSingleObject(final Resource subject,
3514                         final Resource relation, final AsyncProcedure<Resource> procedure) {
3515
3516                 assert (subject != null);
3517                 assert (relation != null);
3518                 assert (procedure != null);
3519
3520                 processor.forEachObject(this, subject, relation,
3521                                 new SingleOrErrorProcedure<Resource>(procedure));
3522
3523         }
3524
3525         @Override
3526         public void forSingleObject(Resource subject, Resource relation,
3527                         SyncProcedure<Resource> procedure) {
3528                 forSingleObject(subject, relation, new SyncToAsyncProcedure<Resource>(
3529                                 procedure));
3530         }
3531
3532         @Override
3533         public void forSingleObject(Resource subject, Resource relation,
3534                         Procedure<Resource> procedure) {
3535                 forSingleObject(subject, relation, new NoneToAsyncProcedure<Resource>(
3536                                 procedure));
3537         }
3538
3539         @Override
3540         public void forSingleStatement(Resource subject, Resource relation,
3541                         AsyncListener<Statement> listener) {
3542                 asyncRequest(new SingleStatement(subject, relation), listener);
3543         }
3544
3545         @Override
3546         public void forSingleStatement(Resource subject, Resource relation,
3547                         SyncListener<Statement> listener) {
3548                 asyncRequest(new SingleStatement(subject, relation), listener);
3549         }
3550
3551         @Override
3552         public void forSingleStatement(Resource subject, Resource relation,
3553                         Listener<Statement> listener) {
3554                 asyncRequest(new SingleStatement(subject, relation), listener);
3555         }
3556
3557         @Override
3558         final public void forSingleStatement(final Resource subject,
3559                         final Resource relation, final AsyncProcedure<Statement> procedure) {
3560
3561                 assert (subject != null);
3562                 assert (relation != null);
3563                 assert (procedure != null);
3564
3565                 processor.forEachStatement(this, subject, relation,
3566                                 new SingleOrErrorProcedure<Statement>(procedure));
3567
3568         }
3569
3570         @Override
3571         public void forSingleStatement(Resource subject, Resource relation,
3572                         SyncProcedure<Statement> procedure) {
3573                 forSingleStatement(subject, relation,
3574                                 new SyncToAsyncProcedure<Statement>(procedure));
3575         }
3576
3577         @Override
3578         public void forSingleStatement(Resource subject, Resource relation,
3579                         Procedure<Statement> procedure) {
3580                 forSingleStatement(subject, relation,
3581                                 new NoneToAsyncProcedure<Statement>(procedure));
3582         }
3583
3584         @Override
3585         public void forSingleType(Resource subject,
3586                         AsyncListener<Resource> listener) {
3587                 asyncRequest(new SingleTypeAny(subject), listener);
3588         }
3589
3590         @Override
3591         public void forSingleType(Resource subject,
3592                         SyncListener<Resource> listener) {
3593                 asyncRequest(new SingleTypeAny(subject), listener);
3594         }
3595
3596         @Override
3597         public void forSingleType(Resource subject,
3598                         Listener<Resource> listener) {
3599                 asyncRequest(new SingleTypeAny(subject), listener);
3600         }
3601
3602         @Override
3603         final public void forSingleType(final Resource subject, final AsyncProcedure<Resource> procedure) {
3604
3605                 assert (subject != null);
3606                 assert (procedure != null);
3607
3608                 final DeepSingleOrErrorProcedure<Resource> checkedProcedure = new DeepSingleOrErrorProcedure<Resource>(procedure);
3609
3610                 processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter<Resource>() {
3611
3612                         @Override
3613                         public void execute(AsyncReadGraph graph, final Resource principalType) {
3614                                 checkedProcedure.offer(graph, principalType);
3615                         }
3616
3617                         @Override
3618                         public void finished(AsyncReadGraph graph) {
3619                                 checkedProcedure.dec(graph);
3620                         }
3621
3622                         @Override
3623                         public void exception(AsyncReadGraph graph, Throwable t) {
3624                                 checkedProcedure.exception(graph, t);
3625                         }
3626
3627                         @Override
3628                         public String toString() {
3629                                 return "forSingleType -> " + procedure;
3630                         }
3631
3632                 });
3633
3634         }
3635
3636         @Override
3637         public void forSingleType(Resource subject, SyncProcedure<Resource> procedure) {
3638                 forSingleType(subject, new SyncToAsyncProcedure<Resource>(
3639                                 procedure));
3640         }
3641
3642         @Override
3643         public void forSingleType(Resource subject, Procedure<Resource> procedure) {
3644                 forSingleType(subject, new NoneToAsyncProcedure<Resource>(
3645                                 procedure));
3646         }
3647
3648         @Override
3649         public void forSingleType(Resource subject, Resource relation,
3650                         AsyncListener<Resource> listener) {
3651                 asyncRequest(new SingleType(subject, relation), listener);
3652         }
3653
3654         @Override
3655         public void forSingleType(Resource subject, Resource relation,
3656                         SyncListener<Resource> listener) {
3657                 asyncRequest(new SingleType(subject, relation), listener);
3658         }
3659
3660         @Override
3661         public void forSingleType(Resource subject, Resource relation,
3662                         Listener<Resource> listener) {
3663                 asyncRequest(new SingleType(subject, relation), listener);
3664         }
3665
3666         @Override
3667         final public void forSingleType(final Resource subject,
3668                         final Resource baseType, final AsyncProcedure<Resource> procedure) {
3669
3670                 assert (subject != null);
3671                 assert (procedure != null);
3672
3673                 final DeepSingleOrErrorProcedure<Resource> checkedProcedure = new DeepSingleOrErrorProcedure<Resource>(procedure);
3674
3675                 processor.forEachPrincipalType(this, subject,
3676                                 new AsyncMultiProcedureAdapter<Resource>() {
3677
3678                                         @Override
3679                                         public void execute(AsyncReadGraph graph,
3680                                                         final Resource principalType) {
3681
3682                                                 checkedProcedure.inc();
3683
3684                                                 if(baseType == null) {
3685
3686                                                         checkedProcedure.offer(graph, principalType);
3687                                                         checkedProcedure.dec(graph);
3688
3689                                                 } else if(principalType.equals(baseType)) {
3690
3691                                                         checkedProcedure.offer(graph, principalType);
3692                                                         checkedProcedure.dec(graph);
3693
3694                                                 } else {
3695
3696                                                         processor.forSupertypes((ReadGraphImpl)graph, principalType,
3697                                                                         new AsyncProcedure<Set<Resource>>() {
3698
3699                                                                                 @Override
3700                                                                                 public void execute(
3701                                                                                                 AsyncReadGraph graph,
3702                                                                                                 Set<Resource> result) {
3703
3704                                                                                         if (result.contains(baseType))
3705                                                                                                 checkedProcedure.offer(graph,
3706                                                                                                                 principalType);
3707                                                                                         checkedProcedure.dec(graph);
3708
3709                                                                                 }
3710
3711                                                                                 @Override
3712                                                                                 public void exception(
3713                                                                                                 AsyncReadGraph graph,
3714                                                                                                 Throwable t) {
3715                                                                                         checkedProcedure
3716                                                                                                         .exception(graph, t);
3717                                                                                 }
3718
3719                                                                         });
3720
3721                                                 }
3722
3723                                         }
3724
3725                                         @Override
3726                                         public void finished(AsyncReadGraph graph) {
3727                                                 checkedProcedure.dec(graph);
3728                                         }
3729
3730                                         @Override
3731                                         public void exception(AsyncReadGraph graph, Throwable t) {
3732                                                 checkedProcedure.exception(graph, t);
3733                                         }
3734
3735                                         @Override
3736                                         public String toString() {
3737                                                 return "forSingleType -> " + procedure;
3738                                         }
3739
3740                                 });
3741
3742         }
3743
3744         @Override
3745         public void forSingleType(Resource subject, Resource relation,
3746                         SyncProcedure<Resource> procedure) {
3747                 forSingleType(subject, relation, new SyncToAsyncProcedure<Resource>(
3748                                 procedure));
3749         }
3750
3751         @Override
3752         public void forSingleType(Resource subject, Resource relation,
3753                         Procedure<Resource> procedure) {
3754                 forSingleType(subject, relation, new NoneToAsyncProcedure<Resource>(
3755                                 procedure));
3756         }
3757
3758         @Override
3759         public <T> void forValue(Resource subject, Binding binding,
3760                         AsyncListener<T> listener) {
3761                 asyncRequest(new Value<T>(subject, binding), listener);
3762         }
3763
3764         @Override
3765         public <T> void forValue(Resource subject, Binding binding,
3766                         SyncListener<T> listener) {
3767                 asyncRequest(new Value<T>(subject, binding), listener);
3768         }
3769
3770         @Override
3771         public <T> void forValue(Resource subject, Binding binding,
3772                         Listener<T> listener) {
3773                 asyncRequest(new Value<T>(subject, binding), listener);
3774         }
3775
3776         @Override
3777         public <T> void forValue(final Resource resource, final Binding binding,
3778                         final AsyncProcedure<T> procedure) {
3779
3780                 assert (resource != null);
3781                 assert (binding != null);
3782                 assert (procedure != null);
3783                 
3784                 processor.forValue(this, resource, new AsyncProcedure<byte[]>() {
3785
3786                         @Override
3787                         public void execute(AsyncReadGraph graph, byte[] result) {
3788                                 
3789                                 try {
3790
3791                                         if (result == null) {
3792                                                 procedure.exception(graph,
3793                                                                 new DoesNotContainValueException(
3794                                                                                 "No value for resource " + resource));
3795                                                 return;
3796                                         }
3797
3798                                         Serializer serializer = binding.serializer();
3799 //                                      Serializer serializer = Bindings.getSerializer( binding );
3800                                         Object obj = serializer.deserialize(result);
3801 //                                      if (!binding.isInstance(obj))
3802 //                                              procedure.exception(graph, new ClassCastException(
3803 //                                                              "Cannot get value " + obj + " with binding "
3804 //                                                                              + binding));
3805 //                                      else
3806                                                 procedure.execute(graph, (T) obj);
3807
3808                                 } catch (IOException e) {
3809                                         procedure.exception(graph, e);
3810                                 } catch (BufferUnderflowException e) {
3811                                         procedure.exception(graph, e);
3812                                 } catch (Throwable t) {
3813                                         procedure.exception(graph, t);
3814                                 }
3815
3816                         }
3817
3818                         @Override
3819                         public void exception(AsyncReadGraph graph, Throwable t) {
3820                                 try {
3821                                         procedure.exception(graph, t);
3822                                 } catch (Throwable t2) {
3823                                 Logger.defaultLogError(t2);
3824                                 }
3825                         }
3826
3827                         @Override
3828                         public String toString() {
3829                                 return "forValue -> " + procedure;
3830                         }
3831
3832                 });
3833
3834         }
3835
3836         @Override
3837         public <T> void forValue(Resource subject, Binding binding,
3838                         SyncProcedure<T> procedure) {
3839                 forValue(subject, binding, new SyncToAsyncProcedure<T>(procedure));
3840         }
3841
3842         @Override
3843         public <T> void forValue(Resource subject, Binding binding,
3844                         Procedure<T> procedure) {
3845                 forValue(subject, binding, new NoneToAsyncProcedure<T>(procedure));
3846         }
3847
3848         @Override
3849         public <T> void forValue(Resource subject, AsyncListener<T> listener) {
3850                 asyncRequest(new ValueImplied<T>(subject), listener);
3851         }
3852
3853         @Override
3854         public <T> void forValue(Resource subject, SyncListener<T> listener) {
3855                 asyncRequest(new ValueImplied<T>(subject), listener);
3856         }
3857
3858         @Override
3859         public <T> void forValue(Resource subject, Listener<T> listener) {
3860                 asyncRequest(new ValueImplied<T>(subject), listener);
3861         }
3862
3863         @Override
3864         final public <T> void forValue(final Resource subject, final AsyncProcedure<T> procedure) {
3865
3866                 assert (subject != null);
3867                 assert (procedure != null);
3868                 
3869                 forRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure<Datatype>() {
3870
3871                         @Override
3872                         public void execute(AsyncReadGraph graph, Datatype type) {
3873                                 // TODO: consider trying Bindings.getBeanBinding(type);
3874                                 Binding binding = Bindings.getBinding(type);
3875                                 graph.forValue(subject, binding, procedure);
3876                         }
3877
3878                         @Override
3879                         public void exception(AsyncReadGraph graph, Throwable throwable) {
3880                                 procedure.exception(graph, new DoesNotContainValueException("Invalid data type", throwable));
3881                         }
3882                         
3883                 });
3884
3885         }
3886
3887         @Override
3888         public <T> void forValue(Resource subject, SyncProcedure<T> procedure) {
3889                 forValue(subject, new SyncToAsyncProcedure<T>(procedure));
3890         }
3891
3892         @Override
3893         public <T> void forValue(Resource subject, Procedure<T> procedure) {
3894                 forValue(subject, new NoneToAsyncProcedure<T>(procedure));
3895         }
3896
3897         @Override
3898         public <T> void forRelatedValue(Resource subject, Resource relation,
3899                         AsyncListener<T> listener) {
3900                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3901         }
3902
3903         @Override
3904         public <T> void forRelatedValue(Resource subject, Resource relation,
3905                         SyncListener<T> listener) {
3906                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3907         }
3908
3909         @Override
3910         public <T> void forRelatedValue(Resource subject, Resource relation,
3911                         Listener<T> listener) {
3912                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3913         }
3914
3915         @Override
3916         final public <T> void forRelatedValue(final Resource subject,
3917                         final Resource relation, final AsyncProcedure<T> procedure) {
3918
3919                 assert (subject != null);
3920                 assert (relation != null);
3921                 assert (procedure != null);
3922
3923                 final DeepSingleOrErrorProcedure<T> checkedProcedure = new DeepSingleOrErrorProcedure<T>(procedure);
3924
3925                 processor.forEachObject(this, subject, relation,
3926                                 new AsyncMultiProcedureAdapter<Resource>() {
3927
3928                                         @Override
3929                                         public void execute(AsyncReadGraph graph,
3930                                                         final Resource object) {
3931
3932                                                 checkedProcedure.inc();
3933
3934                                                 graph.forValue(object, new AsyncProcedure<Object>() {
3935
3936                                                         @Override
3937                                                         public void execute(AsyncReadGraph graph,
3938                                                                         Object result) {
3939                                                                 checkedProcedure.offer(graph, (T) result);
3940                                                                 checkedProcedure.dec(graph);
3941                                                         }
3942
3943                                                         @Override
3944                                                         public void exception(AsyncReadGraph graph,
3945                                                                         Throwable t) {
3946                                                                 checkedProcedure.exception(graph, t);
3947                                                         }
3948
3949                                                         @Override
3950                                                         public String toString() {
3951                                                                 return "forRelatedValue -> " + procedure;
3952                                                         }
3953
3954                                                 });
3955
3956                                         }
3957
3958                                         @Override
3959                                         public void finished(AsyncReadGraph graph) {
3960                                                 checkedProcedure.dec(graph);
3961                                         }
3962
3963                                         @Override
3964                                         public void exception(AsyncReadGraph graph, Throwable t) {
3965                                                 checkedProcedure.exception(graph, t);
3966                                         }
3967
3968                                 });
3969
3970         }
3971
3972         @Override
3973         public <T> void forRelatedValue(Resource subject, Resource relation,
3974                         SyncProcedure<T> procedure) {
3975                 forRelatedValue(subject, relation, new SyncToAsyncProcedure<T>(
3976                                 procedure));
3977         }
3978
3979         @Override
3980         public <T> void forRelatedValue(Resource subject, Resource relation,
3981                         Procedure<T> procedure) {
3982                 forRelatedValue(subject, relation, new NoneToAsyncProcedure<T>(
3983                                 procedure));
3984         }
3985
3986         @Override
3987         public <T> void forRelatedValue(Resource subject, Resource relation,
3988                         Binding binding, AsyncListener<T> listener) {
3989                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3990         }
3991
3992         @Override
3993         public <T> void forRelatedValue(Resource subject, Resource relation,
3994                         Binding binding, SyncListener<T> listener) {
3995                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3996         }
3997
3998         @Override
3999         public <T> void forRelatedValue(Resource subject, Resource relation,
4000                         Binding binding, Listener<T> listener) {
4001                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
4002         }
4003
4004         @Override
4005         final public <T> void forRelatedValue(final Resource subject,
4006                         final Resource relation, final Binding binding,
4007                         final AsyncProcedure<T> procedure) {
4008
4009                 assert (subject != null);
4010                 assert (relation != null);
4011                 assert (binding != null);
4012                 assert (procedure != null);
4013
4014                 final DeepSingleOrErrorProcedure<T> checkedProcedure = new DeepSingleOrErrorProcedure<T>(procedure);
4015                 
4016                 processor.forEachObject(this, subject, relation,
4017                                 new AsyncMultiProcedureAdapter<Resource>() {
4018
4019                                         @Override
4020                                         public void execute(AsyncReadGraph graph,
4021                                                         final Resource object) {
4022
4023                                                 checkedProcedure.inc();
4024
4025                                                 graph.forValue(object, binding, new AsyncProcedure<Object>() {
4026
4027                                                                         @Override
4028                                                                         public void execute(AsyncReadGraph graph,
4029                                                                                         Object result) {
4030                                                                                 
4031                                                                                 checkedProcedure.offer(graph,
4032                                                                                                 (T) result);
4033                                                                                 checkedProcedure.dec(graph);
4034                                                                         }
4035
4036                                                                         @Override
4037                                                                         public void exception(AsyncReadGraph graph,
4038                                                                                         Throwable t) {
4039                                                                                 checkedProcedure.exception(graph, t);
4040                                                                         }
4041
4042                                                                         @Override
4043                                                                         public String toString() {
4044                                                                                 return "forRelatedValue -> "
4045                                                                                                 + procedure;
4046                                                                         }
4047
4048                                                                 });
4049
4050                                         }
4051
4052                                         @Override
4053                                         public void finished(AsyncReadGraph graph) {
4054                                                 checkedProcedure.dec(graph);
4055                                         }
4056
4057                                         @Override
4058                                         public void exception(AsyncReadGraph graph, Throwable t) {
4059                                                 checkedProcedure.exception(graph, t);
4060                                         }
4061
4062                                 });
4063
4064         }
4065
4066         @Override
4067         public <T> void forRelatedValue(Resource subject, Resource relation,
4068                         Binding binding, SyncProcedure<T> procedure) {
4069                 forRelatedValue(subject, relation, binding,
4070                                 new SyncToAsyncProcedure<T>(procedure));
4071         }
4072
4073         @Override
4074         public <T> void forRelatedValue(Resource subject, Resource relation,
4075                         Binding binding, Procedure<T> procedure) {
4076                 forRelatedValue(subject, relation, binding,
4077                                 new NoneToAsyncProcedure<T>(procedure));
4078         }
4079
4080         @Override
4081         public <T> void forAdapted(Resource resource, Class<T> clazz,
4082                         AsyncListener<T> listener) {
4083                 asyncRequest(new Adapter<T>(resource, clazz), listener);
4084         }
4085
4086         @Override
4087         public <T> void forAdapted(Resource resource, Class<T> clazz,
4088                         SyncListener<T> listener) {
4089                 asyncRequest(new Adapter<T>(resource, clazz), listener);
4090         }
4091
4092         @Override
4093         public <T> void forAdapted(Resource resource, Class<T> clazz,
4094                         Listener<T> listener) {
4095                 asyncRequest(new Adapter<T>(resource, clazz), listener);
4096         }
4097
4098         @Override
4099         final public <T> void forAdapted(final Resource resource,
4100                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
4101
4102                 assert (resource != null);
4103                 assert (clazz != null);
4104                 assert (procedure != null);
4105
4106                 final AdaptionService service = getSession().peekService(AdaptionService.class);
4107                 if (service == null)
4108                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
4109                 else
4110                         service.adapt(this, resource, resource, Resource.class, clazz, false, procedure); 
4111
4112         }
4113
4114         @Override
4115         public <T> void forAdapted(Resource resource, Class<T> clazz,
4116                         SyncProcedure<T> procedure) {
4117                 forAdapted(resource, clazz, new SyncToAsyncProcedure<T>(procedure));
4118         }
4119
4120         @Override
4121         public <T> void forAdapted(Resource resource, Class<T> clazz,
4122                         Procedure<T> procedure) {
4123                 forAdapted(resource, clazz, new NoneToAsyncProcedure<T>(procedure));
4124         }
4125
4126         @Override
4127         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
4128                         AsyncListener<T> listener) {
4129                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
4130         }
4131
4132         @Override
4133         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
4134                         SyncListener<T> listener) {
4135                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
4136         }
4137
4138         @Override
4139         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
4140                         Listener<T> listener) {
4141                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
4142         }
4143
4144         @Override
4145         final public <T> void forUniqueAdapted(final Resource resource,
4146                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
4147
4148                 assert (resource != null);
4149                 assert (clazz != null);
4150                 assert (procedure != null);
4151
4152                 final AdaptionService service = getSession().peekService(AdaptionService.class);
4153                 if (service == null)
4154                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
4155                 else
4156                         service.adaptNew(this, resource, clazz, false, procedure);
4157
4158         }
4159
4160         @Override
4161         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
4162                         SyncProcedure<T> procedure) {
4163                 forUniqueAdapted(resource, clazz,
4164                                 new SyncToAsyncProcedure<T>(procedure));
4165         }
4166
4167         @Override
4168         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
4169                         Procedure<T> procedure) {
4170                 forUniqueAdapted(resource, clazz,
4171                                 new NoneToAsyncProcedure<T>(procedure));
4172         }
4173
4174         @Override
4175         public void forPossibleInverse(Resource subject,
4176                         AsyncListener<Resource> listener) {
4177                 asyncRequest(new PossibleInverse(subject), listener);
4178         }
4179
4180         @Override
4181         public void forPossibleInverse(Resource subject,
4182                         SyncListener<Resource> listener) {
4183                 asyncRequest(new PossibleInverse(subject), listener);
4184         }
4185
4186         @Override
4187         public void forPossibleInverse(Resource subject, Listener<Resource> listener) {
4188                 asyncRequest(new PossibleInverse(subject), listener);
4189         }
4190
4191         @Override
4192         final public void forPossibleInverse(final Resource relation,
4193                         final AsyncProcedure<Resource> procedure) {
4194
4195                 assert (relation != null);
4196                 assert (procedure != null);
4197
4198                 processor.forInverse(this, relation, new ExceptionToNullProcedure<Resource>(procedure));
4199
4200         }
4201
4202         @Override
4203         public void forPossibleInverse(Resource subject,
4204                         SyncProcedure<Resource> procedure) {
4205                 forPossibleInverse(subject, new SyncToAsyncProcedure<Resource>(
4206                                 procedure));
4207         }
4208
4209         @Override
4210         public void forPossibleInverse(Resource subject,
4211                         Procedure<Resource> procedure) {
4212                 forPossibleInverse(subject, new NoneToAsyncProcedure<Resource>(
4213                                 procedure));
4214         }
4215
4216         @Override
4217         public void forPossibleObject(Resource subject, Resource relation,
4218                         AsyncListener<Resource> listener) {
4219                 asyncRequest(new PossibleObject(subject, relation), listener);
4220         }
4221
4222         @Override
4223         public void forPossibleObject(Resource subject, Resource relation,
4224                         SyncListener<Resource> listener) {
4225                 asyncRequest(new PossibleObject(subject, relation), listener);
4226         }
4227
4228         @Override
4229         public void forPossibleObject(Resource subject, Resource relation,
4230                         Listener<Resource> listener) {
4231                 asyncRequest(new PossibleObject(subject, relation), listener);
4232         }
4233
4234         @Override
4235         final public void forPossibleObject(final Resource subject,
4236                         final Resource relation, final AsyncProcedure<Resource> procedure) {
4237
4238                 assert (subject != null);
4239                 assert (relation != null);
4240                 assert (procedure != null);
4241
4242                 processor.forEachObject(this, subject, relation,
4243                                 new SingleOrNullProcedure<Resource>(procedure));
4244
4245         }
4246
4247         @Override
4248         public void forPossibleObject(Resource subject, Resource relation,
4249                         SyncProcedure<Resource> procedure) {
4250                 forPossibleObject(subject, relation,
4251                                 new SyncToAsyncProcedure<Resource>(procedure));
4252         }
4253
4254         @Override
4255         public void forPossibleObject(Resource subject, Resource relation,
4256                         Procedure<Resource> procedure) {
4257                 forPossibleObject(subject, relation,
4258                                 new NoneToAsyncProcedure<Resource>(procedure));
4259         }
4260
4261         @Override
4262         public void forPossibleStatement(Resource subject, Resource relation,
4263                         AsyncListener<Statement> listener) {
4264                 asyncRequest(new PossibleStatement(subject, relation), listener);
4265         }
4266
4267         @Override
4268         public void forPossibleStatement(Resource subject, Resource relation,
4269                         SyncListener<Statement> listener) {
4270                 asyncRequest(new PossibleStatement(subject, relation), listener);
4271         }
4272
4273         @Override
4274         public void forPossibleStatement(Resource subject, Resource relation,
4275                         Listener<Statement> listener) {
4276                 asyncRequest(new PossibleStatement(subject, relation), listener);
4277         }
4278
4279         @Override
4280         final public void forPossibleStatement(final Resource subject,
4281                         final Resource relation, final AsyncProcedure<Statement> procedure) {
4282
4283                 assert (subject != null);
4284                 assert (relation != null);
4285                 assert (procedure != null);
4286
4287                 processor.forEachStatement(this, subject, relation,
4288                                 new SingleFunctionalOrNullProcedure<Statement>(
4289                                                 "forPossibleStatement", procedure));
4290
4291         }
4292
4293         @Override
4294         public void forPossibleStatement(Resource subject, Resource relation,
4295                         SyncProcedure<Statement> procedure) {
4296                 forPossibleStatement(subject, relation,
4297                                 new SyncToAsyncProcedure<Statement>(procedure));
4298         }
4299
4300         @Override
4301         public void forPossibleStatement(Resource subject, Resource relation,
4302                         Procedure<Statement> procedure) {
4303                 forPossibleStatement(subject, relation,
4304                                 new NoneToAsyncProcedure<Statement>(procedure));
4305         }
4306
4307         @Override
4308         public void forPossibleType(Resource subject, Resource relation,
4309                         AsyncListener<Resource> listener) {
4310                 asyncRequest(new PossibleType(subject, relation), listener);
4311         }
4312
4313         @Override
4314         public void forPossibleType(Resource subject, Resource relation,
4315                         SyncListener<Resource> listener) {
4316                 asyncRequest(new PossibleType(subject, relation), listener);
4317         }
4318
4319         @Override
4320         public void forPossibleType(Resource subject, Resource relation,
4321                         Listener<Resource> listener) {
4322                 asyncRequest(new PossibleType(subject, relation), listener);
4323         }
4324
4325         @Override
4326         final public void forPossibleType(final Resource subject,
4327                         final Resource baseType, final AsyncProcedure<Resource> procedure) {
4328
4329                 assert (subject != null);
4330                 assert (procedure != null);
4331
4332                 final NullSingleOrNullProcedure<Resource> checkedProcedure = new NullSingleOrNullProcedure<Resource>(procedure);
4333
4334                 processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter<Resource>() {
4335
4336                                         @Override
4337                                         public void execute(AsyncReadGraph graph,
4338                                                         final Resource principalType) {
4339
4340                                                 if (baseType == null) {
4341
4342                                                         checkedProcedure.offer(graph, principalType);
4343
4344                                                 } else if (principalType.equals(baseType)) {
4345
4346                                                         checkedProcedure.offer(graph, principalType);
4347
4348                                                 } else {
4349
4350                                                         checkedProcedure.inc();
4351
4352                                                         processor.forSupertypes((ReadGraphImpl)graph, principalType,
4353                                                                         new AsyncProcedure<Set<Resource>>() {
4354
4355                                                                                 @Override
4356                                                                                 public void execute(
4357                                                                                                 AsyncReadGraph graph,
4358                                                                                                 Set<Resource> result) {
4359
4360                                                                                         if (result.contains(baseType)) {
4361                                                                                                 checkedProcedure.offer(graph,
4362                                                                                                                 principalType);
4363                                                                                         }
4364
4365                                                                                         checkedProcedure.dec(graph);
4366
4367                                                                                 }
4368
4369                                                                                 @Override
4370                                                                                 public void exception(
4371                                                                                                 AsyncReadGraph graph,
4372                                                                                                 Throwable t) {
4373                                                                                         checkedProcedure.exception(graph, t);
4374                                                                                         checkedProcedure.dec(graph);
4375                                                                                 }
4376
4377                                                                                 @Override
4378                                                                                 public String toString() {
4379                                                                                         return "forPossibleType -> "
4380                                                                                                         + procedure;
4381                                                                                 }
4382
4383                                                                         });
4384
4385                                                 }
4386
4387                                         }
4388
4389                                         @Override
4390                                         public void finished(AsyncReadGraph graph) {
4391                                                 checkedProcedure.dec(graph);
4392                                         }
4393
4394                                         @Override
4395                                         public void exception(AsyncReadGraph graph, Throwable t) {
4396                                                 checkedProcedure.exception(graph, t);
4397                                                 checkedProcedure.dec(graph);
4398                                         }
4399
4400                                 });
4401
4402         }
4403
4404         @Override
4405         public void forPossibleType(Resource subject, Resource relation,
4406                         SyncProcedure<Resource> procedure) {
4407                 forPossibleType(subject, relation, new SyncToAsyncProcedure<Resource>(
4408                                 procedure));
4409         }
4410
4411         @Override
4412         public void forPossibleType(Resource subject, Resource relation,
4413                         Procedure<Resource> procedure) {
4414                 forPossibleType(subject, relation, new NoneToAsyncProcedure<Resource>(
4415                                 procedure));
4416         }
4417
4418         @Override
4419         public <T> void forPossibleValue(Resource subject, AsyncListener<T> listener) {
4420                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4421         }
4422
4423         @Override
4424         public <T> void forPossibleValue(Resource subject, SyncListener<T> listener) {
4425                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4426         }
4427
4428         @Override
4429         public <T> void forPossibleValue(Resource subject, Listener<T> listener) {
4430                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4431         }
4432
4433         @Override
4434         final public <T> void forPossibleValue(final Resource subject,
4435                         final AsyncProcedure<T> procedure) {
4436
4437                 assert (subject != null);
4438                 assert (procedure != null);
4439                 
4440                 forPossibleRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure<Datatype>() {
4441
4442                         @Override
4443                         public void execute(AsyncReadGraph graph, final Datatype type) {
4444                                 if (type == null) {
4445                                         procedure.execute(graph, null);
4446                                 } else {
4447                                         try {
4448                                                 // TODO: consider trying Bindings.getBeanBinding(type);
4449                                                 Binding binding = Bindings.getBinding(type);
4450                                                 graph.forPossibleValue(subject, binding, procedure);
4451                                         } catch (RuntimeBindingConstructionException e) {
4452                                                 procedure.exception(graph, e);
4453                                         }
4454                                 }
4455                         }
4456
4457                         @Override
4458                         public void exception(AsyncReadGraph graph, Throwable t) {
4459                                 procedure.exception(graph, t);
4460                         }
4461
4462                         @Override
4463                         public String toString() {
4464                                 return "forPossibleValue -> " + procedure;
4465                         }
4466
4467                 });
4468
4469         }
4470
4471         @Override
4472         public <T> void forPossibleValue(Resource subject,
4473                         SyncProcedure<T> procedure) {
4474                 forPossibleValue(subject, new SyncToAsyncProcedure<T>(procedure));
4475         }
4476
4477         @Override
4478         public <T> void forPossibleValue(Resource subject, Procedure<T> procedure) {
4479                 forPossibleValue(subject, new NoneToAsyncProcedure<T>(procedure));
4480         }
4481
4482         @Override
4483         public <T> void forPossibleValue(Resource subject, Binding binding,
4484                         AsyncListener<T> listener) {
4485                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4486         }
4487
4488         @Override
4489         public <T> void forPossibleValue(Resource subject, Binding binding,
4490                         SyncListener<T> listener) {
4491                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4492         }
4493
4494         @Override
4495         public <T> void forPossibleValue(Resource subject, Binding binding,
4496                         Listener<T> listener) {
4497                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4498         }
4499
4500         @Override
4501         final public <T> void forPossibleValue(final Resource resource,
4502                         final Binding binding, final AsyncProcedure<T> procedure) {
4503
4504                 assert (resource != null);
4505                 assert (binding != null);
4506                 assert (procedure != null);
4507
4508                 processor.forValue(this, resource, new AsyncProcedure<byte[]>() {
4509
4510                         @Override
4511                         public void execute(AsyncReadGraph graph, byte[] result) {
4512
4513                                 try {
4514
4515                                         if (result == null) {
4516                                                 procedure.execute(graph, null);
4517                                                 return;
4518                                         }
4519
4520                                         Serializer serializer = Bindings.getSerializer( binding );
4521                                         Object obj = serializer.deserialize(result);
4522                                         if (!binding.isInstance(obj))
4523                                                 procedure.exception(graph, new ClassCastException(
4524                                                                 "Cannot get value " + obj + " with binding "
4525                                                                                 + binding));
4526                                         else
4527                                                 procedure.execute(graph, (T) obj);
4528
4529                                 } catch (IOException e) {
4530                                         procedure.exception(graph, e);
4531                                 } catch (BufferUnderflowException e) {
4532                                         procedure.exception(graph, e);
4533                                 } catch (Throwable t) {
4534                                         procedure.exception(graph, t);
4535                                 }
4536
4537                         }
4538
4539                         @Override
4540                         public void exception(AsyncReadGraph graph, Throwable t) {
4541                                 try {
4542                                         procedure.exception(graph, t);
4543                                 } catch (Throwable t2) {
4544                                 Logger.defaultLogError(t2);
4545                                 }
4546                         }
4547
4548                         @Override
4549                         public String toString() {
4550                                 return "forPossibleValue -> " + procedure;
4551                         }
4552
4553                 });
4554
4555         }
4556
4557         @Override
4558         public <T> void forPossibleValue(Resource subject, Binding binding,
4559                         SyncProcedure<T> procedure) {
4560                 forPossibleValue(subject, binding, new SyncToAsyncProcedure<T>(
4561                                 procedure));
4562         }
4563
4564         @Override
4565         public <T> void forPossibleValue(Resource subject, Binding binding,
4566                         Procedure<T> procedure) {
4567                 forPossibleValue(subject, binding, new NoneToAsyncProcedure<T>(
4568                                 procedure));
4569         }
4570
4571         @Override
4572         public <T> void forPossibleRelatedValue(Resource subject,
4573                         Resource relation, AsyncListener<T> listener) {
4574                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4575                                 listener);
4576         }
4577
4578         @Override
4579         public <T> void forPossibleRelatedValue(Resource subject,
4580                         Resource relation, SyncListener<T> listener) {
4581                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4582                                 listener);
4583         }
4584
4585         @Override
4586         public <T> void forPossibleRelatedValue(Resource subject,
4587                         Resource relation, Listener<T> listener) {
4588                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4589                                 listener);
4590         }
4591
4592         @Override
4593         final public <T> void forPossibleRelatedValue(final Resource subject,
4594                         final Resource relation, final AsyncProcedure<T> procedure) {
4595
4596                 assert (subject != null);
4597                 assert (relation != null);
4598                 assert (procedure != null);
4599
4600                 final DeepSingleOrNullProcedure<T> checkedProcedure = new DeepSingleOrNullProcedure<T>(procedure);
4601                 
4602                 processor.forEachObject(this, subject, relation,
4603                                 new AsyncMultiProcedureAdapter<Resource>() {
4604
4605                                         @Override
4606                                         public void execute(AsyncReadGraph graph,
4607                                                         final Resource object) {
4608
4609                                                 checkedProcedure.inc();
4610
4611                                                 graph.forValue(object, new AsyncProcedure<Object>() {
4612
4613                                                         @Override
4614                                                         public void execute(AsyncReadGraph graph,
4615                                                                         Object result) {
4616                                                                 checkedProcedure.offer(graph, (T) result);
4617                                                                 checkedProcedure.dec(graph);
4618                                                         }
4619
4620                                                         @Override
4621                                                         public void exception(AsyncReadGraph graph,
4622                                                                         Throwable t) {
4623                                                                 checkedProcedure.exception(graph, t);
4624                                                                 checkedProcedure.dec(graph);
4625                                                         }
4626
4627                                                 });
4628
4629                                         }
4630
4631                                         @Override
4632                                         public void finished(AsyncReadGraph graph) {
4633
4634                                                 checkedProcedure.dec(graph);
4635                                         }
4636
4637                                         @Override
4638                                         public void exception(AsyncReadGraph graph, Throwable t) {
4639                                                 checkedProcedure.exception(graph, t);
4640                                                 checkedProcedure.dec(graph);
4641                                         }
4642
4643                                         @Override
4644                                         public String toString() {
4645                                                 return "forPossibleRelatedValue -> " + procedure;
4646                                         }
4647                                 });
4648
4649         }
4650
4651         @Override
4652         public <T> void forPossibleRelatedValue(Resource subject,
4653                         Resource relation, SyncProcedure<T> procedure) {
4654                 forPossibleRelatedValue(subject, relation, new SyncToAsyncProcedure<T>(
4655                                 procedure));
4656         }
4657
4658         @Override
4659         public <T> void forPossibleRelatedValue(Resource subject,
4660                         Resource relation, Procedure<T> procedure) {
4661                 forPossibleRelatedValue(subject, relation, new NoneToAsyncProcedure<T>(
4662                                 procedure));
4663         }
4664
4665         @Override
4666         public <T> void forPossibleRelatedValue(Resource subject,
4667                         Resource relation, Binding binding, AsyncListener<T> listener) {
4668                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4669                                 listener);
4670         }
4671
4672         @Override
4673         public <T> void forPossibleRelatedValue(Resource subject,
4674                         Resource relation, Binding binding, SyncListener<T> listener) {
4675                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4676                                 listener);
4677         }
4678
4679         @Override
4680         public <T> void forPossibleRelatedValue(Resource subject,
4681                         Resource relation, Binding binding, Listener<T> listener) {
4682                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4683                                 listener);
4684         }
4685
4686 //      @Override
4687 //      final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
4688 //                      final AsyncProcedure<T> procedure) {
4689 //              
4690 //              forPossibleRelatedValue(subject, relation, binding, procedure, false);
4691 //              
4692 //      }
4693
4694         final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
4695                         final AsyncProcedure<T> procedure) {
4696
4697                 assert (subject != null);
4698                 assert (relation != null);
4699                 assert (procedure != null);
4700
4701                 processor.forPossibleObject(this, subject, relation, new AsyncProcedure<Resource>() {
4702                         
4703                         @Override
4704                         public void execute(AsyncReadGraph graph, Resource object) {
4705                                 
4706                                 if(object == null) {
4707                                         procedure.execute(graph, null);
4708                                         return;
4709                                 }
4710
4711                                 processor.forPossibleValue((ReadGraphImpl)graph, object, new AsyncProcedure<byte[]>() {
4712
4713                                         @Override
4714                                         public void execute(AsyncReadGraph graph, byte[] bytes) {
4715
4716                                                 if(bytes != null) {
4717
4718                                                         try {
4719                                                         
4720                                                                 Serializer serializer = binding.serializer();
4721                                                                 Object obj = serializer.deserialize(bytes);
4722                                                                 if (!binding.isInstance(obj)) {
4723                                                                         procedure.exception(graph, new ClassCastException("Cannot get value " + obj + " with binding " + binding));
4724                                                                 } else {
4725                                                                         procedure.execute(graph, (T) obj);
4726                                                                 }
4727
4728                                                         } catch (Throwable t) {
4729                                                                 
4730                                                                 procedure.exception(graph, t);
4731                                                                 
4732                                                         }
4733                                                         
4734                                                 } else {
4735                                                         
4736                                                         procedure.execute(graph, null);
4737                                                         
4738                                                 }
4739                                                 
4740                                         }
4741
4742                                         @Override
4743                                         public void exception(AsyncReadGraph graph, Throwable t) {
4744                                                 procedure.exception(graph, t);
4745                                         }
4746
4747                                 });
4748                                 
4749                         }
4750                         
4751                         @Override
4752                         public void exception(AsyncReadGraph graph, Throwable throwable) {
4753                                 throwable.printStackTrace();
4754                                 procedure.exception(graph, throwable);
4755                         }
4756                         
4757                 });
4758
4759         }
4760
4761         @Override
4762         public <T> void forPossibleRelatedValue(Resource subject,
4763                         Resource relation, Binding binding, SyncProcedure<T> procedure) {
4764                 forPossibleRelatedValue(subject, relation, binding,
4765                                 new SyncToAsyncProcedure<T>(procedure));
4766         }
4767
4768         @Override
4769         public <T> void forPossibleRelatedValue(Resource subject,
4770                         Resource relation, Binding binding, Procedure<T> procedure) {
4771                 forPossibleRelatedValue(subject, relation, binding,
4772                                 new NoneToAsyncProcedure<T>(procedure));
4773         }
4774
4775         @Override
4776         public void forIsInstanceOf(Resource subject, Resource relation,
4777                         AsyncListener<Boolean> listener) {
4778                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4779         }
4780
4781         @Override
4782         public void forIsInstanceOf(Resource subject, Resource relation,
4783                         SyncListener<Boolean> listener) {
4784                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4785         }
4786
4787         @Override
4788         public void forIsInstanceOf(Resource subject, Resource relation,
4789                         Listener<Boolean> listener) {
4790                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4791         }
4792
4793         @Override
4794         final public void forIsInstanceOf(final Resource resource,
4795                         final Resource type, final AsyncProcedure<Boolean> procedure) {
4796
4797                 assert (resource != null);
4798                 assert (type != null);
4799                 assert (procedure != null);
4800
4801                 forTypes(resource, new AsyncProcedure<Set<Resource>>() {
4802
4803                         @Override
4804                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4805                                 
4806                                 try {
4807                                         if (result.contains(type))
4808                                                 procedure.execute(graph, true);
4809                                         else
4810                                                 procedure.execute(graph, false);
4811                                 } catch (Throwable t) {
4812                                 Logger.defaultLogError(t);
4813                                 }
4814                         }
4815
4816                         @Override
4817                         public void exception(AsyncReadGraph graph, Throwable t) {
4818                                 try {
4819                                         procedure.exception(graph, t);
4820                                 } catch (Throwable t2) {
4821                                 Logger.defaultLogError(t2);
4822                                 }
4823                         }
4824
4825                         @Override
4826                         public String toString() {
4827                                 return "forIsInstanceOf -> " + procedure;
4828                         }
4829
4830                 });
4831
4832         }
4833
4834         @Override
4835         public void forIsInstanceOf(Resource subject, Resource relation,
4836                         SyncProcedure<Boolean> procedure) {
4837                 forIsInstanceOf(subject, relation, new SyncToAsyncProcedure<Boolean>(
4838                                 procedure));
4839         }
4840
4841         @Override
4842         public void forIsInstanceOf(Resource subject, Resource relation,
4843                         Procedure<Boolean> procedure) {
4844                 forIsInstanceOf(subject, relation, new NoneToAsyncProcedure<Boolean>(
4845                                 procedure));
4846         }
4847
4848         @Override
4849         public void forIsInheritedFrom(Resource subject, Resource relation,
4850                         AsyncListener<Boolean> listener) {
4851                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4852         }
4853
4854         @Override
4855         public void forIsInheritedFrom(Resource subject, Resource relation,
4856                         SyncListener<Boolean> listener) {
4857                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4858         }
4859
4860         @Override
4861         public void forIsInheritedFrom(Resource subject, Resource relation,
4862                         Listener<Boolean> listener) {
4863                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4864         }
4865
4866         @Override
4867         final public void forIsInheritedFrom(final Resource resource,
4868                         final Resource type, final AsyncProcedure<Boolean> procedure) {
4869
4870                 assert (resource != null);
4871                 assert (type != null);
4872                 assert (procedure != null);
4873
4874                 if (resource.equals(type)) {
4875                         try {
4876                                 procedure.execute(this, true);
4877                         } catch (Throwable t) {
4878                         Logger.defaultLogError(t);
4879                         }
4880                         return;
4881                 }
4882
4883                 forSupertypes(resource, new AsyncProcedure<Set<Resource>>() {
4884
4885                         @Override
4886                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4887                                 try {
4888                                         if (result.contains(type))
4889                                                 procedure.execute(graph, true);
4890                                         else
4891                                                 procedure.execute(graph, false);
4892                                 } catch (Throwable t) {
4893                                 Logger.defaultLogError(t);
4894                                 }
4895                         }
4896
4897                         @Override
4898                         public void exception(AsyncReadGraph graph, Throwable t) {
4899                                 try {
4900                                         procedure.exception(graph, t);
4901                                 } catch (Throwable t2) {
4902                                 Logger.defaultLogError(t2);
4903                                 }
4904                         }
4905
4906                         @Override
4907                         public String toString() {
4908                                 return "forIsInheritedFrom -> " + procedure;
4909                         }
4910
4911                 });
4912
4913         }
4914
4915         @Override
4916         public void forIsInheritedFrom(Resource subject, Resource relation,
4917                         SyncProcedure<Boolean> procedure) {
4918                 forIsInheritedFrom(subject, relation,
4919                                 new SyncToAsyncProcedure<Boolean>(procedure));
4920         }
4921
4922         @Override
4923         public void forIsInheritedFrom(Resource subject, Resource relation,
4924                         Procedure<Boolean> procedure) {
4925                 forIsInheritedFrom(subject, relation,
4926                                 new NoneToAsyncProcedure<Boolean>(procedure));
4927         }
4928
4929         @Override
4930         public void forIsSubrelationOf(Resource subject, Resource relation,
4931                         AsyncListener<Boolean> listener) {
4932                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4933         }
4934
4935         @Override
4936         public void forIsSubrelationOf(Resource subject, Resource relation,
4937                         SyncListener<Boolean> listener) {
4938                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4939         }
4940
4941         @Override
4942         public void forIsSubrelationOf(Resource subject, Resource relation,
4943                         Listener<Boolean> listener) {
4944                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4945         }
4946
4947         @Override
4948         final public void forIsSubrelationOf(final Resource resource,
4949                         final Resource relation, final AsyncProcedure<Boolean> procedure) {
4950
4951                 assert (resource != null);
4952                 assert (relation != null);
4953                 assert (procedure != null);
4954
4955                 if (resource.equals(relation)) {
4956                         procedure.execute(this, true);
4957                         return;
4958                 }
4959
4960                 forSuperrelations(resource, new AsyncProcedure<Set<Resource>>() {
4961
4962                         @Override
4963                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4964                                 try {
4965                                         if (result.contains(relation))
4966                                                 procedure.execute(graph, true);
4967                                         else
4968                                                 procedure.execute(graph, false);
4969                                 } catch (Throwable t) {
4970                                 Logger.defaultLogError(t);
4971                                 }
4972                         }
4973
4974                         @Override
4975                         public void exception(AsyncReadGraph graph, Throwable t) {
4976                                 try {
4977                                         procedure.exception(graph, t);
4978                                 } catch (Throwable t2) {
4979                                 Logger.defaultLogError(t2);
4980                                 }
4981                         }
4982
4983                         @Override
4984                         public String toString() {
4985                                 return "forIsSubrelationOf -> " + procedure;
4986                         }
4987
4988                 });
4989
4990         }
4991
4992         @Override
4993         public void forIsSubrelationOf(Resource subject, Resource relation,
4994                         SyncProcedure<Boolean> procedure) {
4995                 forIsSubrelationOf(subject, relation,
4996                                 new SyncToAsyncProcedure<Boolean>(procedure));
4997         }
4998
4999         @Override
5000         public void forIsSubrelationOf(Resource subject, Resource relation,
5001                         Procedure<Boolean> procedure) {
5002                 forIsSubrelationOf(subject, relation,
5003                                 new NoneToAsyncProcedure<Boolean>(procedure));
5004         }
5005
5006         @Override
5007         public void forHasStatement(Resource subject,
5008                         AsyncListener<Boolean> listener) {
5009                 asyncRequest(new HasStatementSubject(subject), listener);
5010         }
5011
5012         @Override
5013         public void forHasStatement(Resource subject, SyncListener<Boolean> listener) {
5014                 asyncRequest(new HasStatementSubject(subject), listener);
5015         }
5016
5017         @Override
5018         public void forHasStatement(Resource subject, Listener<Boolean> listener) {
5019                 asyncRequest(new HasStatementSubject(subject), listener);
5020         }
5021
5022         @Override
5023         final public void forHasStatement(final Resource subject,
5024                         final AsyncProcedure<Boolean> procedure) {
5025
5026                 assert (subject != null);
5027                 assert (procedure != null);
5028
5029                 processor.forHasStatement(this, subject, procedure);
5030
5031         }
5032
5033         @Override
5034         public void forHasStatement(Resource subject,
5035                         SyncProcedure<Boolean> procedure) {
5036                 forHasStatement(subject, new SyncToAsyncProcedure<Boolean>(procedure));
5037         }
5038
5039         @Override
5040         public void forHasStatement(Resource subject, Procedure<Boolean> procedure) {
5041                 forHasStatement(subject, new NoneToAsyncProcedure<Boolean>(procedure));
5042         }
5043
5044         @Override
5045         public void forHasStatement(Resource subject, Resource relation,
5046                         AsyncListener<Boolean> listener) {
5047                 asyncRequest(new HasStatement(subject, relation), listener);
5048         }
5049
5050         @Override
5051         public void forHasStatement(Resource subject, Resource relation,
5052                         SyncListener<Boolean> listener) {
5053                 asyncRequest(new HasStatement(subject, relation), listener);
5054         }
5055
5056         @Override
5057         public void forHasStatement(Resource subject, Resource relation,
5058                         Listener<Boolean> listener) {
5059                 asyncRequest(new HasStatement(subject, relation), listener);
5060         }
5061
5062         @Override
5063         final public void forHasStatement(final Resource subject,
5064                         final Resource relation, final AsyncProcedure<Boolean> procedure) {
5065
5066                 assert (subject != null);
5067                 assert (relation != null);
5068                 assert (procedure != null);
5069
5070                 processor.forHasStatement(this, subject, relation, procedure);
5071
5072         }
5073
5074         @Override
5075         public void forHasStatement(Resource subject, Resource relation,
5076                         SyncProcedure<Boolean> procedure) {
5077                 forHasStatement(subject, relation, new SyncToAsyncProcedure<Boolean>(
5078                                 procedure));
5079         }
5080
5081         @Override
5082         public void forHasStatement(Resource subject, Resource relation,
5083                         Procedure<Boolean> procedure) {
5084                 forHasStatement(subject, relation, new NoneToAsyncProcedure<Boolean>(
5085                                 procedure));
5086         }
5087
5088         @Override
5089         public void forHasStatement(Resource subject, Resource relation,
5090                         Resource object, AsyncListener<Boolean> listener) {
5091                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
5092                                 listener);
5093         }
5094
5095         @Override
5096         public void forHasStatement(Resource subject, Resource relation,
5097                         Resource object, SyncListener<Boolean> listener) {
5098                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
5099                                 listener);
5100         }
5101
5102         @Override
5103         public void forHasStatement(Resource subject, Resource relation,
5104                         Resource object, Listener<Boolean> listener) {
5105                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
5106                                 listener);
5107         }
5108
5109         @Override
5110         final public void forHasStatement(final Resource subject,
5111                         final Resource relation, final Resource object,
5112                         final AsyncProcedure<Boolean> procedure) {
5113
5114                 assert (subject != null);
5115                 assert (relation != null);
5116                 assert (object != null);
5117                 assert (procedure != null);
5118
5119                 processor.forHasStatement(this, subject, relation, object, procedure);
5120
5121         }
5122
5123         @Override
5124         public void forHasStatement(Resource subject, Resource relation,
5125                         Resource object, SyncProcedure<Boolean> procedure) {
5126                 forHasStatement(subject, relation, object,
5127                                 new SyncToAsyncProcedure<Boolean>(procedure));
5128         }
5129
5130         @Override
5131         public void forHasStatement(Resource subject, Resource relation,
5132                         Resource object, Procedure<Boolean> procedure) {
5133                 forHasStatement(subject, relation, object,
5134                                 new NoneToAsyncProcedure<Boolean>(procedure));
5135         }
5136
5137         @Override
5138         public void forHasValue(Resource subject, AsyncListener<Boolean> listener) {
5139                 asyncRequest(new HasValue(subject), listener);
5140         }
5141
5142         @Override
5143         public void forHasValue(Resource subject, SyncListener<Boolean> listener) {
5144                 asyncRequest(new HasValue(subject), listener);
5145         }
5146
5147         @Override
5148         public void forHasValue(Resource subject, Listener<Boolean> listener) {
5149                 asyncRequest(new HasValue(subject), listener);
5150         }
5151
5152         @Override
5153         final public void forHasValue(final Resource subject,
5154                         final AsyncProcedure<Boolean> procedure) {
5155
5156                 assert (subject != null);
5157                 assert (procedure != null);
5158
5159                 processor.forValue(this, subject, new AsyncProcedure<byte[]>() {
5160
5161                         @Override
5162                         public void execute(AsyncReadGraph graph, byte[] result) {
5163                                 try {
5164                                         if (result == null)
5165                                                 procedure.execute(graph, false);
5166                                         else
5167                                                 procedure.execute(graph, true);
5168                                 } catch (Throwable t) {
5169                                 Logger.defaultLogError(t);
5170                                 }
5171                         }
5172
5173                         @Override
5174                         public void exception(AsyncReadGraph graph, Throwable t) {
5175                                 try {
5176                                         procedure.exception(graph, t);
5177                                 } catch (Throwable t2) {
5178                                 Logger.defaultLogError(t2);
5179                                 }
5180                         }
5181
5182                         @Override
5183                         public String toString() {
5184                                 return "forHasValue -> " + procedure;
5185                         }
5186
5187                 });
5188
5189         }
5190
5191         @Override
5192         public void forHasValue(Resource subject, SyncProcedure<Boolean> procedure) {
5193                 forHasValue(subject, new SyncToAsyncProcedure<Boolean>(procedure));
5194         }
5195
5196         @Override
5197         public void forHasValue(Resource subject, Procedure<Boolean> procedure) {
5198                 forHasValue(subject, new NoneToAsyncProcedure<Boolean>(procedure));
5199         }
5200
5201         @Override
5202         public void forOrderedSet(Resource subject,
5203                         AsyncMultiListener<Resource> listener) {
5204                 asyncRequest(new OrderedSet(subject), listener);
5205         }
5206
5207         @Override
5208         public void forOrderedSet(Resource subject,
5209                         SyncMultiListener<Resource> listener) {
5210                 asyncRequest(new OrderedSet(subject), listener);
5211         }
5212
5213         @Override
5214         public void forOrderedSet(Resource subject, MultiListener<Resource> listener) {
5215                 asyncRequest(new OrderedSet(subject), listener);
5216         }
5217
5218         @Override
5219         final public void forOrderedSet(final Resource subject,
5220                         final AsyncMultiProcedure<Resource> procedure) {
5221
5222                 assert (subject != null);
5223                 assert (procedure != null);
5224
5225                 processor.forOrderedSet(this, subject,
5226                                 new AsyncMultiProcedure<Resource>() {
5227
5228                                         @Override
5229                                         public void finished(AsyncReadGraph graph) {
5230                                                 try {
5231                                                         procedure.finished(graph);
5232                                                 } catch (Throwable t) {
5233                                                 Logger.defaultLogError(t);
5234                                                 }
5235                                         }
5236
5237                                         @Override
5238                                         public void execute(AsyncReadGraph graph, Resource result) {
5239                                                 try {
5240                                                         procedure.execute(graph, result);
5241                                                 } catch (Throwable t) {
5242                                                 Logger.defaultLogError(t);
5243                                                 }
5244                                         }
5245
5246                                         @Override
5247                                         public void exception(AsyncReadGraph graph, Throwable t) {
5248                                                 try {
5249                                                         procedure.exception(graph, t);
5250                                                 } catch (Throwable t2) {
5251                                                 Logger.defaultLogError(t2);
5252                                                 }
5253                                         }
5254
5255                                         @Override
5256                                         public String toString() {
5257                                                 return "forOrderedSet -> " + procedure;
5258                                         }
5259
5260                                 });
5261
5262         }
5263
5264         @Override
5265         public void forOrderedSet(Resource subject,
5266                         SyncMultiProcedure<Resource> procedure) {
5267                 forOrderedSet(subject, new SyncToAsyncMultiProcedure<Resource>(
5268                                 procedure));
5269         }
5270
5271         @Override
5272         public void forOrderedSet(Resource subject,
5273                         MultiProcedure<Resource> procedure) {
5274                 forOrderedSet(subject, new NoneToAsyncMultiProcedure<Resource>(
5275                                 procedure));
5276         }
5277
5278         @Override
5279         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5280                         AsyncListener<T> listener) {
5281                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5282         }
5283
5284         @Override
5285         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5286                         SyncListener<T> listener) {
5287                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5288         }
5289
5290         @Override
5291         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5292                         Listener<T> listener) {
5293                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5294         }
5295
5296         @Override
5297         final public <T> void forPossibleAdapted(final Resource resource,
5298                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
5299
5300                 assert (resource != null);
5301                 assert (clazz != null);
5302                 assert (procedure != null);
5303
5304                 final AdaptionService service = getSession().peekService(AdaptionService.class);
5305                 if (service == null)
5306                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
5307                 else
5308                         service.adapt(this, resource, resource, Resource.class, clazz, true, procedure);
5309         }
5310
5311         @Override
5312         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5313                         SyncProcedure<T> procedure) {
5314                 forPossibleAdapted(resource, clazz, new SyncToAsyncProcedure<T>(
5315                                 procedure));
5316         }
5317
5318         @Override
5319         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5320                         Procedure<T> procedure) {
5321                 forPossibleAdapted(resource, clazz, new NoneToAsyncProcedure<T>(
5322                                 procedure));
5323         }
5324
5325         @Override
5326         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5327                         AsyncListener<T> listener) {
5328                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5329         }
5330
5331         @Override
5332         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5333                         SyncListener<T> listener) {
5334                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5335         }
5336
5337         @Override
5338         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5339                         Listener<T> listener) {
5340                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5341         }
5342
5343         @Override
5344         final public <T> void forPossibleUniqueAdapted(final Resource resource,
5345                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
5346
5347                 assert (resource != null);
5348                 assert (clazz != null);
5349                 assert (procedure != null);
5350
5351                 final AdaptionService service = getSession().peekService(AdaptionService.class);
5352                 if (service == null)
5353                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
5354                 else
5355                         service.adaptNew(this, resource, clazz, true, procedure);
5356
5357         }
5358
5359         @Override
5360         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5361                         SyncProcedure<T> procedure) {
5362                 forPossibleUniqueAdapted(resource, clazz, new SyncToAsyncProcedure<T>(
5363                                 procedure));
5364         }
5365
5366         @Override
5367         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5368                         Procedure<T> procedure) {
5369                 forPossibleUniqueAdapted(resource, clazz, new NoneToAsyncProcedure<T>(
5370                                 procedure));
5371         }
5372
5373         /*
5374          * Implementation of the interface AsyncRequestProcessor
5375          */
5376
5377         @Override
5378         final public Session getSession() {
5379                 return processor.getSession();
5380         }
5381
5382 //      @Override
5383 //      final public Builtins getBuiltins() {
5384 //              return processor.getSession().getBuiltins();
5385 //      }
5386
5387         @Override
5388         public <T> void asyncRequest(final Read<T> request) {
5389
5390                 asyncRequest(request, new AsyncProcedure<T>() {
5391
5392                         @Override
5393                         public void execute(AsyncReadGraph graph, T result) {
5394                         }
5395
5396                         @Override
5397                         public void exception(AsyncReadGraph graph, Throwable t) {
5398                                 Logger.defaultLogError(t);
5399                         }
5400
5401                         @Override
5402                         public String toString() {
5403                                 return "asyncRequest(Read) -> " + request;
5404                         }
5405
5406                 });
5407
5408         }
5409
5410         @Override
5411         public <T> void asyncRequest(Read<T> request, AsyncListener<T> procedure) {
5412                 asyncRequest(request, (AsyncProcedure<T>) procedure);
5413         }
5414
5415         @Override
5416         public <T> void asyncRequest(Read<T> request,
5417                         final SyncListener<T> procedure) {
5418                 asyncRequest(request, new SyncToAsyncListener<T>(procedure));
5419         }
5420
5421         @Override
5422         public <T> void asyncRequest(Read<T> request, final Listener<T> procedure) {
5423                 asyncRequest(request, new NoneToAsyncListener<T>(procedure));
5424         }
5425
5426         @Override
5427         public <T> void asyncRequest(final Read<T> request, final AsyncProcedure<T> procedure) {
5428
5429                 assert (request != null);
5430                 assert (procedure != null);
5431
5432                 final ListenerBase listener = getListenerBase(procedure);
5433
5434                 if (parent != null || listener != null) {
5435
5436                         try {
5437                                 processor.queryRead(this, request, parent, procedure,
5438                                                 listener);
5439                         } catch (Throwable e) {
5440                                 // This throwable has already been transferred to procedure at this point - do nothing about it
5441                                 //Logger.defaultLogError("Internal error ", e);
5442                         }
5443                         
5444                 } else {
5445
5446 //                      final ReadGraphImpl newGraph = newSync();
5447
5448                         try {
5449
5450                                 T result = request.perform(this);
5451                                 
5452                                 try {
5453                                         procedure.execute(this, result);
5454                                 } catch (Throwable t) {
5455                                         Logger.defaultLogError(t);
5456                                 }
5457
5458                         } catch (Throwable t) {
5459
5460                                 try {
5461                                         procedure.exception(this, t);
5462                                 } catch (Throwable t2) {
5463                                         Logger.defaultLogError(t2);
5464                                 }
5465
5466                         } finally {
5467
5468                         }
5469
5470                 }
5471
5472         }
5473
5474     public static ReadGraphImpl createAsync(QueryProcessor support) {
5475         return new ReadGraphImpl(null, support);
5476     }
5477
5478     public static ReadGraphImpl forRecompute(CacheEntry entry, QueryProcessor support) {
5479         return new ReadGraphImpl(entry, support);       
5480     }
5481
5482         @Override
5483         public <T> void asyncRequest(Read<T> request, SyncProcedure<T> procedure) {
5484                 asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
5485         }
5486
5487         @Override
5488         public <T> void asyncRequest(Read<T> request, final Procedure<T> procedure) {
5489                 asyncRequest(request, new NoneToAsyncProcedure<T>(procedure));
5490         }
5491
5492         @Override
5493         final public <T> void asyncRequest(final AsyncRead<T> request) {
5494
5495                 assert (request != null);
5496
5497                 asyncRequest(request, new AsyncProcedure<T>() {
5498
5499                         @Override
5500                         public void execute(AsyncReadGraph graph, T result) {
5501                         }
5502
5503                         @Override
5504                         public void exception(AsyncReadGraph graph, Throwable t) {
5505                         Logger.defaultLogError(t);
5506                         }
5507
5508                         @Override
5509                         public String toString() {
5510                                 return "asyncRequest(AsyncRead) -> " + request;
5511                         }
5512
5513                 });
5514
5515         }
5516
5517         @Override
5518         public <T> void asyncRequest(AsyncRead<T> request,
5519                         AsyncListener<T> procedure) {
5520                 asyncRequest(request, (AsyncProcedure<T>) procedure);
5521         }
5522
5523         @Override
5524         final public <T> void asyncRequest(AsyncRead<T> request,
5525                         final SyncListener<T> procedure) {
5526                 asyncRequest(request, new SyncToAsyncListener<T>(procedure));
5527         }
5528
5529         @Override
5530         final public <T> void asyncRequest(AsyncRead<T> request,
5531                         final Listener<T> procedure) {
5532                 asyncRequest(request, new NoneToAsyncListener<T>(procedure));
5533         }
5534
5535         @Override
5536         final public <T> void asyncRequest(final AsyncRead<T> request,
5537                         final AsyncProcedure<T> procedure) {
5538
5539                 assert (request != null);
5540                 assert (procedure != null);
5541
5542                 final ListenerBase listener = getListenerBase(procedure);
5543
5544                 if (parent != null || listener != null) {
5545
5546                         processor.query(this, request, parent, procedure, listener);
5547
5548                 } else {
5549
5550                         try {
5551                                 
5552                                 request.perform(this, new CallWrappedSingleQueryProcedure4<T>(procedure, request));
5553
5554                         } catch (Throwable t) {
5555
5556                                 if (t instanceof DatabaseException)
5557                                         procedure.exception(this, t);
5558                                 else
5559                                         procedure
5560                                                         .exception(
5561                                                                         this,
5562                                                                         new DatabaseException(
5563                                                                                         "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
5564                                                                                         t));
5565
5566                         }
5567
5568                 }
5569
5570         }
5571
5572         @Override
5573         public <T> void asyncRequest(AsyncRead<T> request,
5574                         SyncProcedure<T> procedure) {
5575                 asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
5576         }
5577
5578         @Override
5579         final public <T> void asyncRequest(final AsyncRead<T> request,
5580                         final Procedure<T> procedure) {
5581                 asyncRequest(request, new NoneToAsyncProcedure<T>(procedure));
5582         }
5583
5584         @Override
5585         public <T> void asyncRequest(final MultiRead<T> request) {
5586
5587                 assert (request != null);
5588
5589                 asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
5590                         @Override
5591                         public void exception(AsyncReadGraph graph, Throwable t) {
5592                         Logger.defaultLogError(t);
5593                         }
5594
5595                         @Override
5596                         public String toString() {
5597                                 return "asyncRequest(MultiRead) -> " + request;
5598                         }
5599                 });
5600
5601         }
5602
5603         @Override
5604         public <T> void asyncRequest(MultiRead<T> request,
5605                         AsyncMultiListener<T> procedure) {
5606                 asyncRequest(request, (AsyncMultiProcedure<T>) procedure);
5607         }
5608
5609         @Override
5610         public <T> void asyncRequest(MultiRead<T> request,
5611                         SyncMultiListener<T> procedure) {
5612                 asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
5613         }
5614
5615         @Override
5616         public <T> void asyncRequest(MultiRead<T> request,
5617                         MultiListener<T> procedure) {
5618                 asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
5619         }
5620
5621         @Override
5622         public <T> void asyncRequest(final MultiRead<T> request,
5623                         final AsyncMultiProcedure<T> procedure) {
5624
5625                 assert (request != null);
5626                 assert (procedure != null);
5627
5628                 final ListenerBase listener = getListenerBase(procedure);
5629
5630                 if (parent != null || listener != null) {
5631
5632 //                  final ReadGraphImpl newGraph = newSync();
5633                     processor.query(this, request, parent, procedure,listener);
5634
5635                 } else {
5636
5637 //                  final ReadGraphImpl newGraph = newSync();
5638
5639                     try {
5640
5641                         request.perform(this, procedure);
5642
5643                     } catch (Throwable t) {
5644
5645                         procedure.exception(this, t);
5646
5647                     }                           
5648
5649                 }
5650
5651         }
5652
5653         @Override
5654         public <T> void asyncRequest(MultiRead<T> request,
5655                         SyncMultiProcedure<T> procedure) {
5656                 asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
5657         }
5658
5659         @Override
5660         public <T> void asyncRequest(MultiRead<T> request,
5661                         MultiProcedure<T> procedure) {
5662                 asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
5663         }
5664
5665         @Override
5666         final public <T> void asyncRequest(final AsyncMultiRead<T> request) {
5667
5668                 assert (request != null);
5669
5670                 asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
5671                         @Override
5672                         public void exception(AsyncReadGraph graph, Throwable t) {
5673                         Logger.defaultLogError(t);
5674                         }
5675
5676                         @Override
5677                         public String toString() {
5678                                 return "asyncRequest(AsyncMultiRead) -> " + request;
5679                         }
5680                 });
5681
5682         }
5683
5684         @Override
5685         public <T> void asyncRequest(AsyncMultiRead<T> request,
5686                         AsyncMultiListener<T> procedure) {
5687                 asyncRequest(request, (AsyncMultiProcedure<T>) procedure);
5688         }
5689
5690         @Override
5691         public <T> void asyncRequest(AsyncMultiRead<T> request,
5692                         SyncMultiListener<T> procedure) {
5693                 asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
5694         }
5695
5696         @Override
5697         public <T> void asyncRequest(AsyncMultiRead<T> request,
5698                         MultiListener<T> procedure) {
5699                 asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
5700         }
5701
5702         @Override
5703         final public <T> void asyncRequest(AsyncMultiRead<T> request,
5704                         final AsyncMultiProcedure<T> procedure) {
5705
5706                 assert (request != null);
5707                 assert (procedure != null);
5708
5709                 ListenerBase listener = getListenerBase(procedure);
5710
5711                 if (parent != null || listener != null) {
5712
5713                         processor.query(this, request, parent, procedure, listener);
5714
5715                 } else {
5716
5717                         try {
5718
5719                                 request.perform(this, new AsyncMultiProcedure<T>() {
5720
5721                                         @Override
5722                                         public void execute(AsyncReadGraph graph, T result) {
5723                                                 procedure.execute(graph, result);
5724                                         }
5725
5726                                         @Override
5727                                         public void finished(AsyncReadGraph graph) {
5728                                                 procedure.finished(graph);
5729                                         }
5730
5731                                         @Override
5732                                         public void exception(AsyncReadGraph graph, Throwable t) {
5733                                                 procedure.exception(graph, t);
5734                                         }
5735
5736                                         @Override
5737                                         public String toString() {
5738                                                 return "asyncRequest(AsyncMultiRead) -> " + procedure;
5739                                         }
5740
5741                                 });
5742
5743                         } catch (Throwable t) {
5744
5745                                 procedure.exception(this, new DatabaseException(t));
5746
5747                         }
5748                 }
5749
5750         }
5751
5752         @Override
5753         public <T> void asyncRequest(AsyncMultiRead<T> request,
5754                         SyncMultiProcedure<T> procedure) {
5755                 asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
5756         }
5757
5758         @Override
5759         final public <T> void asyncRequest(AsyncMultiRead<T> request,
5760                         final MultiProcedure<T> procedure) {
5761                 asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
5762         }
5763
5764         @Override
5765         final public <T> void asyncRequest(final ExternalRead<T> request) {
5766
5767                 assert (request != null);
5768
5769                 asyncRequest(request, new Procedure<T>() {
5770
5771                         @Override
5772                         public void execute(T result) {
5773                         }
5774
5775                         @Override
5776                         public void exception(Throwable t) {
5777                         Logger.defaultLogError(t);
5778                         }
5779
5780                         @Override
5781                         public String toString() {
5782                                 return "asyncRequest(PrimitiveRead) -> " + request;
5783                         }
5784
5785                 });
5786
5787         }
5788
5789         @Override
5790         public <T> void asyncRequest(ExternalRead<T> request,
5791                         final Listener<T> procedure) {
5792                 asyncRequest(request, (Procedure<T>) procedure);
5793         }
5794
5795         @Override
5796         final public <T> void asyncRequest(final ExternalRead<T> request,
5797                         final Procedure<T> procedure) {
5798
5799                 assert (request != null);
5800                 assert (procedure != null);
5801
5802                 ListenerBase listener = getListenerBase(procedure);
5803
5804                 if (parent != null || listener != null) {
5805
5806                         processor.query(this, request, parent, procedure, listener);
5807
5808                 } else {
5809
5810                         try {
5811
5812                                 request.register(this, new Listener<T>() {
5813
5814                                         @Override
5815                                         public void execute(T result) {
5816                                                 procedure.execute(result);
5817                                         }
5818
5819                                         @Override
5820                                         public void exception(Throwable t) {
5821                                                 procedure.exception(t);
5822                                         }
5823
5824                                         @Override
5825                                         public String toString() {
5826                                                 return "asyncRequest(PrimitiveRead) -> " + request;
5827                                         }
5828
5829                                         @Override
5830                                         public boolean isDisposed() {
5831                                                 return true;
5832                                         }
5833
5834                                 });
5835
5836                         } catch (Throwable t) {
5837
5838                                 if (t instanceof DatabaseException)
5839                                         procedure.exception(t);
5840                                 else
5841                                         procedure
5842                                                         .exception(new DatabaseException(
5843                                                                         "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
5844                                                                         t));
5845
5846                         }
5847
5848                 }
5849
5850         }
5851
5852         @Override
5853         public void asyncRequest(final Write request) {
5854
5855                 assert (request != null);
5856                 
5857                 getSession().asyncRequest(request);
5858
5859 //              processor.asyncWrite(request);
5860
5861         }
5862
5863         @Override
5864         public <T> void asyncRequest(final WriteResult<T> request, Procedure<T> procedure) {
5865                 throw new Error("Not implemented.");
5866         }
5867         
5868         @Override
5869         public void asyncRequest(Write request, Consumer<DatabaseException> callback) {
5870                 
5871                 assert (request != null);
5872                 
5873                 getSession().asyncRequest(request, callback);
5874                 
5875         }
5876
5877         @Override
5878         public void asyncRequest(final DelayedWrite request) {
5879
5880                 assert (request != null);
5881
5882                 getSession().asyncRequest(request);
5883
5884         }
5885
5886         @Override
5887         public <T> void asyncRequest(final DelayedWriteResult<T> request, Procedure<T> procedure) {
5888                 throw new Error("Not implemented.");
5889         }
5890         
5891         @Override
5892         public void asyncRequest(DelayedWrite r,
5893                         Consumer<DatabaseException> callback) {
5894                 throw new Error("Not implemented.");
5895         }
5896
5897         @Override
5898         public void asyncRequest(final WriteOnly request) {
5899
5900                 assert (request != null);
5901
5902                 getSession().asyncRequest(request);
5903
5904         }
5905
5906         @Override
5907         public <T> void asyncRequest(final WriteOnlyResult<T> request, Procedure<T> procedure) {
5908                 throw new Error("Not implemented.");
5909         }
5910         
5911         @Override
5912         public void asyncRequest(WriteOnly r, Consumer<DatabaseException> callback) {
5913                 throw new Error("Not implemented.");
5914         }
5915
5916         /*
5917          * Implementation of the interface ServiceLocator
5918          */
5919
5920         @Override
5921         public <T> T getService(Class<T> api) {
5922             if(WriteSupport.class == api) {
5923                 if(this instanceof WriteGraphImpl) {
5924                     WriteGraphImpl impl = (WriteGraphImpl)this;
5925                     return (T)impl.writeSupport;
5926                 }
5927             }
5928                 return getSession().getService(api);
5929         }
5930
5931         @Override
5932         public <T> T peekService(Class<T> api) {
5933                 return getSession().peekService(api);
5934         }
5935
5936         @Override
5937         public boolean hasService(Class<?> api) {
5938                 return getSession().hasService(api);
5939         }
5940
5941         @Override
5942         public <T> void registerService(Class<T> api, T service) {
5943                 getSession().registerService(api, service);
5944         }
5945         
5946         @Override
5947         public boolean isImmutable(Resource resource) throws DatabaseException {
5948                 ResourceImpl impl = (ResourceImpl)resource;
5949                 return processor.isImmutable(impl.id);
5950         }
5951
5952         /*
5953          * Internal routines
5954          */
5955
5956         protected static String INTERNAL_ERROR_STRING = "Transaction aborted due to internal client error. Contact application support.";
5957
5958         /*
5959          * callerThread is the currently running thread state.syncThread is blocking for
5960          * this execution state.syncParent is the blocking request
5961          */
5962
5963         final private boolean isExternal(int thread) {
5964                 return thread == Integer.MIN_VALUE;
5965         }
5966
5967 //      final private boolean isSync(int thread) {
5968 //              return thread < -1 && thread > Integer.MIN_VALUE;
5969 //      }
5970
5971         ReadGraphImpl(ReadGraphImpl graph) {
5972                 this(graph.parent, graph.processor);
5973         }
5974
5975         ReadGraphImpl(CacheEntry parent, QueryProcessor support) {
5976 //              this.state = new ReadGraphState(barrier, support);
5977                 this.parent = parent;
5978                 this.processor = support;
5979         }
5980         
5981         ReadGraphImpl(final QueryProcessor support) {
5982                 
5983 //              this.state = state;
5984                 this.processor = support;
5985                 this.parent = null;
5986                 
5987         }
5988
5989 //      public static ReadGraphImpl createSync(int syncThread, Object syncParent,
5990 //                      ReadGraphSupportImpl support) {
5991 //              return new ReadGraphImpl(syncThread, syncThread, syncParent, null,
5992 //                              support, new AsyncBarrierImpl(null));
5993 //      }
5994
5995         public static ReadGraphImpl create(QueryProcessor support) {
5996                 return new ReadGraphImpl(support);
5997         }
5998
5999 //      public ReadGraphImpl newAsync() {
6000 //              return this;
6001 ////            if(!state.synchronizedExecution) {
6002 ////                    return this;
6003 ////            } else {
6004 ////                    return new ReadGraphImpl(false, parent, state.support, state.barrier);
6005 ////            }
6006 //      }
6007
6008 //      public ReadGraphImpl newSync() {
6009 //              return new ReadGraphImpl(parent, processor);
6010 //      }
6011
6012         public ReadGraphImpl newSync(CacheEntry parentEntry) {
6013                 return new ReadGraphImpl(parentEntry, processor);
6014         }
6015
6016         public ReadGraphImpl newRestart(ReadGraphImpl impl) {
6017
6018                 WriteGraphImpl write = processor.getSession().getService(
6019                                 WriteGraphImpl.class);
6020
6021 //              if (write.callerThread != impl.callerThread)
6022 //                      return new WriteGraphImpl(impl.callerThread, parent, state.support, write.writeSupport, write.provider, write.state.barrier);
6023                 return write;
6024
6025         }
6026
6027 //      public ReadGraphImpl newSync(Object parentRequest) {
6028 //              return new ReadGraphImpl(callerThread, state.parent, state.support, new AsyncBarrierImpl(state.barrier));
6029 //      }
6030
6031 //      public ReadGraphImpl newSync(final int callerThread, Object parentRequest) {
6032 //              assert (state.syncThread == callerThread || (state.syncThread == Integer.MIN_VALUE && callerThread != Integer.MIN_VALUE));
6033 //              return new ReadGraphImpl(callerThread, callerThread, parentRequest,
6034 //                              state.parent, state.support, new AsyncBarrierImpl(state.barrier));
6035 //      }
6036 //
6037 //      public ReadGraphImpl newSyncAsync(Object parentRequest) {
6038 ////            assert (callerThread < 0);
6039 //              return new ReadGraphImpl(callerThread, state.syncThread, parentRequest,
6040 //                              state.parent, state.support, new AsyncBarrierImpl(state.barrier));
6041 //      }
6042 //
6043 //      public ReadGraphImpl newSyncAsync(final int callerThread,
6044 //                      Object parentRequest) {
6045 ////            assert (callerThread < 0);
6046 //              // assert(state.syncThread == callerThread || (state.syncThread == Integer.MIN_VALUE
6047 //              // && callerThread != Integer.MIN_VALUE) );
6048 //              return new ReadGraphImpl(callerThread, callerThread, parentRequest,
6049 //                              state.parent, state.support, new AsyncBarrierImpl(state.barrier));
6050 //      }
6051
6052         public ReadGraphImpl withAsyncParent(CacheEntry parent) {
6053                 return new ReadGraphImpl(parent, processor);
6054         }
6055
6056         public ReadGraphImpl withParent(CacheEntry parent) {
6057                 if(parent == this.parent) return this;
6058                 else return new ReadGraphImpl(parent, processor);
6059         }
6060
6061         final private ListenerBase getListenerBase(final Object procedure) {
6062                 if (procedure instanceof ListenerBase)
6063                         return (ListenerBase) procedure;
6064                 else
6065                         return null;
6066         }
6067
6068         public <T> void waitAsyncProcedure(AsyncMultiReadProcedure<T> procedure) {
6069                 
6070                 assert(procedure.done());
6071                 
6072 //              while (!procedure.done()) {
6073 //
6074 //                      boolean executed = processor.resumeTasks(callerThread, null, null);
6075 //                      if (!executed) {
6076 //                              try {
6077 //                                      Thread.sleep(1);
6078 //                                      //                                                              sema.tryAcquire(1, TimeUnit.MILLISECONDS);
6079 //                              } catch (InterruptedException e) {
6080 //                                      e.printStackTrace();
6081 //                              }
6082 //                      }
6083 //
6084 //              }
6085                 
6086         }
6087
6088         public <T> void waitAsyncProcedure(AsyncReadProcedure<T> procedure) {
6089                 
6090                 assert(procedure.done());
6091                 
6092 //              while (!procedure.done()) {
6093 //
6094 //                      boolean executed = processor.processor.resume(this);
6095 //                      if (!executed) {
6096 //                              try {
6097 //                                      Thread.sleep(1);
6098 //                                      //                                                              sema.tryAcquire(1, TimeUnit.MILLISECONDS);
6099 //                              } catch (InterruptedException e) {
6100 //                                      e.printStackTrace();
6101 //                              }
6102 //                      }
6103 //
6104 //              }
6105                 
6106         }
6107         
6108 //      public void waitAsync(Object request) {
6109 //              try {
6110 //                      state.barrier.waitBarrier(request, this);
6111 //              } catch (Throwable t) {
6112 //                      t.printStackTrace();
6113 //                      processor.scanPending();
6114 //                      processor.querySupport.checkTasks();
6115 //                      throw new RuntimeDatabaseException(t);
6116 //              }
6117 //      }
6118
6119 //      public void restart() {
6120 //              state.barrier.restart();
6121 //      }
6122
6123         public boolean resumeTasks() {
6124                 return processor.resumeTasks(this);
6125         }
6126
6127         Class<?> singleClass(Set<Resource> types) {
6128                 Class<?> result = null;
6129                 for (Resource type : types) {
6130                         Class<?> clazz = processor.getBuiltinValue(type);
6131                         if (clazz != null) {
6132                                 if (result != null)
6133                                         return null;
6134                                 else
6135                                         result = clazz;
6136                         }
6137                 }
6138                 return result;
6139         }
6140
6141         private String debugString(Resource r) {
6142                 String name = null;
6143                 try {
6144                         name = getPossibleRelatedValue(r, processor.getL0(this).HasName);
6145                 } catch (ManyObjectsForFunctionalRelationException e) {
6146                 Logger.defaultLogError(e);
6147                 } catch (ServiceException e) {
6148                 Logger.defaultLogError(e);
6149                 }
6150                 return "[" + name + " - " + r + "]";
6151         }
6152
6153         @Override
6154         public String toString() {
6155                 return "ReadGraphImpl[thread=" + Thread.currentThread() + "]";
6156         }
6157
6158         @Override
6159         final public int thread() {
6160                 return 0;
6161         }
6162         
6163     static class MultiTripleIntProcedure implements TripleIntProcedure {
6164
6165         final private AsyncMultiProcedure<Statement> procedure;
6166         final private ReadGraphImpl impl;
6167         final private QuerySupport support;
6168         
6169         public MultiTripleIntProcedure(AsyncMultiProcedure<Statement> procedure, ReadGraphImpl impl, QuerySupport support) {
6170                 this.procedure = procedure;
6171                 this.impl = impl;
6172                 this.support = support;
6173         }
6174         
6175         @Override
6176         public void execute(ReadGraphImpl graph, int s, int p, int o) {
6177                 try {
6178                         procedure.execute(graph, support.getStatement(s, p, o));
6179                 } catch (Throwable t2) {
6180                         Logger.defaultLogError(t2);
6181                 }
6182         }
6183
6184         @Override
6185         public void finished(ReadGraphImpl graph) {
6186                 try {
6187                         procedure.finished(graph);
6188 //                      impl.state.barrier.dec("ReadGraphSupportImpl.516");
6189                 } catch (Throwable t2) {
6190                         Logger.defaultLogError(t2);
6191                 }
6192         }
6193
6194         @Override
6195         public void exception(ReadGraphImpl graph, Throwable t) {
6196                 try {
6197                         procedure.exception(graph, t);
6198                 } catch (Throwable t2) {
6199                         Logger.defaultLogError(t2);
6200                 }
6201 //              impl.state.barrier.dec("ReadGraphSupportImpl.516");
6202         }
6203
6204         @Override
6205         public String toString() {
6206                 return "forEachObject with " + procedure;
6207         }
6208         
6209     }
6210
6211 //    private AsyncMultiProcedure<Resource> cacheKey = null;
6212 //    private MultiIntProcedure cacheResult = null;
6213 //    
6214 //    final IntProcedure forMultiProcedure(final AsyncMultiProcedure<Resource> procedure) {
6215 //      
6216 //      if(procedure == cacheKey) return cacheResult; 
6217 //      
6218 //      cacheResult = new MultiIntProcedure(procedure, this, processor.support);
6219 //      cacheKey = procedure;
6220 //      
6221 //      return cacheResult;
6222 //      
6223 //    }
6224 //
6225 //    private AsyncMultiProcedure<Statement> cacheKey2 = null;
6226 //    private MultiTripleIntProcedure cacheResult2 = null;
6227 //
6228 //    final synchronized TripleIntProcedure forMultiProcedure(final AsyncMultiProcedure<Statement> procedure) {
6229 //      
6230 //      if(procedure == cacheKey2) return cacheResult2; 
6231 //      
6232 //      cacheResult2 = new MultiTripleIntProcedure(procedure, this, processor.support);
6233 //      cacheKey2 = procedure;
6234 //      
6235 //      return cacheResult2;
6236 //      
6237 //    }
6238     
6239     @Override
6240     public Datatype getDataType(Resource subject) throws DatabaseException {
6241         for(Resource dataTypeResource : getObjects(subject, processor.getL0(this).HasDataType))
6242                 return getValue(dataTypeResource, Bindings.getBindingUnchecked(Datatype.class));
6243         throw new DoesNotContainValueException("The literal has no data type.");
6244     }
6245     
6246     protected <T extends Accessor> T getAccessor4File(Resource subject)
6247     throws DatabaseException {
6248         return null;
6249         /*        
6250         byte[]  bytes = processor.support.getValue(g, subject);
6251         if (null == bytes)
6252             return null;
6253         try {
6254             BinaryVariant va = (BinaryVariant) Accessors.getAccessor(bytes, Datatypes.VARIANT);
6255             Accessor ca = va.getContentAccessor();
6256             return (T)ca;
6257         } catch (AccessorConstructionException e) {
6258             throw new DatabaseException(e);
6259         }
6260         */
6261         /*
6262         if (null == bytes)
6263             return null;
6264         Binding datatype_binding = Bindings.getBindingUnchecked(DataType.class);
6265         Serializer datatype_serializer = datatype_binding.serializer();
6266         DataType datatype;
6267         try {
6268             BinaryMemory in = new BinaryMemory(ByteBuffer.wrap(bytes));
6269             datatype = (DataType)datatype_serializer.deserialize(in);
6270             Binding data_binding = Bindings.getBinding(datatype);
6271             Serializer data_serializer = data_binding.serializer(BinarySerializationFormat.INSTANCE);
6272             Object o = data_serializer.deserialize(in);
6273             try {
6274                 return (T)Accessors.getAccessor(data_binding, o);
6275             } catch(AccessorConstructionException e) {
6276                 return null;
6277             }
6278         } catch (Exception e) {
6279             throw new DatabaseException(e);
6280         }*/
6281     }
6282     @SuppressWarnings("unchecked")
6283     @Override
6284     public <T extends Accessor> T getAccessor(Resource subject) throws DatabaseException {
6285         RandomAccessBinary rab = getRandomAccessBinary(subject);
6286         try {
6287             return (T)Accessors.getAccessor(rab, getDataType(subject));
6288         } catch(AccessorConstructionException e) {
6289             throw new DatabaseException(e);
6290         }
6291     }
6292     @SuppressWarnings("unchecked")
6293     protected <T extends Accessor> T createAccessor(Resource resource, Datatype datatype, Object intialValue)
6294     throws DatabaseException {
6295         RandomAccessBinary rab = createRandomAccessBinary(resource, datatype, intialValue);
6296         try {
6297             return (T)Accessors.getAccessor(rab, datatype);
6298         } catch(AccessorConstructionException e) {
6299             throw new DatabaseException(e);
6300         }
6301     }
6302     @Override
6303     public RandomAccessBinary getRandomAccessBinary(Resource subject) throws DatabaseException {
6304         RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class);
6305         ResourceData rd = ravs.get(subject);
6306         if (null != rd)
6307             return rd;
6308         try {
6309             ExternalValueSupport evs = getService(ExternalValueSupport.class);
6310             long size = evs.getValueSize(this, subject); // Throws DatabaseException if no old external value.
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" + subject.getResourceId());
6317                 rd = new ResourceData(new BinaryFile(file), true); // Old external value.
6318                 final int N = 1<<20;
6319                 long left = size;
6320                 long offset = 0;
6321                 while (left > 0) {
6322                     int length = N < left ? N : (int)left;
6323                     byte[] bytes = evs.readValue(this, subject, offset, length);
6324                     offset += bytes.length;
6325                     left -= bytes.length;
6326                     rd.binaryFile.write(bytes);
6327                 }
6328                 ravs.put(subject, rd);
6329                 return rd;
6330             } catch (Exception e) {
6331                 throw new DatabaseException("Resource " + subject + " have value but there was problem with accessing value data.", e);
6332             }
6333         } catch (Exception e) {
6334             if(Development.DEVELOPMENT) {
6335                 if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
6336                     e.printStackTrace();
6337                 }
6338             }
6339         }
6340         Datatype datatype = getDataType(subject);
6341         Object value = getPossibleValue(subject, Bindings.getBinding(datatype));
6342         return createRandomAccessBinary(subject, datatype, value);
6343     }
6344     public RandomAccessBinary createRandomAccessBinary(Resource resource, Datatype datatype, Object initialValue)
6345     throws DatabaseException {
6346         RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class);
6347         try {
6348             File platform = Platform.getLocation().toFile();
6349             File tempFiles = new File(platform, "tempFiles");
6350             File dbDir = new File(tempFiles, "db");
6351             dbDir.mkdirs();
6352             File file = new File(dbDir, "ResourceFile" + resource.getResourceId());
6353             ResourceData rd = new ResourceData(new BinaryFile(file), false);
6354             Binding binding = Bindings.getBinding(datatype);
6355             if (null == initialValue) {
6356                 initialValue = binding.createDefault();
6357             }
6358             Serializer serializer = binding.serializer();
6359             byte[] bytes = serializer.serialize(initialValue);
6360             rd.binaryFile.write(bytes);
6361             ravs.put(resource, rd);
6362             return rd;
6363         } catch (Exception e) {
6364             if (e instanceof DatabaseException)
6365                 throw (DatabaseException)e;
6366             else
6367                 throw new DatabaseException(e);
6368         }
6369     }
6370
6371 //    static class ExternalValueRequest<T> extends ResourceRead<T> {
6372 //
6373 //              public ExternalValueRequest(Resource resource) {
6374 //                      super(resource);
6375 //              }
6376 //
6377 //              @SuppressWarnings("unchecked")
6378 //              @Override
6379 //              public T perform(ReadGraph graph) throws DatabaseException {
6380 //              try {
6381 //                      
6382 //                      String uri = graph.getURI(resource);
6383 //                      if(Layer0.URIs.Functions_functionApplication.equals(uri)) return (T)functionApplication;
6384 //                      
6385 //                      return (T)ReflectionUtils.getValue(uri).getValue();
6386 //                      
6387 //              } catch(ValueNotFoundException e) {
6388 //                      throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e);
6389 //              } catch(ClassCastException e) {
6390 //                      throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e);
6391 //              }
6392 //              }
6393 //      
6394 //    }
6395     
6396     @SuppressWarnings("unchecked")
6397     @Override
6398     public <T> T getValue2(Resource r, Object context) throws DatabaseException {
6399         Layer0 L0 = processor.getL0(this);
6400         Set<Resource> types = getTypes(r);
6401         
6402         if(types.contains(L0.Literal)) {
6403                 if(isImmutable(r)) {
6404                         return syncRequest(new ValueImplied<T>(r));
6405                 } else {
6406                         return getValue(r);
6407                 }
6408         }
6409         else if(types.contains(L0.ExternalValue)) {
6410                 return (T)syncRequest(new AdaptValue(r), TransientCacheListener.<Object>instance());
6411         }
6412         else {
6413
6414             Function3<ReadGraph,Resource,Object,T> function = requestValueFunction(r);
6415             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r);
6416             try {
6417                 return function.apply(this, r, context);
6418             } catch(RuntimeException e) {
6419                 DatabaseException dte = findPossibleRootException(e);
6420                 if(dte != null) throw dte;
6421                 else throw new DatabaseException(e);
6422             }
6423                 
6424         }
6425     }
6426
6427     @Override
6428     public Variant getVariantValue2(Resource r, Object context) throws DatabaseException {
6429         Layer0 L0 = processor.getL0(this);
6430         Set<Resource> types = getTypes(r);
6431         
6432         if(types.contains(L0.Literal)) {
6433             if(isImmutable(r)) {
6434                 return syncRequest(new VariantValueImplied(r));
6435             } else {
6436                 return getVariantValue(r);
6437             }
6438         }
6439         else if(types.contains(L0.ExternalValue)) {
6440             Object value = syncRequest(new AdaptValue(r), TransientCacheListener.<Object>instance());
6441             try {
6442                 return new Variant(Bindings.OBJECT.getContentBinding(value), value);
6443             } catch ( org.simantics.databoard.binding.error.BindingException e ) {
6444                 throw new BindingException( "No binding found for class " + value.getClass().getName(), e );
6445             }
6446         }
6447         else {
6448
6449             Function3<ReadGraph,Resource,Object,Object> function = requestValueFunction(r);
6450             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r);
6451             try {
6452                 Object value = function.apply(this, r, context);
6453                 try {
6454                     return new Variant(Bindings.OBJECT.getContentBinding(value), value);
6455                 } catch ( org.simantics.databoard.binding.error.BindingException e ) {
6456                     throw new BindingException( "No binding found for class " + value.getClass().getName(), e );
6457                 }
6458             } catch(RuntimeException e) {
6459                 DatabaseException dte = findPossibleRootException(e);
6460                 if(dte != null) throw dte;
6461                 else throw new DatabaseException(e);
6462             }
6463         }
6464     }
6465     
6466     @Override
6467     public <T> T getPossibleValue2(Resource subject, Object context) throws DatabaseException {
6468         try {
6469                 return getValue2(subject, context);
6470         } catch (DatabaseException e) {
6471                 return null;
6472         }
6473     }
6474
6475     static class PossibleConverterFunction<T> extends ResourceRead<Function3<ReadGraph,Resource,Object,T>> {
6476         
6477         public PossibleConverterFunction(Resource resource) {
6478                         super(resource);
6479                 }
6480
6481         @Override
6482         public Function3<ReadGraph,Resource,Object,T> perform(ReadGraph graph) throws DatabaseException {
6483                 return compute(graph, resource);
6484         }
6485         
6486         @SuppressWarnings("unchecked")
6487                 public static <T> Function3<ReadGraph,Resource,Object,T> compute(ReadGraph graph, Resource resource) throws DatabaseException {
6488             Layer0 L0 = Layer0.getInstance(graph);
6489             for(Resource converter : graph.getObjects(resource, L0.ConvertsToValueWith)) {
6490                 try {
6491                         if(L0.Functions_functionApplication.equals(converter)) {
6492                                 return (Function3<ReadGraph,Resource,Object,T>)graph.syncRequest(new AdaptValue(resource));
6493                         } else {
6494                                 return graph.getValue2(converter, resource);
6495                         }
6496                 } catch(RuntimeException e) {
6497                     DatabaseException dte = findPossibleRootException(e);
6498                     if(dte != null) throw dte;
6499                     else throw new DatabaseException(e);
6500                 }
6501             }
6502             return null;
6503         }
6504         
6505     }
6506     
6507     <T> Function3<ReadGraph,Resource,Object,T> requestValueFunction(Resource r) throws DatabaseException {
6508         if(isImmutable(r))
6509                 return syncRequest(new PossibleConverterFunction<T>(r), TransientCacheAsyncListener.<Function3<ReadGraph,Resource,Object,T>>instance());
6510         else
6511                 return syncRequest(new PossibleConverterFunction<T>(r));
6512     }
6513     
6514     /**
6515      * Get a value associated with a graph {@link Resource}, using a possible context object and
6516      * a desired value binding. The following methods are tried in order to retreive the value:
6517      * <ol>
6518      *   <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>
6519      *   <li>If the resource is a {@code L0.ExternalValue}, the value is acquired using
6520      *       {@link ReflectionUtils#getValue(String)}.</li>
6521      *   <li>If the resource is associated with a suitable value converter with relation {@code L0.ConvertsToValueWith}
6522      *       (see {@link #requestValueFunction(Resource)}), the value function is called with the graph, the resource
6523      *       and the context object.</li>
6524      * </ul>
6525      * 
6526      * @param r  A graph resource with which the value is associated
6527      * @param context  A context object that is used for acquiring the value (only applied in case 3)
6528      * @param binding  A binding for the value type (only applied in case 1)
6529      * @return  The value of the graph node.
6530      * @throws DoesNotContainValueException  No value is associated with the graph node.
6531      * @throws DatabaseException  Other errors, such as an error in casting the value to the return type or
6532      *         a runtime error in the value function.
6533      */
6534     @SuppressWarnings("unchecked")
6535         @Override
6536     public <T> T getValue2(Resource r, Object context, Binding binding) throws DatabaseException {
6537         if (binding instanceof ObjectVariantBinding)
6538                 return getValue2(r, context);
6539         
6540         Layer0 L0 = processor.getL0(this);
6541         Set<Resource> types = getTypes(r);
6542         if(types.contains(L0.Literal)) {
6543                 if(isImmutable(r)) {
6544                         return syncRequest(new Value<T>(r, binding));
6545                 } else {
6546                         return getValue(r, binding);
6547                 }
6548         } else if(types.contains(L0.ExternalValue)) {
6549                 try {
6550                         return (T)ReflectionUtils.getValue(getURI(r)).getValue();
6551                 } catch(ValueNotFoundException e) {
6552                         throw new DatabaseException(e);
6553                 } catch(ClassCastException e) {
6554                         throw new DatabaseException(e);
6555                 }
6556         }
6557         else {
6558             Function3<ReadGraph,Resource,Object,T> function = requestValueFunction(r);
6559             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function.");
6560             try {
6561                 Object value = function.apply(this, r, context);
6562                 if(binding.isInstance(value)) return (T)value;
6563                 Binding srcBinding = Bindings.OBJECT.getContentBinding(value);
6564                 return (T)Bindings.adapt(value, srcBinding, binding);
6565             } catch(RuntimeException e) {
6566                 DatabaseException dte = findPossibleRootException(e);
6567                 if(dte != null) throw dte;
6568                 else throw new DatabaseException(e);
6569             } catch (AdaptException e) {
6570                 throw new DatabaseException(e);
6571                         } catch (org.simantics.databoard.binding.error.BindingException e) {
6572                 throw new DatabaseException(e);
6573                         }
6574         }
6575     }
6576     
6577     @Override
6578     public <T> T getPossibleValue2(Resource subject, Object context, Binding binding) throws DatabaseException {
6579         try {
6580                 return getValue2(subject, context, binding);
6581         } catch (DatabaseException e) {
6582                 return null;
6583         }
6584     }
6585     
6586         private static DatabaseException findPossibleRootException(Throwable t) {
6587                 if(t == null) return null;
6588                 if(t instanceof DatabaseException) return (DatabaseException)t;
6589                 if(t instanceof RuntimeException || t instanceof InvocationTargetException) {
6590                         return findPossibleRootException(t.getCause());
6591                 }
6592                 return null;
6593         }
6594     
6595     @Override
6596     public <T> T getRelatedValue2(Resource subject, Resource relation) throws DatabaseException {
6597         return getRelatedValue2(subject, relation, subject);
6598     }
6599     
6600     @Override
6601     public Variant getRelatedVariantValue2(Resource subject, Resource relation) throws DatabaseException {
6602         return getRelatedVariantValue2(subject, relation, subject);
6603     }
6604     
6605     @Override
6606     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation) throws DatabaseException {
6607         try {
6608                 Resource object = getPossibleObject(subject, relation);
6609                 if(object == null) return null;
6610                 else return getValue2(object, subject);
6611         } catch (DatabaseException e) {
6612                 return null;
6613         }
6614     }
6615
6616     @Override
6617     public <T> T getRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6618                 if(Development.DEVELOPMENT) {
6619                         String error = L0Validations.checkValueType(this, subject, relation);
6620                         if(error != null) {
6621                                 Logger.defaultLogError(new ValidationException(error));
6622                                 //throw new ValidationException(error);
6623                                 new ValidationException(error).printStackTrace();
6624                         }
6625                 }
6626         return getValue2(getSingleObject(subject, relation), context);
6627     }
6628     
6629     @Override
6630     public Variant getRelatedVariantValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6631         if(Development.DEVELOPMENT) {
6632             String error = L0Validations.checkValueType(this, subject, relation);
6633             if(error != null) {
6634                 Logger.defaultLogError(new ValidationException(error));
6635                 //throw new ValidationException(error);
6636                 new ValidationException(error).printStackTrace();
6637             }
6638         }
6639         return getVariantValue2(getSingleObject(subject, relation), context);
6640     }
6641     
6642     @Override
6643     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6644         try {
6645                 Resource object = getPossibleObject(subject, relation);
6646                 if(object == null) return null;
6647                 else return getValue2(object, context);
6648         } catch (DatabaseException e) {
6649                 return null;
6650         }
6651     }
6652
6653     @Override
6654     public <T> T getRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException {
6655         return getRelatedValue2(subject, relation, subject, binding);
6656     }
6657     
6658     @Override
6659     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException {
6660         try {
6661                 Resource object = getPossibleObject(subject, relation);
6662                 if(object == null) return null;
6663                 return getValue2(object, subject, binding);
6664         } catch (DatabaseException e) {
6665                 return null;
6666         }
6667     }
6668
6669     @Override
6670     public <T> T getRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException {
6671         return getValue2(getSingleObject(subject, relation), context, binding);
6672     }
6673     
6674     @Override
6675     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException {
6676         try {
6677                 Resource object = getPossibleObject(subject, relation);
6678                 if(object == null) return null;
6679                 else return getValue2(object, context, binding);
6680         } catch (DatabaseException e) {
6681                 return null;
6682         }
6683     }
6684     
6685     @Override
6686     public Type getRelatedValueType(Resource subject, Resource relation) throws DatabaseException {
6687         Layer0 L0 = processor.getL0(this);
6688         Resource property = getSingleObject(subject, relation);
6689         String typeText = (String)getRelatedValue(property, L0.HasValueType, Bindings.STRING);
6690         try {
6691             return org.simantics.scl.compiler.types.Types.parseType(typeText);
6692         } catch (SCLTypeParseException e) {
6693             throw new DatabaseException(e);
6694         }
6695     }
6696     
6697     @Override
6698     public boolean setSynchronous(boolean value) {
6699         boolean old = processor.synch;
6700         processor.synch = value;
6701         return old;
6702     }
6703     
6704     @Override
6705     public boolean getSynchronous() {
6706         return processor.synch;
6707     }
6708     
6709     public void ensureLoaded(int resource) {
6710         processor.querySupport.ensureLoaded(this, resource);
6711     }
6712     
6713     public void ensureLoaded(int resource, int predicate) {
6714         processor.querySupport.ensureLoaded(this, resource, predicate);
6715     }
6716
6717     public byte[] getValue(int resource) {
6718         return processor.querySupport.getValue(this, resource);
6719     }
6720     
6721     public int thread(int resource) {
6722         return (resource >>> 16) & processor.THREAD_MASK;
6723     }
6724
6725     public int thread(Resource resource) {
6726         return (((ResourceImpl)resource).id >>> 16) & processor.THREAD_MASK;
6727     }
6728     
6729     public ResourceSupport getResourceSupport() {
6730         return processor.getResourceSupport();
6731     }
6732     
6733     @Override
6734     public Object getModificationCounter() {
6735         return processor.getSession().getModificationCounter();
6736     }
6737     
6738 }