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 {
43 THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>> adapters =
44 new THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>>();
47 * Contains all adapter declarations and definitions for one class (clazz).
49 static class AdapterDeclaration<T> {
51 THashMap<Resource, Adapter<T,?>> typeAdapters =
52 new THashMap<Resource, Adapter<T,?>>();
53 THashMap<Resource, Adapter<T,?>> instanceAdapters =
54 new THashMap<Resource, Adapter<T,?>>();
55 THashSet<Resource> baseTypes = new THashSet<Resource>();
57 String getDescription(final ReadGraph g) {
58 final StringBuilder b = new StringBuilder();
59 b.append("The following adapters have been defined for ");
60 b.append(clazz.getCanonicalName());
62 typeAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
65 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
68 b.append(g.syncRequest(new ResourceToURI(arg0)));
69 } catch (DatabaseException e) {
81 instanceAdapters.forEachEntry(new TObjectObjectProcedure<Resource, Adapter<T,?>>() {
84 public boolean execute(Resource arg0, Adapter<T,?> arg1) {
85 b.append(" resource ");
87 b.append(g.syncRequest(new ResourceToURI(arg0)));
88 } catch (DatabaseException e) {
102 public AdapterDeclaration(Class<T> clazz) {
106 static class AdapterResult<T,C> {
107 Adapter<T,C> adapter;
110 public AdapterResult(Adapter<T,C> adapter, Resource type) {
111 this.adapter = adapter;
117 * The query returns the adapter inherited by the parameter type.
118 * The query is used only in the case, the type itself does not have
119 * an adapter. The second component of the result contains the type
120 * that originally contributed the adapter.
122 static class GetInheritedAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, AdapterResult<T,C>> {
124 public GetInheritedAdapter(Resource type, AdapterDeclaration<T> decl) {
128 AdapterDeclaration<T> getDeclaration() {
133 public String toString() {
134 return "GetInheritedAdapter|" + parameter + "|" + parameter2;
137 @SuppressWarnings("unchecked")
139 public AdapterResult<T,C> perform(ReadGraph g) throws DatabaseException {
140 Layer0 b = Layer0.getInstance(g);
141 AdapterResult<T,C> result = null;
142 for(Resource supertype : g.getObjects(parameter, b.Inherits)) {
143 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(supertype);
144 if(adapter != null) {
146 result = new AdapterResult<T,C>(adapter, supertype);
147 else if(!result.type.equals(supertype) &&
148 !g.isInheritedFrom(result.type, supertype)) {
149 if(g.isInheritedFrom(supertype, result.type))
150 result = new AdapterResult<T,C>(adapter, supertype);
151 else throw new AdaptionException("Type " +
152 safeName(g, parameter) + " inherits conflicting adapters from "
153 + safeName(g, supertype) + " and " + safeName(g, result.type));
157 AdapterResult<T,C> temp =
158 g.syncRequest(new GetInheritedAdapter<T, C>(supertype, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
162 else if(!result.type.equals(temp.type) &&
163 !g.isInheritedFrom(result.type, temp.type)) {
164 if(g.isInheritedFrom(temp.type, result.type))
166 else throw new AdaptionException("Type " +
167 safeName(g, parameter) + " inherits conflicting adapters from "
168 + safeName(g, temp.type) + " and " + safeName(g, result.type));
178 <C> void inheritedAdapter(AsyncReadGraph graph, Resource type, AsyncProcedure<AdapterResult<T,C>> procedure) {
179 graph.asyncRequest(new GetInheritedAdapter<T, C>(type, this), procedure);
182 Adapter<T,?> directAdapter(Resource r) {
184 synchronized (this) {
185 ret = instanceAdapters.get(r);
190 static class FindAdapter<T,C> extends BinaryRead<Resource, AdapterDeclaration<T>, Adapter<T,C>> {
192 public FindAdapter(Resource resource, AdapterDeclaration<T> decl) {
193 super(resource, decl);
196 @SuppressWarnings("unchecked")
197 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
200 Adapter<T,C> adapter;
201 synchronized (this) {
202 adapter = (Adapter<T,C>)parameter2.instanceAdapters.get(r);
208 Layer0 b = Layer0.getInstance(g);
211 * Try to find adapter from immediate types
213 AdapterResult<T,C> adapterResult = null;
214 for(Resource t : g.getObjects(r, b.InstanceOf)) {
215 Adapter<T,C> adapter = (Adapter<T,C>)parameter2.typeAdapters.get(t);
216 if(adapter != null) {
217 if(adapterResult == null)
218 adapterResult = new AdapterResult<T,C>(adapter, t);
219 else if(!adapterResult.type.equals(t) &&
220 !g.isInheritedFrom(adapterResult.type, t)) {
221 if(g.isInheritedFrom(t, adapterResult.type))
222 adapterResult = new AdapterResult<T,C>(adapter, t);
223 else throw new AdaptionException("Resource " +
224 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
225 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
230 AdapterResult<T,C> temp =
231 g.syncRequest(new GetInheritedAdapter<T, C>(t, parameter2), TransientCacheAsyncListener.<AdapterResult<T,C>>instance());
233 if(adapterResult == null)
234 adapterResult = temp;
235 else if(!adapterResult.type.equals(temp.type) &&
236 !g.isInheritedFrom(adapterResult.type, temp.type)) {
237 if(g.isInheritedFrom(temp.type, adapterResult.type))
238 adapterResult = temp;
239 else throw new AdaptionException("Resource " +
240 safeName(g, r) + " has conflicting " + parameter2.clazz + "-adapters from "
241 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
248 if(adapterResult != null)
249 return adapterResult.adapter;
251 for(Resource t : g.getObjects(r, b.Inherits)) {
252 Adapter<T,C> adapter = findAdapter(t, g);
257 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
258 Adapter<T,C> adapter = findAdapter(t, g);
269 public Adapter<T,C> perform(ReadGraph g) throws DatabaseException {
270 return (Adapter<T, C>)findAdapter(parameter, g);
276 * The query returns either an adapter or adapted for the given
277 * resource. It is assumed that the resource itself does not
280 class Adapt<C> implements Read<T> {
285 public Adapt(Resource resource, C context) {
286 this.resource = resource;
287 this.context = context;
290 AdapterDeclaration<T> getDeclaration() {
291 return AdapterDeclaration.this;
294 @SuppressWarnings("unchecked")
295 Adapter<T,C> findAdapter(Resource r, ReadGraph g) throws DatabaseException {
298 Adapter<T,C> adapter;
299 synchronized (this) {
300 adapter = (Adapter<T,C>)instanceAdapters.get(r);
306 Layer0 b = Layer0.getInstance(g);
309 * Try to find adapter from immediate types
311 AdapterResult<T,C> adapterResult = null;
312 for(Resource t : g.getObjects(r, b.InstanceOf)) {
313 Adapter<T,C> adapter = (Adapter<T,C>)typeAdapters.get(t);
314 if(adapter != null) {
315 if(adapterResult == null)
316 adapterResult = new AdapterResult<T,C>(adapter, t);
317 else if(!adapterResult.type.equals(t) &&
318 !g.isInheritedFrom(adapterResult.type, t)) {
319 if(g.isInheritedFrom(t, adapterResult.type))
320 adapterResult = new AdapterResult<T,C>(adapter, t);
321 else throw new AdaptionException("Resource " +
322 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
323 + safeName(g, t) + " and " + safeName(g, adapterResult.type)
328 AdapterResult<T,C> temp =
329 g.syncRequest(new GetInheritedAdapter<T, C>(t, AdapterDeclaration.this));
331 if(adapterResult == null)
332 adapterResult = temp;
333 else if(!adapterResult.type.equals(temp.type) &&
334 !g.isInheritedFrom(adapterResult.type, temp.type)) {
335 if(g.isInheritedFrom(temp.type, adapterResult.type))
336 adapterResult = temp;
337 else throw new AdaptionException("Resource " +
338 safeName(g, r) + " has conflicting " + clazz + "-adapters from "
339 + safeName(g, temp.type) + " and " + safeName(g, adapterResult.type)
346 if(adapterResult != null)
347 return adapterResult.adapter;
349 for(Resource t : g.getObjects(r, b.Inherits)) {
350 Adapter<T,C> adapter = findAdapter(t, g);
355 for(Resource t : g.getObjects(r, b.SubrelationOf)) {
356 Adapter<T,C> adapter = findAdapter(t, g);
366 public T perform(ReadGraph g) throws DatabaseException {
368 final Adapter<T,C> adapter = (Adapter<T, C>)findAdapter(resource, g);
369 if(adapter == null) return null;
370 else return g.syncRequest(new AsyncRead<T>() {
373 public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
374 // System.out.println("adapter=" + adapter);
375 adapter.adapt(graph, resource, context, procedure);
379 public int threadHash() {
384 public int getFlags() {
392 @SuppressWarnings("rawtypes")
394 public boolean equals(Object other) {
398 else if (other == null)
400 else if (other.getClass() != Adapt.class)
403 return ((Adapt)other).resource.equals(resource)
404 && ((Adapt)other).context.equals(context)
405 && ((Adapt)other).getDeclaration()==getDeclaration();
410 public int hashCode() {
411 return resource.hashCode() + 31*((getClass().hashCode() + 41*(context.hashCode()) +
412 71*getDeclaration().hashCode()));
417 // void adapt2(AsyncReadGraph graph, Resource r, AsyncProcedure<T> procedure) {
418 // graph.asyncRequest(new Adapt(r), procedure);
421 <C> Adapter<T,C> findAdapter(ReadGraph g, Resource r, boolean possible) throws DatabaseException {
423 Adapter<T,C> result = g.syncRequest(new FindAdapter<T,C>(r, AdapterDeclaration.this));
424 if(result != null) return result;
430 * We couldn't adapt the resource. We analyze the situation little for
431 * better error message.
433 for(Resource dt : baseTypes) {
434 if(g.isInstanceOf(r, dt)) {
435 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
436 safeName(g, r) + " although it is instance of " +
437 safeName(g, dt) + "\n" +
441 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
443 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
448 <C> T adapt(ReadGraph g, Resource r, C context, boolean possible) throws DatabaseException {
450 T result = g.syncRequest(new Adapt<C>(r,context));
451 if(result != null) return result;
457 * We couldn't adapt the resource. We analyze the situation little for
458 * better error message.
460 for(Resource dt : baseTypes) {
461 if(g.isInstanceOf(r, dt)) {
462 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
463 safeName(g, r) + " although it is instance of " +
464 safeName(g, dt) + "\n" +
468 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
470 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
475 T adaptNew(ReadGraph g, final Resource r, boolean possible) throws DatabaseException {
477 T result = new Adapt<Resource>(r,r).perform(g);
484 for(Resource dt : baseTypes) {
485 if(g.isInstanceOf(r, dt)) {
486 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
487 safeName(g, r) + " although it is instance of " +
488 safeName(g, dt) + "\n" +
492 throw new AdaptionException("Couldn't find a " + clazz + "-adapter for resource " +
494 ". This is because the resource is not instance of any type which the adapter is declared to.\n" +
501 private <T> AdapterDeclaration<T> getDeclaration(Class<T> targetClass, Class<?> contextClass) {
502 Pair<Class<?>,Class<?>> key = new Pair<Class<?>,Class<?>>(targetClass, contextClass);
503 @SuppressWarnings("unchecked")
504 AdapterDeclaration<T> decl =
505 (AdapterDeclaration<T>)adapters.get(key);
507 decl = new AdapterDeclaration<T>(targetClass);
508 adapters.put(key, decl);
513 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) {
515 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
516 @SuppressWarnings("unchecked")
517 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
521 procedure.execute(graph, null);
523 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + targetClass + "."));
528 @SuppressWarnings("unchecked")
529 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
530 if(adapter != null) {
531 procedure.execute(graph, adapter);
533 graph.forPossibleObject(r, graph.getService(Layer0.class).InstanceOf, new AsyncProcedure<Resource>() {
536 public void exception(AsyncReadGraph graph, Throwable throwable) {
537 procedure.exception(graph, new AdaptionException("Problems in reading types for resource. ", throwable));
541 public void execute(AsyncReadGraph graph, final Resource singleType) {
542 if(singleType != null) {
543 getSingleTypeAdapter(graph, decl, key, r, singleType, possible, procedure);
545 getSingleSuperTypeAdapter(graph, decl, key, r, r, possible, procedure);
557 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) {
559 getAdapter(graph, r, contextClass, targetClass, possible, new AsyncProcedure<Adapter<T,C>>() {
562 public void execute(AsyncReadGraph graph, Adapter<T, C> result) {
565 procedure.execute(graph, null);
567 procedure.exception(graph, new AdaptionException("Internal error. getAdapter returned null and possible was false."));
570 result.adapt(graph, r, context, procedure);
575 public void exception(AsyncReadGraph graph, Throwable throwable) {
576 procedure.exception(graph, throwable);
584 public <T, C> T adapt(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
586 Adapter<T,C> adapter = getAdapter(g, r, context, contextClass, targetClass, possible);
587 if(adapter == null) return null;
589 BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<T>(null, adapter);
591 // SyncReadProcedure<T> procedure = new SyncReadProcedure<T>();
592 adapter.adapt(g, r, context, ap);
594 // procedure.checkAndThrow();
595 // return procedure.result;
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(graph, null);
875 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
879 procedure.execute(graph, decl.adaptNew(graph, r, possible));
880 } catch (AdaptionException e) {
882 procedure.execute(graph, null);
884 procedure.exception(graph, e);
886 } catch (ValidationException e) {
887 procedure.exception(graph, e);
888 } catch (DatabaseException e2) {
889 procedure.exception(graph, 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);