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 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.request.UniqueAsyncRead;
24 import org.simantics.db.common.uri.ResourceToURI;
25 import org.simantics.db.common.utils.NameUtils;
26 import org.simantics.db.exception.AdaptionException;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.exception.ServiceException;
29 import org.simantics.db.exception.ValidationException;
30 import org.simantics.db.procedure.AsyncProcedure;
31 import org.simantics.db.request.AsyncRead;
32 import org.simantics.db.request.Read;
33 import org.simantics.layer0.Layer0;
34 import org.simantics.utils.datastructures.Pair;
36 import gnu.trove.map.hash.THashMap;
37 import gnu.trove.procedure.TObjectObjectProcedure;
38 import gnu.trove.set.hash.THashSet;
40 public class AdaptionService2 implements AdaptionService {
42 THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>> adapters =
43 new THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>>();
46 * Contains all adapter declarations and definitions for one class (clazz).
48 static class AdapterDeclaration<T> {
50 THashMap<Resource, Adapter<T,?>> typeAdapters =
51 new THashMap<Resource, Adapter<T,?>>();
52 THashMap<Resource, Adapter<T,?>> instanceAdapters =
53 new THashMap<Resource, Adapter<T,?>>();
54 THashSet<Resource> baseTypes = new THashSet<Resource>();
56 String getDescription(final ReadGraph g) {
57 final StringBuilder b = new StringBuilder();
58 b.append("The following adapters have been defined for ");
59 b.append(clazz.getCanonicalName());
61 typeAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
64 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
67 b.append(g.syncRequest(new ResourceToURI(arg0)));
68 } catch (DatabaseException e) {
80 instanceAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
83 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
84 b.append(" resource ");
86 b.append(g.syncRequest(new ResourceToURI(arg0)));
87 } catch (DatabaseException e) {
101 public AdapterDeclaration(Class<T> clazz) {
105 static class AdapterResult<T,C> {
106 Adapter<T,C> adapter;
109 public AdapterResult(Adapter<T,C> adapter, Resource type) {
110 this.adapter = adapter;
116 * The query returns the adapter inherited by the parameter type.
117 * The query is used only in the case, the type itself does not have
118 * an adapter. The second component of the result contains the type
119 * that originally contributed the adapter.
121 static class GetInheritedAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, AdapterResult<T,C>> {
123 public GetInheritedAdapter(Resource type, AdapterDeclaration<T> decl) {
127 AdapterDeclaration<T> getDeclaration() {
132 public String toString() {
133 return "GetInheritedAdapter|" + parameter + "|" + parameter2;
136 @SuppressWarnings("unchecked")
138 public AdapterResult<T,C> perform(ReadGraph g) throws DatabaseException {
139 Layer0 b = Layer0.getInstance(g);
140 AdapterResult<T,C> result = null;
141 for(Resource supertype : g.getObjects(parameter, b.Inherits)) {
142 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(supertype);
143 if(adapter != null) {
145 result = new AdapterResult<T,C>(adapter, supertype);
146 else if(!result.type.equals(supertype) &&
147 !g.isInheritedFrom(result.type, supertype)) {
148 if(g.isInheritedFrom(supertype, result.type))
149 result = new AdapterResult<T,C>(adapter, supertype);
150 else throw new AdaptionException("Type " +
151 safeName(g, parameter) + " inherits conflicting adapters from "
152 + safeName(g, supertype) + " and " + safeName(g, result.type));
156 AdapterResult<T,C> temp =
157 g.syncRequest(new GetInheritedAdapter<T, C>(supertype, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
161 else if(!result.type.equals(temp.type) &&
162 !g.isInheritedFrom(result.type, temp.type)) {
163 if(g.isInheritedFrom(temp.type, result.type))
165 else throw new AdaptionException("Type " +
166 safeName(g, parameter) + " inherits conflicting adapters from "
167 + safeName(g, temp.type) + " and " + safeName(g, result.type));
177 <C> void inheritedAdapter(AsyncReadGraph graph, Resource type, AsyncProcedure<AdapterResult<T,C>> procedure) {
178 graph.asyncRequest(new GetInheritedAdapter<T, C>(type, this), procedure);
181 Adapter<T,?> directAdapter(Resource r) {
183 synchronized (this) {
184 ret = instanceAdapters.get(r);
189 static class FindAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, Adapter<T,C>> {
191 public FindAdapter(Resource resource, AdapterDeclaration<T> decl) {
192 super(resource, decl);
195 @SuppressWarnings("unchecked")
196 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
199 Adapter<T,C> adapter;
200 synchronized (this) {
201 adapter = (Adapter<T,C>)parameter2.instanceAdapters.get(r);
207 Layer0 b = Layer0.getInstance(g);
210 * Try to find adapter from immediate types
212 AdapterResult<T,C> adapterResult = null;
213 for(Resource t : g.getObjects(r, b.InstanceOf)) {
214 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(t);
215 if(adapter != null) {
216 if(adapterResult == null)
217 adapterResult = new AdapterResult<T,C>(adapter, t);
218 else if(!adapterResult.type.equals(t) &&
219 !g.isInheritedFrom(adapterResult.type, t)) {
220 if(g.isInheritedFrom(t, adapterResult.type))
221 adapterResult = new AdapterResult<T,C>(adapter, t);
222 else throw new AdaptionException("Resource " +
223 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
224 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
229 AdapterResult<T,C> temp =
230 g.syncRequest(new GetInheritedAdapter<T, C>(t, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
232 if(adapterResult == null)
233 adapterResult = temp;
234 else if(!adapterResult.type.equals(temp.type) &&
235 !g.isInheritedFrom(adapterResult.type, temp.type)) {
236 if(g.isInheritedFrom(temp.type, adapterResult.type))
237 adapterResult = temp;
238 else throw new AdaptionException("Resource " +
239 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
240 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
247 if(adapterResult != null)
248 return adapterResult.adapter;
250 for(Resource t : g.getObjects(r, b.Inherits)) {
251 Adapter<T,C> adapter = findAdapter(t, g);
256 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
257 Adapter<T,C> adapter = findAdapter(t, g);
268 public Adapter<T,C> perform(ReadGraph g) throws DatabaseException {
269 return (Adapter<T, C>)findAdapter(parameter, g);
275 * The query returns either an adapter or adapted for the given
276 * resource. It is assumed that the resource itself does not
279 class Adapt<C> implements Read<T> {
284 public Adapt(Resource resource, C context) {
285 this.resource = resource;
286 this.context = context;
289 AdapterDeclaration<T> getDeclaration() {
290 return AdapterDeclaration.this;
293 @SuppressWarnings("unchecked")
294 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
297 Adapter<T,C> adapter;
298 synchronized (this) {
299 adapter = (Adapter<T,C>)instanceAdapters.get(r);
305 Layer0 b = Layer0.getInstance(g);
308 * Try to find adapter from immediate types
310 AdapterResult<T,C> adapterResult = null;
311 for(Resource t : g.getObjects(r, b.InstanceOf)) {
312 Adapter<T,C> adapter = (Adapter<T,C>)typeAdapters.get(t);
313 if(adapter != null) {
314 if(adapterResult == null)
315 adapterResult = new AdapterResult<T,C>(adapter, t);
316 else if(!adapterResult.type.equals(t) &&
317 !g.isInheritedFrom(adapterResult.type, t)) {
318 if(g.isInheritedFrom(t, adapterResult.type))
319 adapterResult = new AdapterResult<T,C>(adapter, t);
320 else throw new AdaptionException("Resource " +
321 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
322 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
327 AdapterResult<T,C> temp =
328 g.syncRequest(new GetInheritedAdapter<T, C>(t, AdapterDeclaration.this));
330 if(adapterResult == null)
331 adapterResult = temp;
332 else if(!adapterResult.type.equals(temp.type) &&
333 !g.isInheritedFrom(adapterResult.type, temp.type)) {
334 if(g.isInheritedFrom(temp.type, adapterResult.type))
335 adapterResult = temp;
336 else throw new AdaptionException("Resource " +
337 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
338 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
345 if(adapterResult != null)
346 return adapterResult.adapter;
348 for(Resource t : g.getObjects(r, b.Inherits)) {
349 Adapter<T,C> adapter = findAdapter(t, g);
354 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
355 Adapter<T,C> adapter = findAdapter(t, g);
365 public T perform(ReadGraph g) throws DatabaseException {
367 final Adapter<T,C> adapter = (Adapter<T, C>)findAdapter(resource, g);
368 if(adapter == null) return null;
369 else return g.syncRequest(new AsyncRead<T>() {
372 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
373 // System.out.println("adapter=" + adapter);
374 adapter.adapt(graph, resource, context, procedure);
378 public int threadHash() {
383 public int getFlags() {
391 @SuppressWarnings("rawtypes")
393 public boolean equals(Object other) {
397 else if (other == null)
399 else if (other.getClass() != Adapt.class)
402 return ((Adapt)other).resource.equals(resource)
403 && ((Adapt)other).context.equals(context)
404 && ((Adapt)other).getDeclaration()==getDeclaration();
409 public int hashCode() {
410 return resource.hashCode() + 31*((getClass().hashCode() + 41*(context.hashCode()) +
411 71*getDeclaration().hashCode()));
416 // void adapt2(AsyncReadGraph graph, Resource r, AsyncProcedure<T> procedure) {
417 // graph.asyncRequest(new Adapt(r), procedure);
420 <C> Adapter<T,C> findAdapter(ReadGraph g, Resource r, boolean possible) throws DatabaseException {
422 Adapter<T,C> result = g.syncRequest(new FindAdapter<T,C>(r, AdapterDeclaration.this));
423 if(result != null) return result;
429 * We couldn't adapt the resource. We analyze the situation little for
430 * better error message.
432 for(Resource dt : baseTypes) {
433 if(g.isInstanceOf(r, dt)) {
434 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
435 safeName(g, r) + " although it is instance of " +
436 safeName(g, dt) + "\n" +
440 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
442 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
447 <C> T adapt(ReadGraph g, Resource r, C context, boolean possible) throws DatabaseException {
449 T result = g.syncRequest(new Adapt<C>(r,context));
450 if(result != null) return result;
456 * We couldn't adapt the resource. We analyze the situation little for
457 * better error message.
459 for(Resource dt : baseTypes) {
460 if(g.isInstanceOf(r, dt)) {
461 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
462 safeName(g, r) + " although it is instance of " +
463 safeName(g, dt) + "\n" +
467 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
469 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
474 T adaptNew(ReadGraph g, final Resource r, boolean possible) throws DatabaseException {
476 T result = new Adapt<Resource>(r,r).perform(g);
483 for(Resource dt : baseTypes) {
484 if(g.isInstanceOf(r, dt)) {
485 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
486 safeName(g, r) + " although it is instance of " +
487 safeName(g, dt) + "\n" +
491 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
493 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
500 private <T> AdapterDeclaration<T> getDeclaration(Class<T> targetClass, Class<?> contextClass) {
501 Pair<Class<?>,Class<?>> key = new Pair<Class<?>,Class<?>>(targetClass, contextClass);
502 @SuppressWarnings("unchecked")
503 AdapterDeclaration<T> decl =
504 (AdapterDeclaration<T>)adapters.get(key);
506 decl = new AdapterDeclaration<T>(targetClass);
507 adapters.put(key, decl);
512 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) {
514 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
515 @SuppressWarnings("unchecked")
516 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
520 procedure.execute(graph, null);
522 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + targetClass + "."));
527 @SuppressWarnings("unchecked")
528 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
529 if(adapter != null) {
530 procedure.execute(graph, adapter);
532 graph.forPossibleObject(r, graph.getService(Layer0.class).InstanceOf, new AsyncProcedure<Resource>() {
535 public void exception(AsyncReadGraph graph, Throwable throwable) {
536 procedure.exception(graph, new AdaptionException("Problems in reading types for resource. ", throwable));
540 public void execute(AsyncReadGraph graph, final Resource singleType) {
541 if(singleType != null) {
542 getSingleTypeAdapter(graph, decl, key, r, singleType, possible, procedure);
544 getSingleSuperTypeAdapter(graph, decl, key, r, r, possible, procedure);
556 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) {
558 getAdapter(graph, r, contextClass, targetClass, possible, new AsyncProcedure<Adapter<T,C>>() {
561 public void execute(AsyncReadGraph graph, Adapter<T, C> result) {
564 procedure.execute(graph, null);
566 procedure.exception(graph, new AdaptionException("Internal error. getAdapter returned null and possible was false."));
569 result.adapt(graph, r, context, procedure);
574 public void exception(AsyncReadGraph graph, Throwable throwable) {
575 procedure.exception(graph, throwable);
583 public <T, C> T adapt(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
585 Adapter<T,C> adapter = getAdapter(g, r, context, contextClass, targetClass, possible);
586 if(adapter == null) return null;
588 return g.syncRequest(new UniqueAsyncRead<T>() {
591 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
592 adapter.adapt(graph, r, context, procedure);
599 private <T, C> Adapter<T,C> getAdapter(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
601 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
602 @SuppressWarnings("unchecked")
603 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
606 if(possible) return null;
607 else throw new AdaptionException("There are no adapters declared or defined for class " + targetClass + ".");
611 @SuppressWarnings("unchecked")
612 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
613 if(adapter != null) return adapter;
615 Layer0 L0 = Layer0.getInstance(g);
616 Resource singleType = g.getPossibleObject(r, L0.InstanceOf);
617 if(singleType != null) {
618 return getSingleTypeAdapter(g, decl, key, r, singleType, possible);
620 return getSingleSuperTypeAdapter(g, decl, key, r, r, possible);
627 private static class SingleTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
629 final private AdapterDeclaration<T> decl;
631 SingleTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource instance, Boolean possible) {
632 super(key, instance, possible);
637 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
638 return decl.findAdapter(graph, parameter2, parameter3);
643 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) {
645 @SuppressWarnings("unchecked")
646 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
647 if(adapter != null) {
648 procedure.execute(graph, adapter);
650 graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
653 public void exception(AsyncReadGraph graph, Throwable throwable) {
654 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
658 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
660 if(singleSuperType != null) {
661 getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible, procedure);
663 graph.asyncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), procedure);
675 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 {
677 @SuppressWarnings("unchecked")
678 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
679 if(adapter != null) return adapter;
681 Layer0 L0 = Layer0.getInstance(graph);
682 Resource singleSuperType = graph.getPossibleObject(type, L0.Inherits);
683 if(singleSuperType != null) {
684 return getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible);
686 return graph.syncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), TransientCacheAsyncListener.<Adapter<T,C>>instance());
691 // 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) {
693 // @SuppressWarnings("unchecked")
694 // Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
695 // if(adapter != null) {
697 // adapter.adapt(graph, instance, context, procedure);
701 // graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
704 // public void exception(AsyncReadGraph graph, Throwable throwable) {
706 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
711 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
713 // if(singleSuperType != null) {
715 // adaptSingleType(graph, decl, context, instance, singleSuperType, possible, procedure);
719 // graph.asyncRequest(new Read<T>() {
722 // public T perform(ReadGraph graph)
723 // throws DatabaseException {
724 // return decl.adapt(graph, instance, context, possible);
741 private static class SingleSuperTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
743 final private AdapterDeclaration<T> decl;
745 SingleSuperTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource type, Boolean possible) {
746 super(key, type, possible);
751 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
752 return decl.findAdapter(graph, parameter2, parameter3);
757 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) {
759 @SuppressWarnings("unchecked")
760 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
761 if(adapter != null) {
762 procedure.execute(graph, adapter);
765 graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
768 public void exception(AsyncReadGraph graph, Throwable throwable) {
769 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
773 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
775 if(singleSuperType != null) {
777 getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible, procedure);
781 graph.asyncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible), procedure);
793 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 {
795 @SuppressWarnings("unchecked")
796 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
797 if(adapter != null) return adapter;
799 Layer0 L0 = Layer0.getInstance(graph);
800 Resource singleSuperType = graph.getPossibleObject(superType, L0.Inherits);
801 if(singleSuperType != null) {
802 return getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible);
804 return graph.syncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible));
809 // 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) {
811 // @SuppressWarnings("unchecked")
812 // Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
813 // if(adapter != null) {
815 // adapter.adapt(graph, type, context, procedure);
819 // graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
822 // public void exception(AsyncReadGraph graph, Throwable throwable) {
824 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
829 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
831 // if(singleSuperType != null) {
833 // adaptSingleSupertype(graph, decl, context, type, singleSuperType, possible, procedure);
837 // graph.asyncRequest(new Read<T>() {
840 // public T perform(ReadGraph graph)
841 // throws DatabaseException {
842 // return decl.adapt(graph, type, context, possible);
858 public <T> void adaptNew(AsyncReadGraph g, final Resource r, final Class<T> clazz, final boolean possible, final AsyncProcedure<T> procedure) {
860 g.asyncRequest(new ReadRequest() {
863 public void run(ReadGraph graph) throws DatabaseException {
865 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(clazz, Resource.class);
867 @SuppressWarnings("unchecked")
868 AdapterDeclaration<T> decl =
869 (AdapterDeclaration<T>)adapters.get(key);
873 procedure.execute(g, null);
875 procedure.exception(g, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
879 procedure.execute(g, decl.adaptNew(graph, r, possible));
880 } catch (AdaptionException e) {
882 procedure.execute(g, null);
884 procedure.exception(g, e);
886 } catch (ValidationException e) {
887 procedure.exception(g, e);
888 } catch (DatabaseException e2) {
889 procedure.exception(g, new ServiceException(e2));
900 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
901 addInstanceAdapter(resource, targetClass, Resource.class, adapter);
905 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
906 synchronized (this) {
907 getDeclaration(targetClass, contextClass).instanceAdapters.put(resource, adapter);
912 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass) {
913 return removeInstanceAdapter(resource, targetClass, Resource.class);
917 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass) {
918 synchronized (this) {
919 return getDeclaration(targetClass, contextClass).instanceAdapters.remove(resource);
924 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
925 removeInstanceAdapter(resource, targetClass, Resource.class, adapter);
929 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
930 synchronized (this) {
931 AdapterDeclaration<T> decl = getDeclaration(targetClass, contextClass);
932 Adapter<T,?> existing = decl.instanceAdapters.get(resource);
933 if (existing == adapter) {
934 decl.instanceAdapters.remove(resource);
940 public <T> void addAdapter(Resource type, Class<T> targetClass, Adapter<T,?> adapter) {
941 addAdapter(type, targetClass, Resource.class, adapter);
945 public <T> void addAdapter(Resource type, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
946 getDeclaration(targetClass, contextClass).typeAdapters.put(type, adapter);
950 public <T> void declareAdapter(Resource type, Class<T> targetClass) {
951 declareAdapter(type, targetClass, Resource.class);
955 public <T> void declareAdapter(Resource type, Class<T> targetClass, Class<?> contextClass) {
956 getDeclaration(targetClass, contextClass).baseTypes.add(type);
959 public static String safeName(ReadGraph g, Resource r) throws DatabaseException {
960 // Builtins b = g.getBuiltins();
961 // for(Resource name : g.getObjects(r, b.HasName))
962 // return g.getValue(name);
963 // for(Resource t : g.getObjects(r, b.InstanceOf))
964 // for(Resource name : g.getObjects(t, b.HasName))
965 // return ": "+ g.getValue(name);
966 // for(Resource t : g.getObjects(r, b.Inherits))
967 // for(Resource name : g.getObjects(t, b.HasName))
968 // return "<T "+ g.getValue(name);
969 // for(Resource t : g.getObjects(r, b.SubrelationOf))
970 // for(Resource name : g.getObjects(t, b.HasName))
971 // return "<R "+ g.getValue(name);
973 // return "\"" + g.getValue(r) + "\"";
974 // return "" + r.getResourceId();
975 return NameUtils.getSafeName(g, r, true);