1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 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 gnu.trove.map.hash.THashMap;
15 import gnu.trove.procedure.TObjectObjectProcedure;
16 import gnu.trove.set.hash.THashSet;
18 import org.simantics.db.AsyncReadGraph;
19 import org.simantics.db.ReadGraph;
20 import org.simantics.db.Resource;
21 import org.simantics.db.adaption.Adapter;
22 import org.simantics.db.adaption.AdaptionService;
23 import org.simantics.db.common.procedure.BlockingAsyncProcedure;
24 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
25 import org.simantics.db.common.procedure.single.SyncReadProcedure;
26 import org.simantics.db.common.request.BinaryRead;
27 import org.simantics.db.common.request.ReadRequest;
28 import org.simantics.db.common.request.TernaryRead;
29 import org.simantics.db.common.uri.ResourceToURI;
30 import org.simantics.db.common.utils.NameUtils;
31 import org.simantics.db.exception.AdaptionException;
32 import org.simantics.db.exception.DatabaseException;
33 import org.simantics.db.exception.ServiceException;
34 import org.simantics.db.exception.ValidationException;
35 import org.simantics.db.procedure.AsyncProcedure;
36 import org.simantics.db.request.AsyncRead;
37 import org.simantics.db.request.Read;
38 import org.simantics.layer0.Layer0;
39 import org.simantics.utils.datastructures.Pair;
41 public class AdaptionService2 implements AdaptionService {
45 THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>> adapters =
46 new THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>>();
49 * Contains all adapter declarations and definitions for one class (clazz).
51 static class AdapterDeclaration<T> {
53 THashMap<Resource, Adapter<T,?>> typeAdapters =
54 new THashMap<Resource, Adapter<T,?>>();
55 THashMap<Resource, Adapter<T,?>> instanceAdapters =
56 new THashMap<Resource, Adapter<T,?>>();
57 THashSet<Resource> baseTypes = new THashSet<Resource>();
59 String getDescription(final ReadGraph g) {
60 final StringBuilder b = new StringBuilder();
61 b.append("The following adapters have been defined for ");
62 b.append(clazz.getCanonicalName());
64 typeAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
67 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
70 b.append(g.syncRequest(new ResourceToURI(arg0)));
71 } catch (DatabaseException e) {
83 instanceAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
86 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
87 b.append(" resource ");
89 b.append(g.syncRequest(new ResourceToURI(arg0)));
90 } catch (DatabaseException e) {
104 public AdapterDeclaration(Class<T> clazz) {
108 static class AdapterResult<T,C> {
109 Adapter<T,C> adapter;
112 public AdapterResult(Adapter<T,C> adapter, Resource type) {
113 this.adapter = adapter;
119 * The query returns the adapter inherited by the parameter type.
120 * The query is used only in the case, the type itself does not have
121 * an adapter. The second component of the result contains the type
122 * that originally contributed the adapter.
124 static class GetInheritedAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, AdapterResult<T,C>> {
126 public GetInheritedAdapter(Resource type, AdapterDeclaration<T> decl) {
130 AdapterDeclaration<T> getDeclaration() {
135 public String toString() {
136 return "GetInheritedAdapter|" + parameter + "|" + parameter2;
139 @SuppressWarnings("unchecked")
141 public AdapterResult<T,C> perform(ReadGraph g) throws DatabaseException {
142 Layer0 b = Layer0.getInstance(g);
143 AdapterResult<T,C> result = null;
144 for(Resource supertype : g.getObjects(parameter, b.Inherits)) {
145 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(supertype);
146 if(adapter != null) {
148 result = new AdapterResult<T,C>(adapter, supertype);
149 else if(!result.type.equals(supertype) &&
150 !g.isInheritedFrom(result.type, supertype)) {
151 if(g.isInheritedFrom(supertype, result.type))
152 result = new AdapterResult<T,C>(adapter, supertype);
153 else throw new AdaptionException("Type " +
154 safeName(g, parameter) + " inherits conflicting adapters from "
155 + safeName(g, supertype) + " and " + safeName(g, result.type));
159 AdapterResult<T,C> temp =
160 g.syncRequest(new GetInheritedAdapter<T, C>(supertype, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
164 else if(!result.type.equals(temp.type) &&
165 !g.isInheritedFrom(result.type, temp.type)) {
166 if(g.isInheritedFrom(temp.type, result.type))
168 else throw new AdaptionException("Type " +
169 safeName(g, parameter) + " inherits conflicting adapters from "
170 + safeName(g, temp.type) + " and " + safeName(g, result.type));
180 <C> void inheritedAdapter(AsyncReadGraph graph, Resource type, AsyncProcedure<AdapterResult<T,C>> procedure) {
181 graph.asyncRequest(new GetInheritedAdapter<T, C>(type, this), procedure);
184 Adapter<T,?> directAdapter(Resource r) {
186 synchronized (this) {
187 ret = instanceAdapters.get(r);
192 static class FindAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, Adapter<T,C>> {
194 public FindAdapter(Resource resource, AdapterDeclaration<T> decl) {
195 super(resource, decl);
198 @SuppressWarnings("unchecked")
199 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
202 Adapter<T,C> adapter;
203 synchronized (this) {
204 adapter = (Adapter<T,C>)parameter2.instanceAdapters.get(r);
210 Layer0 b = Layer0.getInstance(g);
213 * Try to find adapter from immediate types
215 AdapterResult<T,C> adapterResult = null;
216 for(Resource t : g.getObjects(r, b.InstanceOf)) {
217 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(t);
218 if(adapter != null) {
219 if(adapterResult == null)
220 adapterResult = new AdapterResult<T,C>(adapter, t);
221 else if(!adapterResult.type.equals(t) &&
222 !g.isInheritedFrom(adapterResult.type, t)) {
223 if(g.isInheritedFrom(t, adapterResult.type))
224 adapterResult = new AdapterResult<T,C>(adapter, t);
225 else throw new AdaptionException("Resource " +
226 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
227 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
232 AdapterResult<T,C> temp =
233 g.syncRequest(new GetInheritedAdapter<T, C>(t, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
235 if(adapterResult == null)
236 adapterResult = temp;
237 else if(!adapterResult.type.equals(temp.type) &&
238 !g.isInheritedFrom(adapterResult.type, temp.type)) {
239 if(g.isInheritedFrom(temp.type, adapterResult.type))
240 adapterResult = temp;
241 else throw new AdaptionException("Resource " +
242 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
243 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
250 if(adapterResult != null)
251 return adapterResult.adapter;
253 for(Resource t : g.getObjects(r, b.Inherits)) {
254 Adapter<T,C> adapter = findAdapter(t, g);
259 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
260 Adapter<T,C> adapter = findAdapter(t, g);
271 public Adapter<T,C> perform(ReadGraph g) throws DatabaseException {
272 return (Adapter<T, C>)findAdapter(parameter, g);
278 * The query returns either an adapter or adapted for the given
279 * resource. It is assumed that the resource itself does not
282 class Adapt<C> implements Read<T> {
287 public Adapt(Resource resource, C context) {
288 this.resource = resource;
289 this.context = context;
292 AdapterDeclaration<T> getDeclaration() {
293 return AdapterDeclaration.this;
296 @SuppressWarnings("unchecked")
297 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
300 Adapter<T,C> adapter;
301 synchronized (this) {
302 adapter = (Adapter<T,C>)instanceAdapters.get(r);
308 Layer0 b = Layer0.getInstance(g);
311 * Try to find adapter from immediate types
313 AdapterResult<T,C> adapterResult = null;
314 for(Resource t : g.getObjects(r, b.InstanceOf)) {
315 Adapter<T,C> adapter = (Adapter<T,C>)typeAdapters.get(t);
316 if(adapter != null) {
317 if(adapterResult == null)
318 adapterResult = new AdapterResult<T,C>(adapter, t);
319 else if(!adapterResult.type.equals(t) &&
320 !g.isInheritedFrom(adapterResult.type, t)) {
321 if(g.isInheritedFrom(t, adapterResult.type))
322 adapterResult = new AdapterResult<T,C>(adapter, t);
323 else throw new AdaptionException("Resource " +
324 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
325 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
330 AdapterResult<T,C> temp =
331 g.syncRequest(new GetInheritedAdapter<T, C>(t, AdapterDeclaration.this));
333 if(adapterResult == null)
334 adapterResult = temp;
335 else if(!adapterResult.type.equals(temp.type) &&
336 !g.isInheritedFrom(adapterResult.type, temp.type)) {
337 if(g.isInheritedFrom(temp.type, adapterResult.type))
338 adapterResult = temp;
339 else throw new AdaptionException("Resource " +
340 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
341 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
348 if(adapterResult != null)
349 return adapterResult.adapter;
351 for(Resource t : g.getObjects(r, b.Inherits)) {
352 Adapter<T,C> adapter = findAdapter(t, g);
357 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
358 Adapter<T,C> adapter = findAdapter(t, g);
368 public T perform(ReadGraph g) throws DatabaseException {
370 final Adapter<T,C> adapter = (Adapter<T, C>)findAdapter(resource, g);
371 if(adapter == null) return null;
372 else return g.syncRequest(new AsyncRead<T>() {
375 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
376 // System.out.println("adapter=" + adapter);
377 adapter.adapt(graph, resource, context, procedure);
381 public int threadHash() {
386 public int getFlags() {
394 @SuppressWarnings("rawtypes")
396 public boolean equals(Object other) {
400 else if (other == null)
402 else if (other.getClass() != Adapt.class)
405 return ((Adapt)other).resource.equals(resource)
406 && ((Adapt)other).context.equals(context)
407 && ((Adapt)other).getDeclaration()==getDeclaration();
412 public int hashCode() {
413 return resource.hashCode() + 31*((getClass().hashCode() + 41*(context.hashCode()) +
414 71*getDeclaration().hashCode()));
419 // void adapt2(AsyncReadGraph graph, Resource r, AsyncProcedure<T> procedure) {
420 // graph.asyncRequest(new Adapt(r), procedure);
423 <C> Adapter<T,C> findAdapter(ReadGraph g, Resource r, boolean possible) throws DatabaseException {
425 Adapter<T,C> result = g.syncRequest(new FindAdapter<T,C>(r, AdapterDeclaration.this));
426 if(result != null) return result;
432 * We couldn't adapt the resource. We analyze the situation little for
433 * better error message.
435 for(Resource dt : baseTypes) {
436 if(g.isInstanceOf(r, dt)) {
437 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
438 safeName(g, r) + " although it is instance of " +
439 safeName(g, dt) + "\n" +
443 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
445 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
450 <C> T adapt(ReadGraph g, Resource r, C context, boolean possible) throws DatabaseException {
452 T result = g.syncRequest(new Adapt<C>(r,context));
453 if(result != null) return result;
459 * We couldn't adapt the resource. We analyze the situation little for
460 * better error message.
462 for(Resource dt : baseTypes) {
463 if(g.isInstanceOf(r, dt)) {
464 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
465 safeName(g, r) + " although it is instance of " +
466 safeName(g, dt) + "\n" +
470 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
472 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
477 T adaptNew(ReadGraph g, final Resource r, boolean possible) throws DatabaseException {
479 T result = new Adapt<Resource>(r,r).perform(g);
486 for(Resource dt : baseTypes) {
487 if(g.isInstanceOf(r, dt)) {
488 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
489 safeName(g, r) + " although it is instance of " +
490 safeName(g, dt) + "\n" +
494 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
496 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
503 private <T> AdapterDeclaration<T> getDeclaration(Class<T> targetClass, Class<?> contextClass) {
504 Pair<Class<?>,Class<?>> key = new Pair<Class<?>,Class<?>>(targetClass, contextClass);
505 @SuppressWarnings("unchecked")
506 AdapterDeclaration<T> decl =
507 (AdapterDeclaration<T>)adapters.get(key);
509 decl = new AdapterDeclaration<T>(targetClass);
510 adapters.put(key, decl);
515 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) {
517 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
518 @SuppressWarnings("unchecked")
519 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
523 procedure.execute(graph, null);
525 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + targetClass + "."));
530 @SuppressWarnings("unchecked")
531 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
532 if(adapter != null) {
533 procedure.execute(graph, adapter);
535 graph.forPossibleObject(r, graph.getService(Layer0.class).InstanceOf, new AsyncProcedure<Resource>() {
538 public void exception(AsyncReadGraph graph, Throwable throwable) {
539 procedure.exception(graph, new AdaptionException("Problems in reading types for resource. ", throwable));
543 public void execute(AsyncReadGraph graph, final Resource singleType) {
544 if(singleType != null) {
545 getSingleTypeAdapter(graph, decl, key, r, singleType, possible, procedure);
547 getSingleSuperTypeAdapter(graph, decl, key, r, r, possible, procedure);
559 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) {
561 getAdapter(graph, r, contextClass, targetClass, possible, new AsyncProcedure<Adapter<T,C>>() {
564 public void execute(AsyncReadGraph graph, Adapter<T, C> result) {
567 procedure.execute(graph, null);
569 procedure.exception(graph, new AdaptionException("Internal error. getAdapter returned null and possible was false."));
572 result.adapt(graph, r, context, procedure);
577 public void exception(AsyncReadGraph graph, Throwable throwable) {
578 procedure.exception(graph, throwable);
586 public <T, C> T adapt(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
588 Adapter<T,C> adapter = getAdapter(g, r, context, contextClass, targetClass, possible);
589 if(adapter == null) return null;
591 BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<T>(g, null, adapter);
593 // SyncReadProcedure<T> procedure = new SyncReadProcedure<T>();
594 adapter.adapt(g, r, context, ap);
597 // procedure.checkAndThrow();
598 // return procedure.result;
602 private <T, C> Adapter<T,C> getAdapter(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
604 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
605 @SuppressWarnings("unchecked")
606 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
609 if(possible) return null;
610 else throw new AdaptionException("There are no adapters declared or defined for class " + targetClass + ".");
614 @SuppressWarnings("unchecked")
615 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
616 if(adapter != null) return adapter;
618 Layer0 L0 = Layer0.getInstance(g);
619 Resource singleType = g.getPossibleObject(r, L0.InstanceOf);
620 if(singleType != null) {
621 return getSingleTypeAdapter(g, decl, key, r, singleType, possible);
623 return getSingleSuperTypeAdapter(g, decl, key, r, r, possible);
630 private static class SingleTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
632 final private AdapterDeclaration<T> decl;
634 SingleTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource instance, Boolean possible) {
635 super(key, instance, possible);
640 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
641 return decl.findAdapter(graph, parameter2, parameter3);
646 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) {
648 @SuppressWarnings("unchecked")
649 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
650 if(adapter != null) {
651 procedure.execute(graph, adapter);
653 graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
656 public void exception(AsyncReadGraph graph, Throwable throwable) {
657 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
661 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
663 if(singleSuperType != null) {
664 getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible, procedure);
666 graph.asyncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), procedure);
678 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 {
680 @SuppressWarnings("unchecked")
681 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
682 if(adapter != null) return adapter;
684 Layer0 L0 = Layer0.getInstance(graph);
685 Resource singleSuperType = graph.getPossibleObject(type, L0.Inherits);
686 if(singleSuperType != null) {
687 return getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible);
689 return graph.syncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), TransientCacheAsyncListener.<Adapter<T,C>>instance());
694 // 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) {
696 // @SuppressWarnings("unchecked")
697 // Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
698 // if(adapter != null) {
700 // adapter.adapt(graph, instance, context, procedure);
704 // graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
707 // public void exception(AsyncReadGraph graph, Throwable throwable) {
709 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
714 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
716 // if(singleSuperType != null) {
718 // adaptSingleType(graph, decl, context, instance, singleSuperType, possible, procedure);
722 // graph.asyncRequest(new Read<T>() {
725 // public T perform(ReadGraph graph)
726 // throws DatabaseException {
727 // return decl.adapt(graph, instance, context, possible);
744 private static class SingleSuperTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
746 final private AdapterDeclaration<T> decl;
748 SingleSuperTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource type, Boolean possible) {
749 super(key, type, possible);
754 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
755 return decl.findAdapter(graph, parameter2, parameter3);
760 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) {
762 @SuppressWarnings("unchecked")
763 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
764 if(adapter != null) {
765 procedure.execute(graph, adapter);
768 graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
771 public void exception(AsyncReadGraph graph, Throwable throwable) {
772 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
776 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
778 if(singleSuperType != null) {
780 getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible, procedure);
784 graph.asyncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible), procedure);
796 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 {
798 @SuppressWarnings("unchecked")
799 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
800 if(adapter != null) return adapter;
802 Layer0 L0 = Layer0.getInstance(graph);
803 Resource singleSuperType = graph.getPossibleObject(superType, L0.Inherits);
804 if(singleSuperType != null) {
805 return getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible);
807 return graph.syncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible));
812 // 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) {
814 // @SuppressWarnings("unchecked")
815 // Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
816 // if(adapter != null) {
818 // adapter.adapt(graph, type, context, procedure);
822 // graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
825 // public void exception(AsyncReadGraph graph, Throwable throwable) {
827 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
832 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
834 // if(singleSuperType != null) {
836 // adaptSingleSupertype(graph, decl, context, type, singleSuperType, possible, procedure);
840 // graph.asyncRequest(new Read<T>() {
843 // public T perform(ReadGraph graph)
844 // throws DatabaseException {
845 // return decl.adapt(graph, type, context, possible);
861 public <T> void adaptNew(AsyncReadGraph g, final Resource r, final Class<T> clazz, final boolean possible, final AsyncProcedure<T> procedure) {
863 g.asyncRequest(new ReadRequest() {
866 public void run(ReadGraph graph) throws DatabaseException {
868 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(clazz, Resource.class);
870 @SuppressWarnings("unchecked")
871 AdapterDeclaration<T> decl =
872 (AdapterDeclaration<T>)adapters.get(key);
876 procedure.execute(graph, null);
878 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
882 procedure.execute(graph, decl.adaptNew(graph, r, possible));
883 } catch (AdaptionException e) {
885 procedure.execute(graph, null);
887 procedure.exception(graph, e);
889 } catch (ValidationException e) {
890 procedure.exception(graph, e);
891 } catch (DatabaseException e2) {
892 procedure.exception(graph, new ServiceException(e2));
903 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
904 addInstanceAdapter(resource, targetClass, Resource.class, adapter);
908 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
909 synchronized (this) {
910 getDeclaration(targetClass, contextClass).instanceAdapters.put(resource, adapter);
915 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass) {
916 return removeInstanceAdapter(resource, targetClass, Resource.class);
920 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass) {
921 synchronized (this) {
922 return getDeclaration(targetClass, contextClass).instanceAdapters.remove(resource);
927 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
928 removeInstanceAdapter(resource, targetClass, Resource.class, adapter);
932 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
933 synchronized (this) {
934 AdapterDeclaration<T> decl = getDeclaration(targetClass, contextClass);
935 Adapter<T,?> existing = decl.instanceAdapters.get(resource);
936 if (existing == adapter) {
937 decl.instanceAdapters.remove(resource);
943 public <T> void addAdapter(Resource type, Class<T> targetClass, Adapter<T,?> adapter) {
944 addAdapter(type, targetClass, Resource.class, adapter);
948 public <T> void addAdapter(Resource type, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
949 getDeclaration(targetClass, contextClass).typeAdapters.put(type, adapter);
953 public <T> void declareAdapter(Resource type, Class<T> targetClass) {
954 declareAdapter(type, targetClass, Resource.class);
958 public <T> void declareAdapter(Resource type, Class<T> targetClass, Class<?> contextClass) {
959 getDeclaration(targetClass, contextClass).baseTypes.add(type);
962 public static String safeName(ReadGraph g, Resource r) throws DatabaseException {
963 // Builtins b = g.getBuiltins();
964 // for(Resource name : g.getObjects(r, b.HasName))
965 // return g.getValue(name);
966 // for(Resource t : g.getObjects(r, b.InstanceOf))
967 // for(Resource name : g.getObjects(t, b.HasName))
968 // return ": "+ g.getValue(name);
969 // for(Resource t : g.getObjects(r, b.Inherits))
970 // for(Resource name : g.getObjects(t, b.HasName))
971 // return "<T "+ g.getValue(name);
972 // for(Resource t : g.getObjects(r, b.SubrelationOf))
973 // for(Resource name : g.getObjects(t, b.HasName))
974 // return "<R "+ g.getValue(name);
976 // return "\"" + g.getValue(r) + "\"";
977 // return "" + r.getResourceId();
978 return NameUtils.getSafeName(g, r, true);