1 /*******************************************************************************
2 * Copyright (c) 2007, 2018 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.services.adaption;
14 import org.simantics.db.AsyncReadGraph;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.adaption.Adapter;
18 import org.simantics.db.adaption.AdaptionService;
19 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
20 import org.simantics.db.common.request.BinaryRead;
21 import org.simantics.db.common.request.ReadRequest;
22 import org.simantics.db.common.request.TernaryRead;
23 import org.simantics.db.common.uri.ResourceToURI;
24 import org.simantics.db.common.utils.NameUtils;
25 import org.simantics.db.exception.AdaptionException;
26 import org.simantics.db.exception.DatabaseException;
27 import org.simantics.db.exception.ServiceException;
28 import org.simantics.db.exception.ValidationException;
29 import org.simantics.db.procedure.AsyncProcedure;
30 import org.simantics.db.request.AsyncRead;
31 import org.simantics.db.request.Read;
32 import org.simantics.layer0.Layer0;
33 import org.simantics.utils.datastructures.Pair;
35 import gnu.trove.map.hash.THashMap;
36 import gnu.trove.procedure.TObjectObjectProcedure;
37 import gnu.trove.set.hash.THashSet;
39 public class AdaptionService2 implements AdaptionService {
41 THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>> adapters =
42 new THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>>();
45 * Contains all adapter declarations and definitions for one class (clazz).
47 static class AdapterDeclaration<T> {
49 THashMap<Resource, Adapter<T,?>> typeAdapters =
50 new THashMap<Resource, Adapter<T,?>>();
51 THashMap<Resource, Adapter<T,?>> instanceAdapters =
52 new THashMap<Resource, Adapter<T,?>>();
53 THashSet<Resource> baseTypes = new THashSet<Resource>();
55 String getDescription(final ReadGraph g) {
56 final StringBuilder b = new StringBuilder();
57 b.append("The following adapters have been defined for ");
58 b.append(clazz.getCanonicalName());
60 typeAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
63 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
66 b.append(g.syncRequest(new ResourceToURI(arg0)));
67 } catch (DatabaseException e) {
79 instanceAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
82 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
83 b.append(" resource ");
85 b.append(g.syncRequest(new ResourceToURI(arg0)));
86 } catch (DatabaseException e) {
100 public AdapterDeclaration(Class<T> clazz) {
104 static class AdapterResult<T,C> {
105 Adapter<T,C> adapter;
108 public AdapterResult(Adapter<T,C> adapter, Resource type) {
109 this.adapter = adapter;
115 * The query returns the adapter inherited by the parameter type.
116 * The query is used only in the case, the type itself does not have
117 * an adapter. The second component of the result contains the type
118 * that originally contributed the adapter.
120 static class GetInheritedAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, AdapterResult<T,C>> {
122 public GetInheritedAdapter(Resource type, AdapterDeclaration<T> decl) {
126 AdapterDeclaration<T> getDeclaration() {
131 public String toString() {
132 return "GetInheritedAdapter|" + parameter + "|" + parameter2;
135 @SuppressWarnings("unchecked")
137 public AdapterResult<T,C> perform(ReadGraph g) throws DatabaseException {
138 Layer0 b = Layer0.getInstance(g);
139 AdapterResult<T,C> result = null;
140 for(Resource supertype : g.getObjects(parameter, b.Inherits)) {
141 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(supertype);
142 if(adapter != null) {
144 result = new AdapterResult<T,C>(adapter, supertype);
145 else if(!result.type.equals(supertype) &&
146 !g.isInheritedFrom(result.type, supertype)) {
147 if(g.isInheritedFrom(supertype, result.type))
148 result = new AdapterResult<T,C>(adapter, supertype);
149 else throw new AdaptionException("Type " +
150 safeName(g, parameter) + " inherits conflicting adapters from "
151 + safeName(g, supertype) + " and " + safeName(g, result.type));
155 AdapterResult<T,C> temp =
156 g.syncRequest(new GetInheritedAdapter<T, C>(supertype, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
160 else if(!result.type.equals(temp.type) &&
161 !g.isInheritedFrom(result.type, temp.type)) {
162 if(g.isInheritedFrom(temp.type, result.type))
164 else throw new AdaptionException("Type " +
165 safeName(g, parameter) + " inherits conflicting adapters from "
166 + safeName(g, temp.type) + " and " + safeName(g, result.type));
176 <C> void inheritedAdapter(AsyncReadGraph graph, Resource type, AsyncProcedure<AdapterResult<T,C>> procedure) {
177 graph.asyncRequest(new GetInheritedAdapter<T, C>(type, this), procedure);
180 Adapter<T,?> directAdapter(Resource r) {
182 synchronized (this) {
183 ret = instanceAdapters.get(r);
188 static class FindAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, Adapter<T,C>> {
190 public FindAdapter(Resource resource, AdapterDeclaration<T> decl) {
191 super(resource, decl);
194 @SuppressWarnings("unchecked")
195 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
198 Adapter<T,C> adapter;
199 synchronized (this) {
200 adapter = (Adapter<T,C>)parameter2.instanceAdapters.get(r);
206 Layer0 b = Layer0.getInstance(g);
209 * Try to find adapter from immediate types
211 AdapterResult<T,C> adapterResult = null;
212 for(Resource t : g.getObjects(r, b.InstanceOf)) {
213 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(t);
214 if(adapter != null) {
215 if(adapterResult == null)
216 adapterResult = new AdapterResult<T,C>(adapter, t);
217 else if(!adapterResult.type.equals(t) &&
218 !g.isInheritedFrom(adapterResult.type, t)) {
219 if(g.isInheritedFrom(t, adapterResult.type))
220 adapterResult = new AdapterResult<T,C>(adapter, t);
221 else throw new AdaptionException("Resource " +
222 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
223 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
228 AdapterResult<T,C> temp =
229 g.syncRequest(new GetInheritedAdapter<T, C>(t, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
231 if(adapterResult == null)
232 adapterResult = temp;
233 else if(!adapterResult.type.equals(temp.type) &&
234 !g.isInheritedFrom(adapterResult.type, temp.type)) {
235 if(g.isInheritedFrom(temp.type, adapterResult.type))
236 adapterResult = temp;
237 else throw new AdaptionException("Resource " +
238 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
239 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
246 if(adapterResult != null)
247 return adapterResult.adapter;
249 for(Resource t : g.getObjects(r, b.Inherits)) {
250 Adapter<T,C> adapter = findAdapter(t, g);
255 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
256 Adapter<T,C> adapter = findAdapter(t, g);
267 public Adapter<T,C> perform(ReadGraph g) throws DatabaseException {
268 return (Adapter<T, C>)findAdapter(parameter, g);
274 * The query returns either an adapter or adapted for the given
275 * resource. It is assumed that the resource itself does not
278 class Adapt<C> implements Read<T> {
283 public Adapt(Resource resource, C context) {
284 this.resource = resource;
285 this.context = context;
288 AdapterDeclaration<T> getDeclaration() {
289 return AdapterDeclaration.this;
292 @SuppressWarnings("unchecked")
293 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
296 Adapter<T,C> adapter;
297 synchronized (this) {
298 adapter = (Adapter<T,C>)instanceAdapters.get(r);
304 Layer0 b = Layer0.getInstance(g);
307 * Try to find adapter from immediate types
309 AdapterResult<T,C> adapterResult = null;
310 for(Resource t : g.getObjects(r, b.InstanceOf)) {
311 Adapter<T,C> adapter = (Adapter<T,C>)typeAdapters.get(t);
312 if(adapter != null) {
313 if(adapterResult == null)
314 adapterResult = new AdapterResult<T,C>(adapter, t);
315 else if(!adapterResult.type.equals(t) &&
316 !g.isInheritedFrom(adapterResult.type, t)) {
317 if(g.isInheritedFrom(t, adapterResult.type))
318 adapterResult = new AdapterResult<T,C>(adapter, t);
319 else throw new AdaptionException("Resource " +
320 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
321 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
326 AdapterResult<T,C> temp =
327 g.syncRequest(new GetInheritedAdapter<T, C>(t, AdapterDeclaration.this));
329 if(adapterResult == null)
330 adapterResult = temp;
331 else if(!adapterResult.type.equals(temp.type) &&
332 !g.isInheritedFrom(adapterResult.type, temp.type)) {
333 if(g.isInheritedFrom(temp.type, adapterResult.type))
334 adapterResult = temp;
335 else throw new AdaptionException("Resource " +
336 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
337 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
344 if(adapterResult != null)
345 return adapterResult.adapter;
347 for(Resource t : g.getObjects(r, b.Inherits)) {
348 Adapter<T,C> adapter = findAdapter(t, g);
353 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
354 Adapter<T,C> adapter = findAdapter(t, g);
364 public T perform(ReadGraph g) throws DatabaseException {
366 final Adapter<T,C> adapter = (Adapter<T, C>)findAdapter(resource, g);
367 if(adapter == null) return null;
368 else return g.syncRequest((AsyncRead<T>)(graph, procedure) -> {
369 //System.out.println("adapter=" + adapter);
370 adapter.adapt(graph, resource, context, procedure);
375 @SuppressWarnings("rawtypes")
377 public boolean equals(Object other) {
381 else if (other == null)
383 else if (other.getClass() != Adapt.class)
386 return ((Adapt)other).resource.equals(resource)
387 && ((Adapt)other).context.equals(context)
388 && ((Adapt)other).getDeclaration()==getDeclaration();
393 public int hashCode() {
394 return resource.hashCode() + 31*((getClass().hashCode() + 41*(context.hashCode()) +
395 71*getDeclaration().hashCode()));
400 // void adapt2(AsyncReadGraph graph, Resource r, AsyncProcedure<T> procedure) {
401 // graph.asyncRequest(new Adapt(r), procedure);
404 <C> Adapter<T,C> findAdapter(ReadGraph g, Resource r, boolean possible) throws DatabaseException {
406 Adapter<T,C> result = g.syncRequest(new FindAdapter<T,C>(r, AdapterDeclaration.this));
407 if(result != null) return result;
413 * We couldn't adapt the resource. We analyze the situation little for
414 * better error message.
416 for(Resource dt : baseTypes) {
417 if(g.isInstanceOf(r, dt)) {
418 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
419 safeName(g, r) + " although it is instance of " +
420 safeName(g, dt) + "\n" +
424 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
426 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
431 <C> T adapt(ReadGraph g, Resource r, C context, boolean possible) throws DatabaseException {
433 T result = g.syncRequest(new Adapt<C>(r,context));
434 if(result != null) return result;
440 * We couldn't adapt the resource. We analyze the situation little for
441 * better error message.
443 for(Resource dt : baseTypes) {
444 if(g.isInstanceOf(r, dt)) {
445 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
446 safeName(g, r) + " although it is instance of " +
447 safeName(g, dt) + "\n" +
451 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
453 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
458 T adaptNew(ReadGraph g, final Resource r, boolean possible) throws DatabaseException {
460 T result = new Adapt<Resource>(r,r).perform(g);
467 for(Resource dt : baseTypes) {
468 if(g.isInstanceOf(r, dt)) {
469 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
470 safeName(g, r) + " although it is instance of " +
471 safeName(g, dt) + "\n" +
475 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
477 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
484 private <T> AdapterDeclaration<T> getDeclaration(Class<T> targetClass, Class<?> contextClass) {
485 Pair<Class<?>,Class<?>> key = new Pair<Class<?>,Class<?>>(targetClass, contextClass);
486 @SuppressWarnings("unchecked")
487 AdapterDeclaration<T> decl =
488 (AdapterDeclaration<T>)adapters.get(key);
490 decl = new AdapterDeclaration<T>(targetClass);
491 adapters.put(key, decl);
496 public <T,C> void getAdapter(AsyncReadGraph graph, final Resource r, final Class<C> contextClass, final Class<T> targetClass, final boolean possible, final AsyncProcedure<Adapter<T,C>> procedure) {
498 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
499 @SuppressWarnings("unchecked")
500 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
504 procedure.execute(graph, null);
506 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + targetClass + "."));
511 @SuppressWarnings("unchecked")
512 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
513 if(adapter != null) {
514 procedure.execute(graph, adapter);
516 graph.forPossibleObject(r, graph.getService(Layer0.class).InstanceOf, new AsyncProcedure<Resource>() {
519 public void exception(AsyncReadGraph graph, Throwable throwable) {
520 procedure.exception(graph, new AdaptionException("Problems in reading types for resource. ", throwable));
524 public void execute(AsyncReadGraph graph, final Resource singleType) {
525 if(singleType != null) {
526 getSingleTypeAdapter(graph, decl, key, r, singleType, possible, procedure);
528 getSingleSuperTypeAdapter(graph, decl, key, r, r, possible, procedure);
540 public <T,C> void adapt(AsyncReadGraph graph, final Resource r, final C context, Class<C> contextClass, Class<T> targetClass, final boolean possible, final AsyncProcedure<T> procedure) {
542 getAdapter(graph, r, contextClass, targetClass, possible, new AsyncProcedure<Adapter<T,C>>() {
545 public void execute(AsyncReadGraph graph, Adapter<T, C> result) {
548 procedure.execute(graph, null);
550 procedure.exception(graph, new AdaptionException("Internal error. getAdapter returned null and possible was false."));
553 result.adapt(graph, r, context, procedure);
558 public void exception(AsyncReadGraph graph, Throwable throwable) {
559 procedure.exception(graph, throwable);
567 public <T, C> T adapt(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
569 Adapter<T,C> adapter = getAdapter(g, r, context, contextClass, targetClass, possible);
570 if(adapter == null) return null;
572 return g.syncRequest((AsyncRead<T>)(graph, procedure) -> adapter.adapt(graph, r, context, procedure));
576 private <T, C> Adapter<T,C> getAdapter(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
578 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
579 @SuppressWarnings("unchecked")
580 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
583 if(possible) return null;
584 else throw new AdaptionException("There are no adapters declared or defined for class " + targetClass + ".");
588 @SuppressWarnings("unchecked")
589 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
590 if(adapter != null) return adapter;
592 Layer0 L0 = Layer0.getInstance(g);
593 Resource singleType = g.getPossibleObject(r, L0.InstanceOf);
594 if(singleType != null) {
595 return getSingleTypeAdapter(g, decl, key, r, singleType, possible);
597 return getSingleSuperTypeAdapter(g, decl, key, r, r, possible);
604 private static class SingleTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
606 final private AdapterDeclaration<T> decl;
608 SingleTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource instance, Boolean possible) {
609 super(key, instance, possible);
614 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
615 return decl.findAdapter(graph, parameter2, parameter3);
620 private <T,C> void getSingleTypeAdapter(AsyncReadGraph graph, final AdapterDeclaration<T> decl, final Pair<Class<T>, Class<?>> key, final Resource instance, final Resource type, final boolean possible, final AsyncProcedure<Adapter<T,C>> procedure) {
622 @SuppressWarnings("unchecked")
623 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
624 if(adapter != null) {
625 procedure.execute(graph, adapter);
627 graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
630 public void exception(AsyncReadGraph graph, Throwable throwable) {
631 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
635 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
637 if(singleSuperType != null) {
638 getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible, procedure);
640 graph.asyncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), procedure);
652 private <T,C> Adapter<T,C> getSingleTypeAdapter(ReadGraph graph, final AdapterDeclaration<T> decl, final Pair<Class<T>, Class<?>> key, final Resource instance, final Resource type, final boolean possible) throws DatabaseException {
654 @SuppressWarnings("unchecked")
655 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
656 if(adapter != null) return adapter;
658 Layer0 L0 = Layer0.getInstance(graph);
659 Resource singleSuperType = graph.getPossibleObject(type, L0.Inherits);
660 if(singleSuperType != null) {
661 return getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible);
663 return graph.syncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), TransientCacheAsyncListener.<Adapter<T,C>>instance());
668 // private <T,C> void adaptSingleType(AsyncReadGraph graph, final AdapterDeclaration<T> decl, final C context, final Resource instance, final Resource type, final boolean possible, final AsyncProcedure<T> procedure) {
670 // @SuppressWarnings("unchecked")
671 // Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
672 // if(adapter != null) {
674 // adapter.adapt(graph, instance, context, procedure);
678 // graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
681 // public void exception(AsyncReadGraph graph, Throwable throwable) {
683 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
688 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
690 // if(singleSuperType != null) {
692 // adaptSingleType(graph, decl, context, instance, singleSuperType, possible, procedure);
696 // graph.asyncRequest(new Read<T>() {
699 // public T perform(ReadGraph graph)
700 // throws DatabaseException {
701 // return decl.adapt(graph, instance, context, possible);
718 private static class SingleSuperTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
720 final private AdapterDeclaration<T> decl;
722 SingleSuperTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource type, Boolean possible) {
723 super(key, type, possible);
728 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
729 return decl.findAdapter(graph, parameter2, parameter3);
734 private <T,C> void getSingleSuperTypeAdapter(AsyncReadGraph graph, final AdapterDeclaration<T> decl, final Pair<Class<T>, Class<?>> key, final Resource type, final Resource superType, final boolean possible, final AsyncProcedure<Adapter<T,C>> procedure) {
736 @SuppressWarnings("unchecked")
737 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
738 if(adapter != null) {
739 procedure.execute(graph, adapter);
742 graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
745 public void exception(AsyncReadGraph graph, Throwable throwable) {
746 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
750 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
752 if(singleSuperType != null) {
754 getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible, procedure);
758 graph.asyncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible), procedure);
770 private <T,C> Adapter<T,C> getSingleSuperTypeAdapter(ReadGraph graph, final AdapterDeclaration<T> decl, final Pair<Class<T>, Class<?>> key, final Resource type, final Resource superType, final boolean possible) throws DatabaseException {
772 @SuppressWarnings("unchecked")
773 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
774 if(adapter != null) return adapter;
776 Layer0 L0 = Layer0.getInstance(graph);
777 Resource singleSuperType = graph.getPossibleObject(superType, L0.Inherits);
778 if(singleSuperType != null) {
779 return getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible);
781 return graph.syncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible));
786 // private <T,C> void adaptSingleSupertype(AsyncReadGraph graph, final AdapterDeclaration<T> decl, final C context, final Resource type, final Resource superType, final boolean possible, final AsyncProcedure<T> procedure) {
788 // @SuppressWarnings("unchecked")
789 // Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
790 // if(adapter != null) {
792 // adapter.adapt(graph, type, context, procedure);
796 // graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
799 // public void exception(AsyncReadGraph graph, Throwable throwable) {
801 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
806 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
808 // if(singleSuperType != null) {
810 // adaptSingleSupertype(graph, decl, context, type, singleSuperType, possible, procedure);
814 // graph.asyncRequest(new Read<T>() {
817 // public T perform(ReadGraph graph)
818 // throws DatabaseException {
819 // return decl.adapt(graph, type, context, possible);
835 public <T> void adaptNew(AsyncReadGraph g, final Resource r, final Class<T> clazz, final boolean possible, final AsyncProcedure<T> procedure) {
837 g.asyncRequest(new ReadRequest() {
840 public void run(ReadGraph graph) throws DatabaseException {
842 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(clazz, Resource.class);
844 @SuppressWarnings("unchecked")
845 AdapterDeclaration<T> decl =
846 (AdapterDeclaration<T>)adapters.get(key);
850 procedure.execute(g, null);
852 procedure.exception(g, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
856 procedure.execute(g, decl.adaptNew(graph, r, possible));
857 } catch (AdaptionException e) {
859 procedure.execute(g, null);
861 procedure.exception(g, e);
863 } catch (ValidationException e) {
864 procedure.exception(g, e);
865 } catch (DatabaseException e2) {
866 procedure.exception(g, new ServiceException(e2));
877 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
878 addInstanceAdapter(resource, targetClass, Resource.class, adapter);
882 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
883 synchronized (this) {
884 getDeclaration(targetClass, contextClass).instanceAdapters.put(resource, adapter);
889 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass) {
890 return removeInstanceAdapter(resource, targetClass, Resource.class);
894 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass) {
895 synchronized (this) {
896 return getDeclaration(targetClass, contextClass).instanceAdapters.remove(resource);
901 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
902 removeInstanceAdapter(resource, targetClass, Resource.class, adapter);
906 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
907 synchronized (this) {
908 AdapterDeclaration<T> decl = getDeclaration(targetClass, contextClass);
909 Adapter<T,?> existing = decl.instanceAdapters.get(resource);
910 if (existing == adapter) {
911 decl.instanceAdapters.remove(resource);
917 public <T> void addAdapter(Resource type, Class<T> targetClass, Adapter<T,?> adapter) {
918 addAdapter(type, targetClass, Resource.class, adapter);
922 public <T> void addAdapter(Resource type, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
923 getDeclaration(targetClass, contextClass).typeAdapters.put(type, adapter);
927 public <T> void declareAdapter(Resource type, Class<T> targetClass) {
928 declareAdapter(type, targetClass, Resource.class);
932 public <T> void declareAdapter(Resource type, Class<T> targetClass, Class<?> contextClass) {
933 getDeclaration(targetClass, contextClass).baseTypes.add(type);
936 public static String safeName(ReadGraph g, Resource r) throws DatabaseException {
937 // Builtins b = g.getBuiltins();
938 // for(Resource name : g.getObjects(r, b.HasName))
939 // return g.getValue(name);
940 // for(Resource t : g.getObjects(r, b.InstanceOf))
941 // for(Resource name : g.getObjects(t, b.HasName))
942 // return ": "+ g.getValue(name);
943 // for(Resource t : g.getObjects(r, b.Inherits))
944 // for(Resource name : g.getObjects(t, b.HasName))
945 // return "<T "+ g.getValue(name);
946 // for(Resource t : g.getObjects(r, b.SubrelationOf))
947 // for(Resource name : g.getObjects(t, b.HasName))
948 // return "<R "+ g.getValue(name);
950 // return "\"" + g.getValue(r) + "\"";
951 // return "" + r.getResourceId();
952 return NameUtils.getSafeName(g, r, true);