Removed contact application support prints
[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.nio.BufferUnderflowException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.IdentityHashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
29 import java.util.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.DevelopmentKeys;
49 import org.simantics.db.ExternalValueSupport;
50 import org.simantics.db.ReadGraph;
51 import org.simantics.db.RelationContext;
52 import org.simantics.db.Resource;
53 import org.simantics.db.Session;
54 import org.simantics.db.Statement;
55 import org.simantics.db.adaption.AdaptionService;
56 import org.simantics.db.common.primitiverequest.Adapter;
57 import org.simantics.db.common.primitiverequest.Builtin;
58 import org.simantics.db.common.primitiverequest.DatatypeBinding;
59 import org.simantics.db.common.primitiverequest.ForEachAssertedObject;
60 import org.simantics.db.common.primitiverequest.ForEachAssertedStatement;
61 import org.simantics.db.common.primitiverequest.HasStatement;
62 import org.simantics.db.common.primitiverequest.HasStatementSubject;
63 import org.simantics.db.common.primitiverequest.HasStatementSubjectObject;
64 import org.simantics.db.common.primitiverequest.HasValue;
65 import org.simantics.db.common.primitiverequest.Inverse;
66 import org.simantics.db.common.primitiverequest.IsInheritedFrom;
67 import org.simantics.db.common.primitiverequest.IsInstanceOf;
68 import org.simantics.db.common.primitiverequest.IsSubrelationOf;
69 import org.simantics.db.common.primitiverequest.OrderedSet;
70 import org.simantics.db.common.primitiverequest.PossibleAdapter;
71 import org.simantics.db.common.primitiverequest.PossibleInverse;
72 import org.simantics.db.common.primitiverequest.PossibleObject;
73 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
74 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied;
75 import org.simantics.db.common.primitiverequest.PossibleStatement;
76 import org.simantics.db.common.primitiverequest.PossibleType;
77 import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter;
78 import org.simantics.db.common.primitiverequest.PossibleValue;
79 import org.simantics.db.common.primitiverequest.PossibleValueImplied;
80 import org.simantics.db.common.primitiverequest.RelatedValue;
81 import org.simantics.db.common.primitiverequest.RelatedValueImplied;
82 import org.simantics.db.common.primitiverequest.SingleObject;
83 import org.simantics.db.common.primitiverequest.SingleStatement;
84 import org.simantics.db.common.primitiverequest.SingleType;
85 import org.simantics.db.common.primitiverequest.SingleTypeAny;
86 import org.simantics.db.common.primitiverequest.Types;
87 import org.simantics.db.common.primitiverequest.UniqueAdapter;
88 import org.simantics.db.common.primitiverequest.Value;
89 import org.simantics.db.common.primitiverequest.ValueImplied;
90 import org.simantics.db.common.primitiverequest.VariantValueImplied;
91 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
92 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
93 import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
94 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
95 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
96 import org.simantics.db.common.procedure.single.SyncReadProcedure;
97 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrErrorProcedure;
98 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure;
99 import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure;
100 import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure;
101 import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure;
102 import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure;
103 import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure;
104 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
105 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
106 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
107 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
108 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
109 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
110 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
111 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
112 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
113 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
114 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
115 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
116 import org.simantics.db.common.request.AdaptValue;
117 import org.simantics.db.common.request.ResourceRead;
118 import org.simantics.db.common.utils.Logger;
119 import org.simantics.db.common.utils.NameUtils;
120 import org.simantics.db.common.validation.L0Validations;
121 import org.simantics.db.exception.AdaptionException;
122 import org.simantics.db.exception.ArgumentException;
123 import org.simantics.db.exception.AssumptionException;
124 import org.simantics.db.exception.BindingException;
125 import org.simantics.db.exception.DatabaseException;
126 import org.simantics.db.exception.DoesNotContainValueException;
127 import org.simantics.db.exception.EmptyResourceException;
128 import org.simantics.db.exception.InternalException;
129 import org.simantics.db.exception.InvalidLiteralException;
130 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
131 import org.simantics.db.exception.NoInverseException;
132 import org.simantics.db.exception.NoSingleResultException;
133 import org.simantics.db.exception.ResourceNotFoundException;
134 import org.simantics.db.exception.ServiceException;
135 import org.simantics.db.exception.ValidationException;
136 import org.simantics.db.impl.BlockingAsyncProcedure;
137 import org.simantics.db.impl.RelationContextImpl;
138 import org.simantics.db.impl.ResourceImpl;
139 import org.simantics.db.impl.internal.RandomAccessValueSupport;
140 import org.simantics.db.impl.internal.ResourceData;
141 import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
142 import org.simantics.db.impl.query.CacheEntry;
143 import org.simantics.db.impl.query.QueryCache;
144 import org.simantics.db.impl.query.QueryCacheBase;
145 import org.simantics.db.impl.query.QueryProcessor;
146 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
147 import org.simantics.db.impl.query.QuerySupport;
148 import org.simantics.db.impl.query.TripleIntProcedure;
149 import org.simantics.db.impl.support.ResourceSupport;
150 import org.simantics.db.procedure.AsyncListener;
151 import org.simantics.db.procedure.AsyncMultiListener;
152 import org.simantics.db.procedure.AsyncMultiProcedure;
153 import org.simantics.db.procedure.AsyncProcedure;
154 import org.simantics.db.procedure.AsyncSetListener;
155 import org.simantics.db.procedure.Listener;
156 import org.simantics.db.procedure.ListenerBase;
157 import org.simantics.db.procedure.MultiListener;
158 import org.simantics.db.procedure.MultiProcedure;
159 import org.simantics.db.procedure.Procedure;
160 import org.simantics.db.procedure.SetListener;
161 import org.simantics.db.procedure.StatementProcedure;
162 import org.simantics.db.procedure.SyncListener;
163 import org.simantics.db.procedure.SyncMultiListener;
164 import org.simantics.db.procedure.SyncMultiProcedure;
165 import org.simantics.db.procedure.SyncProcedure;
166 import org.simantics.db.procedure.SyncSetListener;
167 import org.simantics.db.request.AsyncMultiRead;
168 import org.simantics.db.request.AsyncRead;
169 import org.simantics.db.request.DelayedWrite;
170 import org.simantics.db.request.DelayedWriteResult;
171 import org.simantics.db.request.ExternalRead;
172 import org.simantics.db.request.MultiRead;
173 import org.simantics.db.request.Read;
174 import org.simantics.db.request.ReadInterface;
175 import org.simantics.db.request.Write;
176 import org.simantics.db.request.WriteInterface;
177 import org.simantics.db.request.WriteOnly;
178 import org.simantics.db.request.WriteOnlyResult;
179 import org.simantics.db.request.WriteResult;
180 import org.simantics.layer0.Layer0;
181 import org.simantics.scl.compiler.types.Type;
182 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
183 import org.simantics.scl.reflection.ReflectionUtils;
184 import org.simantics.scl.reflection.ValueNotFoundException;
185 import org.simantics.scl.runtime.function.Function3;
186 import org.simantics.utils.DataContainer;
187 import org.simantics.utils.Development;
188 import org.simantics.utils.datastructures.Pair;
189 import org.simantics.utils.datastructures.collections.CollectionUtils;
190 import org.slf4j.LoggerFactory;
191
192 import gnu.trove.map.hash.TObjectIntHashMap;
193
194 public class ReadGraphImpl implements AsyncReadGraph {
195
196     private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
197
198     final static boolean EMPTY_RESOURCE_CHECK = false;
199     
200         final public CacheEntry parent;
201         final public QueryProcessor processor;
202         
203         public AsyncBarrierImpl asyncBarrier = null;
204         
205         final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
206         final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
207
208         final public static TObjectIntHashMap<String> counters = new TObjectIntHashMap<String>(); 
209         
210         public static void resetCounters() {
211                 counters.clear();
212         }
213         
214         public static String listCounters(File file) throws IOException {
215                 
216                 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
217
218                 for(Pair<String,Integer> p : CollectionUtils.valueSortedEntries(counters)) {
219                         b.print(-p.second + " " + p.first + "\n");
220                 }
221
222                 b.close();
223
224                 return "Dumped " + counters.size() + " queries.";
225                 
226         }
227         
228         /*
229          * Implementation of the interface ReadGraph
230          */
231         final public String getURI(final Resource resource)     throws AssumptionException, ValidationException, ServiceException {
232                 
233                 assert (resource != null);
234
235                 try {
236
237                         return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource));
238
239                 } catch (AssumptionException e) {
240
241                         throw new AssumptionException(e);
242
243                 } catch (ValidationException e) {
244
245                         throw new ValidationException(e);
246
247                 } catch (ServiceException e) {
248
249                         throw new ServiceException(e);
250
251                 } catch (DatabaseException e) {
252
253                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
254
255                 }
256
257         }
258         
259         final public String getPossibleURI(final Resource resource)     throws ValidationException,     ServiceException {
260
261                 assert (resource != null);
262
263                 try {
264
265                         return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource));
266
267                 } catch (ValidationException e) {
268
269                         throw new ValidationException(e);
270
271                 } catch (ServiceException e) {
272
273                         throw new ServiceException(e);
274
275                 } catch (DatabaseException e) {
276
277                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
278
279                 }
280
281         }
282
283         final public Resource getResource(final String id)
284                         throws ResourceNotFoundException, ValidationException,
285                         ServiceException {
286
287                 assert (id != null);
288
289                 try {
290
291                         Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
292                         // FIXME: stupid to throw this here and catch and wrap it right away
293                         if(rid == 0) throw new ResourceNotFoundException(id);
294                         return processor.querySupport.getResource(rid);
295
296                 } catch (ResourceNotFoundException e) {
297
298                         throw new ResourceNotFoundException(id, e);
299
300                 } catch (ValidationException e) {
301
302                         throw new ValidationException(e);
303
304                 } catch (ServiceException e) {
305
306                         throw new ServiceException(e);
307
308                 } catch (DatabaseException e) {
309
310                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
311
312                 }
313
314         }
315
316         final public Resource getPossibleResource(final String id)
317         throws ResourceNotFoundException, ValidationException,
318         ServiceException {
319
320                 assert (id != null);
321
322                 try {
323
324                         return getResource(id);
325
326                 } catch (ResourceNotFoundException e) {
327                         
328                         return null;
329
330                 } catch (ValidationException e) {
331
332                         throw new ValidationException(e);
333
334                 } catch (ServiceException e) {
335
336                         throw new ServiceException(e);
337
338                 } catch (DatabaseException e) {
339
340                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
341
342                 }
343
344         }
345         
346         @Override
347         public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
348                 
349                 assert (resource != null);
350
351                 try {
352
353                         int rId = processor.querySupport.getId(resource);
354                         return QueryCache.resultChildMap(this, rId, parent, null);
355
356                 } catch (ValidationException e) {
357
358                         throw new ValidationException(e);
359
360                 } catch (ServiceException e) {
361
362                         throw new ServiceException(e);
363
364                 } catch (DatabaseException e) {
365
366                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
367
368                 }
369                 
370         }
371
372         final public Resource getRootLibrary() {
373                 return processor.getRootLibraryResource();
374         }
375         
376         final public Resource getBuiltin(final String id)
377                         throws ResourceNotFoundException, ServiceException {
378
379                 assert (id != null);
380
381                 try {
382
383                         return syncRequest(new Builtin(id));
384
385                 } catch (ResourceNotFoundException e) {
386
387                         throw new ResourceNotFoundException(id, e);
388
389                 } catch (ServiceException e) {
390
391                         throw new ServiceException(e);
392
393                 } catch (DatabaseException e) {
394
395                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
396
397                 }
398
399         }
400
401         static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure {
402
403                 private static Throwable DONE = new Throwable();
404                 
405                 Throwable exception = null;
406                 
407                 final ResourceSupport support;
408                 
409                 public StatementReadProcedure(ResourceSupport support) {
410                         this.support = support;
411                 }
412                 
413                 @Override
414                 public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) {
415                         add(s);
416                         add(p);
417                         add(o);
418                 }
419                 
420                 @Override
421                 public void finished(AsyncReadGraph graph) {
422                         exception = DONE;
423                 }
424
425                 @Override
426                 public void exception(AsyncReadGraph graph, Throwable t) {
427                         exception = t;
428                 }
429                 
430                 public void checkAndThrow() throws DatabaseException {
431                         if(exception != DONE) {
432                                 if (exception instanceof DatabaseException)
433                                         throw (DatabaseException) exception;
434                                 else
435                                         throw new DatabaseException(
436                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
437                                                         exception);
438                         }
439                 }
440                 
441                 public boolean done() {
442                         return exception != null;
443                 }
444
445                 @Override
446                 public boolean contains(Object obj) {
447                     if(!(obj instanceof InternalStatement))
448                         return false;
449                     InternalStatement statement = (InternalStatement)obj;
450                     int s = statement.s;
451                     int p = statement.p;
452                     int o = statement.o;
453                     for(int i=0;i<sizeInternal();i+=3)
454                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
455                     return true;
456                     return false;
457                 }
458
459                 @SuppressWarnings("unchecked")
460         @Override
461                 public <T> T[] toArray(T[] a) {
462                     int length = sizeInternal() / 3;
463                     if(length > a.length) {
464                         Class<?> arrayType = a.getClass();
465                         a = (arrayType == Object[].class) 
466                                 ? (T[]) new Object[length]
467                                 : (T[]) Array.newInstance(arrayType.getComponentType(), length);
468                     }
469                     else {
470                         for(int i=length;i<a.length;++i)
471                             a[i] = null;
472                     }
473             for(int i=0,j=0;i<sizeInternal();i+=3,++j)
474                 a[j] = (T)new InternalStatement(support, getQuick(i), getQuick(i+1), getQuick(i+2));
475             return a;
476                 }
477
478                 @Override
479                 public boolean add(Statement e) {
480                         throw new UnsupportedOperationException();
481                 }
482
483                 @Override
484                 public boolean remove(Object o) {
485                         throw new UnsupportedOperationException();
486                 }
487
488                 @Override
489                 public boolean addAll(Collection<? extends Statement> c) {
490                         throw new UnsupportedOperationException();
491                 }
492
493                 class IteratorImpl implements ListIterator<Statement> {
494             
495             int index;
496             
497             public IteratorImpl(int index) {
498                 this.index = index;
499             }
500
501             @Override
502             public boolean hasNext() {
503                 return index < sizeInternal(); 
504             }
505
506             @Override
507             public Statement next() {
508                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
509                 index += 3;
510                 return result;
511             }
512
513             @Override
514             public void remove() {
515                 throw new Error("Not supported");
516             }
517
518             @Override
519             public boolean hasPrevious() {
520                 return index > 0;
521             }
522
523             @Override
524             public Statement previous() {
525                 index -= 3;
526                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
527                 return result;
528             }
529
530             @Override
531             public int nextIndex() {
532                 return index/3;
533             }
534
535             @Override
536             public int previousIndex() {
537                 return index/3-1;
538             }
539
540             @Override
541             public void set(Statement e) {
542                 throw new UnsupportedOperationException();
543             }
544
545             @Override
546             public void add(Statement e) {
547                 throw new UnsupportedOperationException();
548             }
549             
550         };
551         
552                 @Override
553                 public Iterator<Statement> iterator() {
554                         return new IteratorImpl(0);
555                 }
556                 
557                 @Override
558                 public int size() {
559                         return sizeInternal() / 3;
560                 }
561
562                 @Override
563                 public Object[] toArray() {
564                     Object[] result = new Object[sizeInternal() / 3];
565                     for(int i=0,j=0;j<sizeInternal();i++,j+=3)
566                         result[i] = new InternalStatement(support, getQuick(j), getQuick(j+1), getQuick(j+2));
567                         return result;
568                 }
569
570         @Override
571         public boolean addAll(int index, Collection<? extends Statement> c) {
572             throw new UnsupportedOperationException();
573         }
574
575         @Override
576         public Statement get(int index) {
577             index += 3;
578             if(index < 0 || index >= sizeInternal())
579                 throw new IndexOutOfBoundsException();
580             return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
581         }
582
583         @Override
584         public Statement set(int index, Statement element) {
585             throw new UnsupportedOperationException();
586         }
587
588         @Override
589         public void add(int index, Statement element) {
590             throw new UnsupportedOperationException();
591         }
592
593         @Override
594         public Statement remove(int index) {
595             throw new UnsupportedOperationException();
596         }
597
598         @Override
599         public int indexOf(Object obj) {
600             if(!(obj instanceof InternalStatement))
601                 return -1;
602             InternalStatement statement = (InternalStatement)obj;
603             int s = statement.s;
604             int p = statement.p;
605             int o = statement.o;
606             for(int i=0;i<sizeInternal();i+=3)
607                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
608                     return i/3;
609             return -1;
610         }
611
612         @Override
613         public int lastIndexOf(Object obj) {
614             if(!(obj instanceof InternalStatement))
615                 return -1;
616             InternalStatement statement = (InternalStatement)obj;
617             int s = statement.s;
618             int p = statement.p;
619             int o = statement.o;
620             for(int i=sizeInternal()-3;i>=0;i-=3)
621                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
622                     return i/3;
623             return -1;
624         }
625
626         @Override
627         public ListIterator<Statement> listIterator() {
628             return new IteratorImpl(0);
629         }
630
631         @Override
632         public ListIterator<Statement> listIterator(int index) {
633             return new IteratorImpl(index*3);
634         }
635
636         @Override
637         public List<Statement> subList(int fromIndex, int toIndex) {
638             if(fromIndex < 0 || toIndex*3 >= sizeInternal() || fromIndex > toIndex)
639                 throw new IndexOutOfBoundsException();
640             return new RandomAccessSubList<Statement>(this, fromIndex, toIndex-fromIndex);
641         }
642         }
643         
644         @Override
645         final public Collection<Statement> getStatements(final Resource subject,
646                         final Resource relation)
647                         throws ManyObjectsForFunctionalRelationException, ServiceException {
648
649                 assert (subject != null);
650                 assert (relation != null);
651
652                 try {
653
654                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
655                         processor.forEachStatement(this, subject, relation, procedure);
656                         procedure.checkAndThrow();
657                         return procedure;
658                         
659                 } catch (DatabaseException e) {
660
661                         System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation);
662
663                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
664                         processor.forEachStatement(this, subject, relation, procedure);
665                         
666                         return Collections.emptyList();
667                 
668 //                      throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e);
669
670                 }
671
672         }
673
674         @Override
675         final public Collection<Statement> getAssertedStatements(final Resource subject, final Resource relation)
676                         throws ManyObjectsForFunctionalRelationException, ServiceException {
677
678                 assert (subject != null);
679                 assert (relation != null);
680
681                 try {
682
683                         return syncRequest(new ForEachAssertedStatement(subject, relation));
684
685                 } catch (ManyObjectsForFunctionalRelationException e) {
686
687                         throw new ManyObjectsForFunctionalRelationException(e);
688
689                 } catch (ServiceException e) {
690
691                         throw new ServiceException(e);
692
693                 } catch (DatabaseException e) {
694
695                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
696
697                 }
698
699         }
700
701         @Override
702         final public Collection<Resource> getPredicates(final Resource subject) throws ServiceException {
703
704                 assert (subject != null);
705
706                 try {
707
708                         return processor.getPredicates(this, subject);
709
710 //                      AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
711 //                      processor.forEachPredicate(this, subject, procedure);
712 //                      procedure.checkAndThrow();
713 //                      return procedure;
714
715                 } catch (ServiceException e) {
716
717                         throw new ServiceException(e);
718
719                 } catch (DatabaseException e) {
720
721                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
722
723                 }  catch (Throwable e) {
724
725             throw new ServiceException(e);
726
727                 }
728
729         }
730
731         @Override
732         final public Collection<Resource> getPrincipalTypes(final Resource subject)
733                         throws ServiceException {
734
735                 assert (subject != null);
736
737                 try {
738
739                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
740                         processor.forEachPrincipalType(this, subject, procedure);
741                         procedure.checkAndThrow();
742                         return procedure;
743                         
744                 } catch (ServiceException e) {
745
746                         throw new ServiceException(e);
747
748                 } catch (DatabaseException e) {
749
750                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
751
752                 }
753
754         }
755
756         @Override
757         final public Set<Resource> getTypes(final Resource subject) throws ServiceException {
758
759                 assert (subject != null);
760
761                 try {
762                         
763                         return processor.getTypes(this, subject);
764                         
765                 } catch (ServiceException e) {
766
767                         throw new ServiceException(e);
768                         
769                 } catch (DatabaseException e) {
770
771                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
772
773         } catch (Throwable e) {
774
775             throw new ServiceException(e);
776
777                 }
778
779         }
780
781         @Override
782         final public Set<Resource> getSupertypes(final Resource subject)
783                         throws ServiceException {
784
785                 assert (subject != null);
786
787                 try {
788
789                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
790                         processor.forSupertypes(this, subject, procedure);
791                         procedure.checkAndThrow();
792                         return procedure.result;
793
794                 } catch (ServiceException e) {
795
796                         throw new ServiceException(e);
797
798                 } catch (DatabaseException e) {
799
800                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
801
802                 }
803
804         }
805
806         @Override
807         final public Set<Resource> getSuperrelations(final Resource subject)
808                         throws ServiceException {
809
810                 assert (subject != null);
811
812                 try {
813
814                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
815                         processor.forSuperrelations(this, subject, procedure);
816                         procedure.checkAndThrow();
817                         return procedure.result;
818
819                 } catch (ServiceException e) {
820
821                         throw new ServiceException(e);
822
823                 } catch (DatabaseException e) {
824
825                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
826
827                 }
828
829         }
830         
831         @Override
832         public Resource getPossibleSuperrelation(Resource subject) throws ServiceException {
833                 
834                 try {
835
836                         SyncReadProcedure<Resource> procedure = new SyncReadProcedure<Resource>();
837                         processor.forPossibleSuperrelation(this, subject, procedure);
838                         procedure.checkAndThrow();
839                         return procedure.result;
840
841                 } catch (ServiceException e) {
842
843                         throw new ServiceException(e);
844
845                 } catch (DatabaseException e) {
846
847                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
848
849                 }
850
851         }
852
853         @Override
854         final public Collection<Resource> getObjects(final Resource subject, final Resource relation)
855                         throws ServiceException {
856
857                 assert (subject != null);
858                 assert (relation != null);
859
860                 if(Development.DEVELOPMENT) {
861             if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) {
862                 counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1);
863             }
864             //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace();
865                 }
866                 
867                 try {
868
869                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
870                         processor.forEachObject(this, subject, relation, procedure);
871                         procedure.checkAndThrow();
872                         return procedure;
873                         
874                 } catch (DatabaseException e) {
875
876                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
877
878                 }
879
880         }
881
882         @Override
883         final public Collection<Resource> getAssertedObjects(
884                         final Resource subject, final Resource relation)
885                         throws ManyObjectsForFunctionalRelationException, ServiceException {
886
887         if (subject == null)
888             throw new ArgumentException("Subject must not be null.");
889         if (relation == null)
890             throw new ArgumentException("Relation must not be null. Subject=" + subject);
891
892                 try {
893
894                         return syncRequest(new ForEachAssertedObject(subject, relation));
895
896                 } catch (ManyObjectsForFunctionalRelationException e) {
897
898                         throw new ManyObjectsForFunctionalRelationException(e);
899
900                 } catch (ServiceException e) {
901
902                         throw new ServiceException(e);
903
904                 } catch (DatabaseException e) {
905
906                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
907
908                 }
909
910         }
911
912         @Override
913         final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException {
914
915                 assert (relation != null);
916
917                 try {
918
919                         return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
920
921                 } catch (NoSingleResultException e) {
922
923                         throw new NoInverseException(e);
924
925                 } catch (ServiceException e) {
926
927                         throw new ServiceException(e);
928
929                 }
930
931         }
932
933         @Override
934         final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException {
935
936                 if( subject == null) throw new IllegalArgumentException("subject can not be null");
937                 if( relation == null) throw new IllegalArgumentException("relation can not be null");
938
939                 try {
940                         int single = processor.getSingleObject(this, subject, relation);
941                         if (single == 0) {
942                                 if (EMPTY_RESOURCE_CHECK) {
943                                         if (!hasStatement(subject)) {
944                                                 throw new EmptyResourceException("Resource " + debugString(subject));
945                                         }
946                                 }
947                                 throw new NoSingleResultException("No single object for subject " + debugString(subject)
948                                                 + " and relation " + debugString(relation), single);
949                         }
950                         return processor.querySupport.getResource(single);
951                 } catch (NoSingleResultException e) {
952                         throw e;
953                 } catch (DatabaseException e) {
954                         throw new ServiceException(e);
955                 } 
956         }
957
958         @Override
959         final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
960                 assert (subject != null);
961                 assert (relation != null);
962                 try {
963                         Collection<Statement> statements = getStatements(subject, relation);
964                         if (statements.size() == 1) {
965                                 return statements.iterator().next();
966                         } else {
967                                 if (EMPTY_RESOURCE_CHECK)
968                                         if (!hasStatement(subject))
969                                                 throw new EmptyResourceException("Resource " + debugString(subject));
970                                 throw new NoSingleResultException("No single statement for subject " + debugString(subject)
971                                                 + " and relation " + debugString(relation), statements.size());
972                         }
973                 } catch (ServiceException e) {
974                         throw new ServiceException(e);
975                 } 
976         }
977
978         @Override
979         final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
980                 assert (subject != null);
981                 try {
982                         ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
983                         if (principalTypes.size() == 1) {
984                             return principalTypes.get(0);
985                         } else {
986                             throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
987                         }
988                 } catch (ServiceException e) {
989                         throw new ServiceException(e);
990                 } 
991         }
992
993         @Override
994         final public Resource getSingleType(final Resource subject,
995                         final Resource baseType) throws NoSingleResultException,
996                         ServiceException {
997
998                 assert (subject != null);
999                 assert (baseType != null);
1000
1001                 try {
1002                         return syncRequest(new SingleType(subject, baseType));
1003                 } catch (DatabaseException e) {
1004                     throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
1005                 }
1006         }
1007
1008         @Override
1009         final public <T> T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1010
1011                 assert (subject != null);
1012
1013                 try {
1014
1015                         Layer0 L0 = processor.getL0(this);
1016             int object = processor.getSingleObject(this, subject, L0.HasDataType);
1017             if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1018             
1019             if(processor.isImmutable(object)) {
1020                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1021                         return getValue(subject, binding);
1022             } else {
1023                     byte[] dt = processor.getValue(this, object);
1024                     if(dt == null) throw new ServiceException("No data type for " + subject);
1025                     Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1026                     Binding binding = Bindings.getBinding(datatype);
1027                     return getValue(subject, binding);
1028             }
1029                         
1030         } catch (IOException e) {
1031
1032             throw new ServiceException(e);
1033
1034                 } catch (DoesNotContainValueException e) {
1035
1036                         throw new DoesNotContainValueException(e, subject);
1037
1038                 } catch (ServiceException e) {
1039
1040                         throw new ServiceException(e);
1041
1042                 } catch (DatabaseException e) {
1043
1044                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1045
1046         }
1047
1048         }
1049
1050     @Override
1051     final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1052
1053         assert (subject != null);
1054
1055         try {
1056
1057             Layer0 L0 = processor.getL0(this);
1058             int object = processor.getSingleObject(this, subject, L0.HasDataType);
1059             if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1060             
1061             if(processor.isImmutable(object)) {
1062                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1063                 return new Variant(binding, getValue(subject, binding));
1064             } else {
1065                 byte[] dt = processor.getValue(this, object);
1066                 if(dt == null) throw new ServiceException("No data type for " + subject);
1067                 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1068                 Binding binding = Bindings.getBinding(datatype);
1069                 return new Variant(binding, getValue(subject, binding));
1070             }
1071             
1072         } catch (IOException e) {
1073
1074             throw new ServiceException(e);
1075
1076         } catch (DoesNotContainValueException e) {
1077
1078             throw new DoesNotContainValueException(e, subject);
1079
1080         } catch (ServiceException e) {
1081
1082             throw new ServiceException(e);
1083
1084         } catch (DatabaseException e) {
1085
1086             throw new ServiceException(INTERNAL_ERROR_STRING, e);
1087
1088         }               
1089         }
1090
1091         static final IdentityHashMap<Binding,Serializer> serializers = new IdentityHashMap<Binding,Serializer>();
1092         
1093         static {
1094                 serializers.put(Bindings.STRING, Bindings.STRING.serializer());
1095         }
1096         
1097         final protected Serializer getSerializer(Binding binding) {
1098             return binding.serializer();
1099         }
1100         
1101         @Override
1102         final public <T> T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException,
1103                         ServiceException {
1104
1105                 assert (subject != null);
1106
1107                 try {
1108                         
1109                         byte[] bytes = processor.getValue(this, subject);
1110                         if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
1111
1112                         Serializer serializer = getSerializer(binding);
1113                         return (T)serializer.deserialize(bytes);
1114
1115                 } catch (DoesNotContainValueException e) {
1116
1117                         throw new DoesNotContainValueException(e);
1118
1119                 } catch (IOException e) {
1120
1121                         throw new ServiceException(e);
1122
1123                 } catch (DatabaseException e) {
1124                     
1125             throw new ServiceException(e);
1126             
1127         } catch (BufferUnderflowException e) {
1128             // This is sometimes thrown when deserialize fails because wrong format.
1129             // For callers of this method this is just an service exception.
1130             throw new ServiceException(e);
1131         }
1132
1133         }
1134
1135         @Override
1136         final public <T> T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1137                         DoesNotContainValueException, ServiceException {
1138
1139                 assert (subject != null);
1140                 assert (relation != null);
1141
1142                 try {
1143                         Resource object = getSingleObject(subject, relation);
1144                         return getValue(object);
1145                 } catch (NoSingleResultException e) {
1146                         throw new NoSingleResultException("No single value found for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1147                 } catch (DoesNotContainValueException e) {
1148                         try {
1149                                 Layer0 L0 = processor.getL0(this);
1150                                 Resource object = getPossibleObject(subject, relation);
1151                                 if(isInstanceOf(object, L0.Value)) {
1152                                         if(isInstanceOf(object, L0.Literal)) {
1153                                                 throw new DoesNotContainValueException(e);
1154                                         } else {
1155                                                 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1156                                         }
1157                                 } else {
1158                                         throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1159                                 }
1160                         } catch (DoesNotContainValueException e2) {
1161                                 throw e2;
1162                         } catch (DatabaseException e2) {
1163                                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1164                         }
1165                 } catch (ServiceException e) {
1166                         throw new ServiceException(e);
1167                 }
1168         }
1169
1170     @Override
1171     final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1172             DoesNotContainValueException, ServiceException {
1173
1174         assert (subject != null);
1175         assert (relation != null);
1176
1177         try {
1178             Resource object = getSingleObject(subject, relation);
1179             return getVariantValue(object);
1180         } catch (NoSingleResultException e) {
1181             throw new NoSingleResultException("No single object for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1182         } catch (DoesNotContainValueException e) {
1183             try {
1184                 Layer0 L0 = processor.getL0(this);
1185                 Resource object = getPossibleObject(subject, relation);
1186                 if(isInstanceOf(object, L0.Value)) {
1187                     if(isInstanceOf(object, L0.Literal)) {
1188                         throw new DoesNotContainValueException(e);
1189                     } else {
1190                         throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1191                     }
1192                 } else {
1193                     throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1194                 }
1195             } catch (DoesNotContainValueException e2) {
1196                 throw e2;
1197             } catch (DatabaseException e2) {
1198                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1199             }
1200         } catch (ServiceException e) {
1201             throw new ServiceException(e);
1202         } 
1203     }
1204     
1205         @Override
1206         final public <T> T getRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1207                         throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException {
1208
1209                 assert (subject != null);
1210                 assert (relation != null);
1211
1212                 try {
1213                         Resource object = getSingleObject(subject, relation);
1214                         return getValue(object, binding);
1215                 } catch (NoSingleResultException e) {
1216                     String message = "";
1217                     try {
1218                     String subjectName = NameUtils.getSafeName(this, subject, true);
1219                     String relationName = NameUtils.getSafeName(this, relation, true);
1220                     message = "Subject: " + subjectName + ", Relation: " + relationName;
1221                     } catch (DatabaseException e2) {
1222                         
1223                     }
1224             throw new NoSingleResultException(message, e.getResultCount(), e);
1225                 } catch (DoesNotContainValueException e) {
1226                         throw new DoesNotContainValueException(e);
1227                 } catch (ServiceException e) {
1228                         throw new ServiceException(e);
1229                 }
1230         }
1231
1232         @Override
1233         final public <T> T adapt(final Resource resource, final Class<T> clazz)
1234                         throws AdaptionException, ValidationException, ServiceException {
1235
1236                 assert (resource != null);
1237                 assert (clazz != null);
1238
1239                 try {
1240
1241                         return syncRequest(new Adapter<T>(resource, clazz));
1242
1243                 } catch (AdaptionException e) {
1244
1245                         throw new AdaptionException(e);
1246
1247                 } catch (ValidationException e) {
1248
1249                         throw new ValidationException(e);
1250
1251                 } catch (ServiceException e) {
1252
1253                         throw new ServiceException(e);
1254
1255                 } catch (DatabaseException e) {
1256
1257                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1258
1259                 }
1260
1261         }
1262
1263         @Override
1264         final public <T,C> T adaptContextual(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1265                         throws AdaptionException, ValidationException, ServiceException {
1266
1267                 assert (resource != null);
1268                 assert (context != null);
1269
1270                 class ContextualAdapter implements AsyncRead<T> {
1271
1272                         final private Resource resource;
1273                         final private C context;
1274                     final private Class<T> clazz;
1275                     
1276                     @Override
1277                     public int hashCode() {
1278                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1279                     }
1280                     
1281                     @Override
1282                     final public int threadHash() {
1283                         return resource.getThreadHash();
1284                     }
1285                     
1286                     @Override
1287                     public boolean equals(Object object) {
1288                         if (this == object)
1289                             return true;
1290                         else if (object == null)
1291                             return false;
1292                         else if (getClass() != object.getClass())
1293                             return false;
1294                         ContextualAdapter r = (ContextualAdapter)object;
1295                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1296                     }
1297
1298                     @Override
1299                     public int getFlags() {
1300                         return 0;
1301                     }
1302                     
1303                     public ContextualAdapter(Resource resource, C context, Class<T> clazz) {
1304                         this.resource = resource;
1305                         this.context = context;
1306                         this.clazz = clazz;
1307                     }
1308
1309                     @Override
1310                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1311                         
1312                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1313                                 if (service == null)
1314                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1315                                 else
1316                                         service.adapt(graph, resource, context, contextClass, clazz, false, procedure); 
1317                         
1318                     }
1319
1320                     @Override
1321                     public String toString() {
1322                         return "Adapter for (" + resource + "," + context + ") as " + clazz.getName();
1323                     }
1324                     
1325                 }
1326                 
1327                 try {
1328
1329                         return syncRequest(new ContextualAdapter(resource, context, clazz));
1330
1331                 } catch (AdaptionException e) {
1332
1333                         throw new AdaptionException(e);
1334
1335                 } catch (ValidationException e) {
1336
1337                         throw new ValidationException(e);
1338
1339                 } catch (ServiceException e) {
1340
1341                         throw new ServiceException(e);
1342
1343                 } catch (DatabaseException e) {
1344
1345                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1346
1347                 }
1348
1349         }
1350         
1351         @Override
1352         final public <T> T adaptRelated(final Resource resource, final Resource relation, final Class<T> clazz)
1353                         throws AdaptionException, NoSingleResultException, ValidationException, ServiceException {
1354
1355                 assert (resource != null);
1356                 assert (clazz != null);
1357
1358                 Statement stm = getSingleStatement(resource, relation);
1359                 
1360                 return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz);
1361                 
1362         }
1363
1364         @Override
1365         final public <T> T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class<T> clazz)
1366                         throws ValidationException, ServiceException {
1367
1368                 try {
1369                         return adaptRelated(resource, relation, clazz);
1370                 } catch (DatabaseException e) {
1371                         return null;
1372                 }
1373                 
1374         }
1375
1376         @Override
1377         final public <T,C> T getPossibleContextualAdapter(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1378                         throws ValidationException, ServiceException {
1379
1380                 assert (resource != null);
1381                 assert (context != null);
1382
1383                 class PossibleContextualAdapter implements AsyncRead<T> {
1384
1385                         final private Resource resource;
1386                         final private C context;
1387                     final private Class<T> clazz;
1388                     
1389                     @Override
1390                     public int hashCode() {
1391                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1392                     }
1393                     
1394                     @Override
1395                     final public int threadHash() {
1396                         return resource.getThreadHash();
1397                     }
1398                     
1399                     @Override
1400                     public boolean equals(Object object) {
1401                         if (this == object)
1402                             return true;
1403                         else if (object == null)
1404                             return false;
1405                         else if (getClass() != object.getClass())
1406                             return false;
1407                         PossibleContextualAdapter r = (PossibleContextualAdapter)object;
1408                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1409                     }
1410
1411                     @Override
1412                     public int getFlags() {
1413                         return 0;
1414                     }
1415                     
1416                     public PossibleContextualAdapter(Resource resource, C context, Class<T> clazz) {
1417                         this.resource = resource;
1418                         this.context = context;
1419                         this.clazz = clazz;
1420                     }
1421
1422                     @Override
1423                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1424                         
1425                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1426                                 if (service == null)
1427                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1428                                 else
1429                                         service.adapt(graph, resource, context, contextClass, clazz, true, procedure); 
1430                         
1431                     }
1432
1433                     @Override
1434                     public String toString() {
1435                         return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName();
1436                     }
1437                     
1438                 }
1439                 
1440                 try {
1441
1442                         return syncRequest(new PossibleContextualAdapter(resource, context, clazz));
1443
1444                 } catch (ValidationException e) {
1445
1446                         throw new ValidationException(e);
1447
1448                 } catch (ServiceException e) {
1449
1450                         throw new ServiceException(e);
1451
1452                 } catch (DatabaseException e) {
1453
1454                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1455
1456                 }
1457                 
1458         }
1459
1460         @Override
1461         final public <T> T adaptUnique(final Resource resource, final Class<T> clazz)
1462                         throws AdaptionException, ValidationException, ServiceException {
1463
1464                 assert (resource != null);
1465                 assert (clazz != null);
1466
1467                 try {
1468
1469                         return syncRequest(new UniqueAdapter<T>(resource, clazz));
1470
1471                 } catch (AdaptionException e) {
1472
1473                         throw new AdaptionException(e);
1474
1475                 } catch (ValidationException e) {
1476
1477                         throw new ValidationException(e);
1478
1479                 } catch (ServiceException e) {
1480
1481                         throw new ServiceException(e);
1482
1483                 } catch (DatabaseException e) {
1484
1485                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1486
1487                 }
1488
1489         }
1490
1491         @Override
1492         final public Resource getPossibleInverse(final Resource relation)
1493                         throws ServiceException {
1494
1495                 assert (relation != null);
1496
1497                 try {
1498
1499                         return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
1500
1501                 } catch (ServiceException e) {
1502
1503                         throw new ServiceException(e);
1504
1505                 } catch (DatabaseException e) {
1506
1507                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1508
1509                 }
1510
1511         }
1512
1513         @Override
1514         public Resource getPossibleObject(final Resource subject, final Resource relation)
1515                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1516
1517                 assert (subject != null);
1518                 assert (relation != null);
1519
1520                 try {
1521
1522                     int result = processor.getSingleObject(this, subject, relation);
1523                     if(result == 0) return null;
1524                     
1525                     return processor.querySupport.getResource(result);
1526
1527              } catch (ManyObjectsForFunctionalRelationException e) {
1528
1529                  throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
1530                  
1531                 } catch (DatabaseException e) {
1532
1533                         throw new ServiceException(e);
1534
1535                 }
1536                 
1537         }
1538
1539         @Override
1540         final public Statement getPossibleStatement(final Resource subject, final Resource relation)
1541                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1542
1543                 assert (subject != null);
1544                 assert (relation != null);
1545
1546                 try {
1547
1548                         Collection<Statement> statements = getStatements(subject, relation);
1549                         if(statements.size() == 1) return statements.iterator().next();
1550                         else return null;
1551
1552                 } catch (ManyObjectsForFunctionalRelationException e) {
1553
1554                         throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
1555
1556                 } catch (ServiceException e) {
1557
1558                         throw new ServiceException(e);
1559
1560                 } 
1561
1562         }
1563
1564         @Override
1565         final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException {
1566
1567                 assert (subject != null);
1568                 assert (baseType != null);
1569
1570                 try {
1571
1572                         AsyncReadProcedure<Resource> procedure = new AsyncReadProcedure<Resource>();
1573                         forPossibleType(subject, baseType, procedure);
1574                         procedure.checkAndThrow();
1575                         return procedure.result;                        
1576
1577                 } catch (ServiceException e) {
1578
1579                         throw new ServiceException(e);
1580
1581                 } catch (DatabaseException e) {
1582
1583                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1584
1585                 }
1586
1587         }
1588
1589         @Override
1590         final public <T> T getPossibleValue(final Resource subject) throws ServiceException {
1591
1592                 assert (subject != null);
1593
1594                 try {
1595                     
1596                     int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType);
1597                     if(object == 0) return null;
1598                     
1599             if(processor.isImmutable(object)) {
1600                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1601                         return getPossibleValue(subject, binding);
1602             } else {
1603                     byte[] dt = processor.getValue(this, object);
1604                     if(dt == null) return null;
1605                     Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1606                     Binding binding = Bindings.getBinding(datatype);
1607                     return getPossibleValue(subject, binding);
1608             }
1609                     
1610         } catch (IOException e) {
1611             
1612             throw new ServiceException(e);
1613             
1614                 } catch (ServiceException e) {
1615
1616                         throw new ServiceException(e);
1617
1618                 } catch (DatabaseException e) {
1619
1620                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1621
1622         }
1623
1624         }
1625
1626         @Override
1627         final public <T> T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException {
1628
1629                 assert (subject != null);
1630                 assert (binding != null);
1631
1632                 try {
1633
1634             byte[] dt = processor.getValue(this, subject);
1635             if(dt == null) return null;
1636                         Serializer serializer = getSerializer(binding);
1637             return (T)serializer.deserialize(dt);
1638
1639         } catch (IOException e) {
1640
1641             throw new ServiceException(e);
1642             
1643                 } catch (BindingException e) {
1644
1645                         throw new BindingException(e);
1646
1647                 } catch (ServiceException e) {
1648
1649                         throw new ServiceException(e);
1650
1651                 } catch (DatabaseException e) {
1652                         e.printStackTrace();
1653                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1654         }
1655
1656         }
1657
1658         @Override
1659         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation)
1660                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1661
1662                 assert (subject != null);
1663                 assert (relation != null);
1664
1665                 try {
1666
1667                         Resource object = getPossibleObject(subject, relation);
1668                         if(object == null) return null;
1669                         else return getPossibleValue(object);
1670
1671                 } catch (ManyObjectsForFunctionalRelationException e) {
1672
1673                         throw new ManyObjectsForFunctionalRelationException(e);
1674
1675                 } catch (ServiceException e) {
1676
1677                         throw new ServiceException(e);
1678
1679                 } 
1680
1681         }
1682
1683         @Override
1684         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1685                         throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
1686
1687                 assert (subject != null);
1688                 assert (relation != null);
1689                 assert (binding != null);
1690
1691                 try {
1692
1693                         Resource object = getPossibleObject(subject, relation);
1694                         if(object == null) return null;
1695                         else return getPossibleValue(object, binding);
1696
1697                 } catch (ManyObjectsForFunctionalRelationException e) {
1698
1699                         throw new ManyObjectsForFunctionalRelationException(e);
1700
1701                 } catch (BindingException e) {
1702
1703                         throw new BindingException(e);
1704
1705                 } catch (ServiceException e) {
1706
1707                         throw new ServiceException(e);
1708
1709                 }
1710
1711         }
1712
1713         @Override
1714         public <T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1715
1716                 assert (resource != null);
1717                 assert (clazz != null);
1718
1719                 try {
1720
1721                         return syncRequest(new PossibleAdapter<T>(resource, clazz));
1722
1723                 } catch (ValidationException e) {
1724
1725                         throw new ValidationException(e);
1726
1727                 } catch (AdaptionException e) {
1728
1729                         return null;
1730
1731                 } catch (DatabaseException e) {
1732
1733                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1734
1735                 }
1736         }
1737
1738         @Override
1739         public <T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1740
1741                 assert (resource != null);
1742                 assert (clazz != null);
1743
1744                 try {
1745
1746                         return syncRequest(new PossibleUniqueAdapter<T>(resource, clazz));
1747
1748                 } catch (AdaptionException e) {
1749
1750                         return null;
1751
1752                 } catch (ValidationException e) {
1753
1754                         throw new ValidationException(e);
1755
1756                 } catch (DatabaseException e) {
1757
1758                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1759
1760                 }
1761
1762         }
1763
1764     @Override
1765     final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException {
1766
1767         assert (resource != null);
1768         assert (type != null);
1769
1770         Set<Resource> resources = getTypes(resource);
1771         // This check was necessary because some of the callers of this method got stuck when the NPE was thrown from here.
1772         if (null == resources)
1773             return false;
1774         
1775         if(EMPTY_RESOURCE_CHECK) {
1776             if (resources.isEmpty()) {
1777                 if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource));
1778             }
1779         }
1780         
1781         return resources.contains(type);
1782
1783     }
1784
1785         @Override
1786         final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException {
1787
1788                 assert (resource != null);
1789                 assert (type != null);
1790
1791                 try {
1792
1793                         if(resource.equals(type)) return true;
1794                         
1795                         return getSupertypes(resource).contains(type);
1796
1797                 } catch (ServiceException e) {
1798
1799                         throw new ServiceException(e);
1800
1801                 } 
1802                 
1803         }
1804
1805         @Override
1806         final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException {
1807
1808                 assert (resource != null);
1809                 assert (type != null);
1810
1811                 try {
1812
1813                         if(resource.equals(type)) return true;
1814                         
1815                         return getSuperrelations(resource).contains(type);
1816
1817                 } catch (ServiceException e) {
1818
1819                         throw new ServiceException(e);
1820
1821                 } 
1822
1823         }
1824
1825         @Override
1826         final public boolean hasStatement(final Resource subject) throws ServiceException {
1827
1828                 assert (subject != null);
1829
1830                 try {
1831
1832                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1833                         processor.forHasStatement(this, subject, procedure);
1834                         procedure.checkAndThrow();
1835                         return procedure.result;
1836
1837                 } catch (ServiceException e) {
1838
1839                         throw new ServiceException(e);
1840
1841                 } catch (DatabaseException e) {
1842
1843                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1844
1845                 }
1846
1847         }
1848
1849         @Override
1850         final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException {
1851
1852                 assert (subject != null);
1853                 assert (relation != null);
1854
1855                 try {
1856
1857                         Collection<Resource> objects = getObjects(subject, relation);
1858                         return !objects.isEmpty();
1859
1860                 } catch (ServiceException e) {
1861
1862                         throw new ServiceException(e);
1863
1864                 } 
1865                 
1866         }
1867
1868         @Override
1869         final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1870
1871                 assert (subject != null);
1872                 assert (relation != null);
1873                 assert (object != null);
1874
1875                 try {
1876
1877                         for(Resource o : getObjects(subject, relation)) {
1878                                 if(object.equals(o)) return true;
1879                         }
1880                         
1881                         return false;
1882
1883                 } catch (ServiceException e) {
1884
1885                         throw new ServiceException(e);
1886
1887                 }
1888
1889         }
1890
1891         @Override
1892         final public boolean hasValue(final Resource subject) throws ServiceException {
1893
1894                 assert (subject != null);
1895
1896                 try {
1897
1898                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1899                         processor.forHasValue(this, subject, procedure);
1900                         procedure.checkAndThrow();
1901                         return procedure.result;
1902
1903                 } catch (ServiceException e) {
1904
1905                         throw new ServiceException(e);
1906
1907                 } catch (DatabaseException e) {
1908
1909                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1910
1911                 }
1912
1913         }
1914
1915         final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1916
1917                 @Override
1918                 public void execute(AsyncReadGraph graph, Object result) {
1919                 }
1920
1921                 @Override
1922                 public void exception(AsyncReadGraph graph, Throwable throwable) {
1923                 }
1924                 
1925         };
1926         
1927         /*
1928          * Implementation of the interface RequestProcessor
1929          */
1930
1931         @Override
1932         public <T> T syncRequest(final Read<T> request) throws DatabaseException {
1933
1934                 assert (request != null);
1935
1936                 return QueryCache.resultReadEntry(this, request, parent, null, null);
1937
1938         }
1939
1940         @Override
1941         public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1942                         throws DatabaseException {
1943                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1944         }
1945
1946         @Override
1947         public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1948                         throws DatabaseException {
1949                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1950         }
1951
1952         @Override
1953         public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1954
1955                 assert (request != null);
1956
1957                 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1958
1959                 return QueryCache.resultReadEntry(this, request, parent, listener, procedure);
1960
1961         }
1962
1963         @Override
1964         public <T> T syncRequest(final Read<T> request,
1965                         final SyncProcedure<T> procedure) throws DatabaseException {
1966                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
1967         }
1968
1969         @Override
1970         public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
1971                         throws DatabaseException {
1972                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
1973         }
1974
1975         static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
1976
1977                 private static Throwable DONE = new Throwable();
1978                 
1979                 T result = null;
1980                 Throwable exception = null;
1981                 
1982                 @Override
1983                 public void execute(AsyncReadGraph graph, T t) {
1984                         result = t;
1985                         exception = DONE;
1986                 }
1987
1988                 @Override
1989                 public void exception(AsyncReadGraph graph, Throwable t) {
1990                         exception = t;
1991                 }
1992                 
1993                 public void checkAndThrow() throws DatabaseException {
1994                         if(exception != DONE) {
1995                                 if (exception instanceof DatabaseException)
1996                                         throw (DatabaseException) exception;
1997                                 else
1998                                         throw new DatabaseException(
1999                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
2000                                                         exception);
2001                         }
2002                 }
2003                 
2004                 public boolean done() {
2005                         return exception != null;
2006                 }
2007                 
2008         }
2009         
2010         @Override
2011         public <T> T syncRequest(final AsyncRead<T> request)
2012                         throws DatabaseException {
2013
2014                 assert (request != null);
2015                 asyncBarrier = new AsyncBarrierImpl(null);
2016                 BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, null, request);
2017                 syncRequest(request, ap);
2018                 return ap.get();
2019
2020         }
2021
2022         @Override
2023         public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2024                         throws DatabaseException {
2025                 return syncRequest(request, (AsyncProcedure<T>) procedure);
2026         }
2027
2028         @Override
2029         public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2030                         throws DatabaseException {
2031                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2032         }
2033
2034         @Override
2035         public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2036                         throws DatabaseException {
2037                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2038         }
2039
2040         @Override
2041         final public <T> T syncRequest(final AsyncRead<T> request,
2042                         final AsyncProcedure<T> procedure) throws DatabaseException {
2043
2044                 assert (request != null);
2045
2046                 ListenerBase listener = getListenerBase(procedure);
2047
2048                 BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2049
2050                 QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
2051
2052                 return ap.get();
2053
2054         }
2055
2056         final private <T> void syncRequest(final AsyncRead<T> request, final AsyncReadProcedure<T> procedure) throws DatabaseException {
2057
2058                 assert (request != null);
2059
2060                 ListenerBase listener = getListenerBase(procedure);
2061                 assert(listener == null);
2062
2063                 BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2064
2065                 QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
2066
2067                 ap.get();
2068
2069         }
2070
2071         @Override
2072         public <T> T syncRequest(AsyncRead<T> request,
2073                         final SyncProcedure<T> procedure) throws DatabaseException {
2074                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2075         }
2076
2077         @Override
2078         final public <T> T syncRequest(final AsyncRead<T> request,
2079                         final Procedure<T> procedure) throws DatabaseException {
2080                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2081         }
2082
2083         @Override
2084         public <T> Collection<T> syncRequest(final MultiRead<T> request)
2085                         throws DatabaseException {
2086
2087                 assert (request != null);
2088
2089                 final ArrayList<T> result = new ArrayList<T>();
2090                 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2091
2092                 syncRequest(request, new SyncMultiProcedure<T>() {
2093
2094                         @Override
2095                         public void execute(ReadGraph graph, T t) {
2096                                 synchronized (result) {
2097                                         result.add(t);
2098                                 }
2099                         }
2100
2101                         @Override
2102                         public void finished(ReadGraph graph) {
2103                         }
2104
2105                         @Override
2106                         public void exception(ReadGraph graph, Throwable t) {
2107                                 exception.set(t);
2108                         }
2109
2110                         @Override
2111                         public String toString() {
2112                                 return "syncRequest(MultiRead) -> " + request;
2113                         }
2114
2115                 });
2116
2117                 Throwable t = exception.get();
2118                 if (t != null) {
2119                         if (t instanceof DatabaseException)
2120                                 throw (DatabaseException) t;
2121                         else
2122                                 throw new DatabaseException(
2123                                                 "Unexpected exception in ReadGraph.syncRequest(Read)",
2124                                                 t);
2125                 }
2126
2127                 return result;
2128
2129         }
2130
2131         @Override
2132         public <T> Collection<T> syncRequest(MultiRead<T> request,
2133                         SyncMultiListener<T> procedure) {
2134                 return syncRequest(request, (SyncMultiProcedure<T>)procedure);
2135         }
2136
2137         @Override
2138         public <T> Collection<T> syncRequest(MultiRead<T> request,
2139                         MultiListener<T> procedure) {
2140                 return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
2141         }
2142
2143         @Override
2144         public <T> Collection<T> syncRequest(MultiRead<T> request,
2145                         SyncMultiProcedure<T> procedure) {
2146
2147                 assert (request != null);
2148
2149                 ListenerBase listener = getListenerBase(procedure);
2150
2151                 final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
2152
2153                 if (parent != null || listener != null) {
2154
2155 //                      Object syncParent = request;
2156
2157 //                      final ReadGraphImpl newGraph = newSync();
2158
2159                         processor.query(this, request, parent, wrapper, listener);
2160
2161 //                      newGraph.waitAsync(syncParent);
2162
2163                 } else {
2164
2165 //                      Object syncParent = request;
2166
2167 //                      final ReadGraphImpl newGraph = newSync();
2168
2169                         try {
2170                                 request.perform(this, wrapper);
2171                         } catch (Throwable t) {
2172                                 wrapper.exception(this, t);
2173                         }
2174
2175                 }
2176
2177                 return wrapper.get();
2178
2179         }
2180
2181         @Override
2182         public <T> Collection<T> syncRequest(MultiRead<T> request,
2183                         MultiProcedure<T> procedure) {
2184                 return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
2185         }
2186
2187         static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2188
2189                 private static Throwable DONE = new Throwable();
2190                 
2191                 private static final long serialVersionUID = -6494230465108115812L;
2192                 
2193                 Throwable exception = null;
2194                 
2195                 @Override
2196                 public synchronized void execute(AsyncReadGraph graph, T t) {
2197                         add(t);
2198                 }
2199
2200                 @Override
2201                 public void finished(AsyncReadGraph graph) {
2202                         exception = DONE;
2203                 }
2204
2205                 @Override
2206                 public void exception(AsyncReadGraph graph, Throwable t) {
2207                         exception = t;
2208                 }
2209                 
2210                 public void checkAndThrow() throws DatabaseException {
2211                         if(exception != DONE) {
2212                                 if (exception instanceof DatabaseException)
2213                                         throw (DatabaseException) exception;
2214                                 else
2215                                         throw new DatabaseException(
2216                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2217                                                         exception);
2218                         }
2219                 }
2220                 
2221                 public boolean done() {
2222                         return exception != null;
2223                 }
2224                 
2225         }
2226
2227         @Override
2228         final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2229                         throws DatabaseException {
2230
2231                 assert (request != null);
2232
2233                 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2234                 
2235                 syncRequest(request, procedure);
2236                 
2237                 procedure.checkAndThrow();
2238                 return procedure;
2239
2240         }
2241
2242         @Override
2243         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2244                         AsyncMultiListener<T> procedure) {
2245                 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2246         }
2247
2248         @Override
2249         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2250                         SyncMultiListener<T> procedure) {
2251                 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2252         }
2253
2254         @Override
2255         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2256                         MultiListener<T> procedure) {
2257                 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2258         }
2259
2260         final private <T> void syncRequest(final AsyncMultiRead<T> request,
2261                         final AsyncMultiReadProcedure<T> procedure) {
2262
2263                 assert (request != null);
2264                 assert (procedure != null);
2265
2266                 ListenerBase listener = getListenerBase(procedure);
2267
2268                 if (parent != null || listener != null) {
2269
2270 //                      Object syncParent = request;
2271
2272 //                      final ReadGraphImpl newGraph = newSync();
2273
2274                         processor.query(this, request, parent, procedure, listener);
2275
2276 //                      newGraph.waitAsync(syncParent);
2277                         waitAsyncProcedure(procedure);
2278
2279                 } else {
2280
2281 //                      Object syncParent = callerThread == Integer.MIN_VALUE ? null
2282 //                                      : request;
2283 //
2284 //                      final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2285
2286                         try {
2287
2288 //                              inc();
2289 //                              ReadGraphImpl sync = newSync();
2290                                 request.perform(this, procedure);
2291 //                              sync.waitAsync(null);
2292                                 waitAsyncProcedure(procedure);
2293 //                              dec();
2294
2295                         } catch (Throwable t) {
2296
2297                                 waitAsyncProcedure(procedure);
2298 //                              dec();
2299
2300                         }
2301
2302                 }
2303
2304         }
2305         
2306         
2307         @Override
2308         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2309                         final AsyncMultiProcedure<T> procedure) {
2310
2311                 assert (request != null);
2312                 assert (procedure != null);
2313
2314                 ListenerBase listener = getListenerBase(procedure);
2315
2316                 if (parent != null || listener != null) {
2317
2318 //                      Object syncParent = request;
2319
2320 //                      final ReadGraphImpl newGraph = newSync();
2321
2322                         processor.query(this, request, parent, procedure, listener);
2323
2324 //                      newGraph.waitAsync(syncParent);
2325
2326                 } else {
2327
2328 //                      Object syncParent = request;
2329
2330 //                      final ReadGraphImpl newGraph = newSync();
2331
2332                         try {
2333
2334                                 request.perform(this, new AsyncMultiProcedure<T>() {
2335
2336                                         @Override
2337                                         public void execute(AsyncReadGraph graph, T result) {
2338                                                 procedure.execute(graph, result);
2339                                         }
2340
2341                                         @Override
2342                                         public void finished(AsyncReadGraph graph) {
2343                                                 procedure.finished(graph);
2344                                         }
2345
2346                                         @Override
2347                                         public void exception(AsyncReadGraph graph, Throwable t) {
2348                                                 procedure.exception(graph, t);
2349                                         }
2350
2351                                         @Override
2352                                         public String toString() {
2353                                                 return "syncRequest(AsyncMultiRead) -> " + procedure;
2354                                         }
2355
2356                                 });
2357
2358                         } catch (Throwable t) {
2359
2360                         }
2361
2362                 }
2363
2364                 // TODO!!
2365                 return null;
2366
2367         }
2368
2369         @Override
2370         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2371                         final SyncMultiProcedure<T> procedure) {
2372                 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2373         }
2374
2375         @Override
2376         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2377                         final MultiProcedure<T> procedure) {
2378                 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2379         }
2380
2381         @Override
2382         public <T> T syncRequest(final ExternalRead<T> request)
2383                         throws DatabaseException {
2384
2385                 assert (request != null);
2386
2387                 return syncRequest(request, new Procedure<T>() {
2388
2389                         @Override
2390                         public void execute(T t) {
2391                         }
2392
2393                         @Override
2394                         public void exception(Throwable t) {
2395                         }
2396
2397                         @Override
2398                         public String toString() {
2399                                 return "syncRequest(AsyncRead) -> " + request;
2400                         }
2401
2402                 });
2403
2404         }
2405
2406         @Override
2407         public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2408                 return syncRequest(request, (Procedure<T>) procedure);
2409         }
2410
2411         @Override
2412         final public <T> T syncRequest(final ExternalRead<T> request,
2413                         final Procedure<T> procedure) throws DatabaseException {
2414
2415         assert (request != null);
2416
2417         ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
2418         return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
2419
2420         }
2421
2422         @Override
2423         public void syncRequest(final Write 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 WriteResult<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 void syncRequest(final DelayedWrite request)
2444                         throws DatabaseException {
2445
2446                 assert (request != null);
2447
2448                 throw new DatabaseException(
2449                                 "Write operations are not supported during read transactions!");
2450
2451         }
2452
2453         @Override
2454         public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {
2455
2456                 assert (request != null);
2457
2458                 throw new DatabaseException(
2459                                 "Write operations are not supported during read transactions!");
2460
2461         }
2462         
2463         @Override
2464         public void syncRequest(final WriteOnly request) throws DatabaseException {
2465
2466                 assert (request != null);
2467
2468                 throw new DatabaseException(
2469                                 "Write operations are not supported during read transactions!");
2470
2471         }
2472
2473         @Override
2474         public <T> T syncRequest(final WriteOnlyResult<T> request) throws DatabaseException {
2475
2476                 assert (request != null);
2477
2478                 throw new DatabaseException(
2479                                 "Write operations are not supported during read transactions!");
2480
2481         }
2482         
2483         @Override
2484         public <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure) {
2485                 r.request(this, procedure);
2486         }
2487         
2488         @Override
2489         public <T> void async(ReadInterface<T> r, Procedure<T> procedure) {
2490                 r.request(this, procedure);
2491         }
2492         
2493         @Override
2494         public <T> void async(ReadInterface<T> r, SyncProcedure<T> procedure) {
2495                 r.request(this, procedure);
2496         }
2497         
2498         @Override
2499         public <T> void async(ReadInterface<T> r, AsyncListener<T> procedure) {
2500                 r.request(this, procedure);
2501         }
2502         
2503         @Override
2504         public <T> void async(ReadInterface<T> r, Listener<T> procedure) {
2505                 r.request(this, procedure);
2506         }
2507         
2508         @Override
2509         public <T> void async(ReadInterface<T> r, SyncListener<T> procedure) {
2510                 r.request(this, procedure);
2511         }
2512
2513         @Override
2514         public <T> T sync(ReadInterface<T> r) throws DatabaseException {
2515                 return r.request(this);
2516         }
2517         
2518         @Override
2519         public <T> T sync(WriteInterface<T> r) throws DatabaseException {
2520                 return r.request(this);
2521         }
2522         
2523         @Override
2524         public <T> void async(WriteInterface<T> r, Procedure<T> procedure) {
2525                 r.request(this, procedure);
2526         }
2527
2528         @Override
2529         public <T> void async(WriteInterface<T> r) {
2530                 r.request(this, new ProcedureAdapter<T>());
2531         }
2532
2533         /*
2534          * Implementation of the interface AsyncReadGraph
2535          */
2536
2537         @Override
2538         public void forURI(Resource resource, AsyncListener<String> listener) {
2539                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2540                                 listener);
2541         }
2542
2543         @Override
2544         public void forURI(Resource resource, SyncListener<String> listener) {
2545                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2546                                 listener);
2547         }
2548
2549         @Override
2550         public void forURI(Resource resource, Listener<String> listener) {
2551                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2552                                 listener);
2553         }
2554
2555         @Override
2556         final public void forURI(final Resource resource,
2557                         final AsyncProcedure<String> procedure) {
2558
2559                 assert (resource != null);
2560                 assert (procedure != null);
2561
2562                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2563                                 procedure);
2564
2565         }
2566
2567         @Override
2568         public void forURI(Resource resource, SyncProcedure<String> procedure) {
2569                 forURI(resource, new SyncToAsyncProcedure<String>(procedure));
2570         }
2571
2572         @Override
2573         public void forURI(Resource resource, Procedure<String> procedure) {
2574                 forURI(resource, new NoneToAsyncProcedure<String>(procedure));
2575         }
2576         
2577         @Override
2578         public void forResource(String id, AsyncListener<Resource> listener) {
2579                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2580                                 listener);
2581         }
2582
2583         @Override
2584         public void forResource(String id, SyncListener<Resource> listener) {
2585                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2586                                 listener);
2587         }
2588
2589         @Override
2590         public void forResource(String id, Listener<Resource> listener) {
2591                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2592                                 listener);
2593         }
2594
2595         @Override
2596         final public void forResource(final String id,
2597                         final AsyncProcedure<Resource> procedure) {
2598
2599                 assert (id != null);
2600                 assert (procedure != null);
2601
2602                 processor.forResource(this, id, procedure);
2603
2604         }
2605
2606         @Override
2607         public void forResource(String id, SyncProcedure<Resource> procedure) {
2608                 forResource(id, new SyncToAsyncProcedure<Resource>(procedure));
2609         }
2610
2611         @Override
2612         public void forResource(String id, Procedure<Resource> procedure) {
2613                 forResource(id, new NoneToAsyncProcedure<Resource>(procedure));
2614         }
2615
2616         @Override
2617         public void forBuiltin(String id, AsyncListener<Resource> listener) {
2618                 asyncRequest(new Builtin(id), listener);
2619         }
2620
2621         @Override
2622         public void forBuiltin(String id, SyncListener<Resource> listener) {
2623                 asyncRequest(new Builtin(id), listener);
2624         }
2625
2626         @Override
2627         public void forBuiltin(String id, Listener<Resource> listener) {
2628                 asyncRequest(new Builtin(id), listener);
2629         }
2630
2631         @Override
2632         final public void forBuiltin(final String id,
2633                         final AsyncProcedure<Resource> procedure) {
2634
2635                 assert (id != null);
2636                 assert (procedure != null);
2637
2638                 processor.forBuiltin(this, id, procedure);
2639
2640         }
2641
2642         @Override
2643         public void forBuiltin(String id, SyncProcedure<Resource> procedure) {
2644                 forBuiltin(id, new SyncToAsyncProcedure<Resource>(procedure));
2645         }
2646
2647         @Override
2648         public void forBuiltin(String id, Procedure<Resource> procedure) {
2649                 forBuiltin(id, new NoneToAsyncProcedure<Resource>(procedure));
2650         }
2651
2652         @Override
2653         final public void forEachStatement(Resource subject, Resource relation,
2654                         AsyncMultiProcedure<Statement> procedure) {
2655
2656                 assert (subject != null);
2657                 assert (relation != null);
2658                 assert (procedure != null);
2659
2660                 processor.forEachStatement(this, subject, relation, procedure);
2661
2662         }
2663
2664         @Override
2665         public void forEachStatement(Resource subject, Resource relation,
2666                         SyncMultiProcedure<Statement> procedure) {
2667                 forEachStatement(subject, relation,
2668                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2669         }
2670
2671         @Override
2672         final public void forEachStatement(Resource subject, Resource relation,
2673                         MultiProcedure<Statement> procedure) {
2674
2675                 assert (subject != null);
2676                 assert (relation != null);
2677                 assert (procedure != null);
2678
2679                 processor.forEachStatement(this, subject, relation, procedure);
2680
2681         }