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