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