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.adapter.TransientCacheAsyncListener;
24 import org.simantics.db.common.procedure.single.SyncReadProcedure;
25 import org.simantics.db.common.request.BinaryRead;
26 import org.simantics.db.common.request.ReadRequest;
27 import org.simantics.db.common.request.TernaryRead;
28 import org.simantics.db.common.uri.ResourceToURI;
29 import org.simantics.db.common.utils.NameUtils;
30 import org.simantics.db.exception.AdaptionException;
31 import org.simantics.db.exception.DatabaseException;
32 import org.simantics.db.exception.ServiceException;
33 import org.simantics.db.exception.ValidationException;
34 import org.simantics.db.procedure.AsyncProcedure;
35 import org.simantics.db.request.AsyncRead;
36 import org.simantics.db.request.Read;
37 import org.simantics.layer0.Layer0;
38 import org.simantics.utils.datastructures.Pair;
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);
587 SyncReadProcedure<T> procedure = new SyncReadProcedure<T>();
588 adapter.adapt(g, r, context, procedure);
589 procedure.checkAndThrow();
590 return procedure.result;
594 private <T, C> Adapter<T,C> getAdapter(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
596 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(targetClass, contextClass);
597 @SuppressWarnings("unchecked")
598 final AdapterDeclaration<T> decl = (AdapterDeclaration<T>)adapters.get(key);
601 if(possible) return null;
602 else throw new AdaptionException("There are no adapters declared or defined for class " + targetClass + ".");
606 @SuppressWarnings("unchecked")
607 final Adapter<T,C> adapter = (Adapter<T,C>)decl.directAdapter(r);
608 if(adapter != null) return adapter;
610 Layer0 L0 = Layer0.getInstance(g);
611 Resource singleType = g.getPossibleObject(r, L0.InstanceOf);
612 if(singleType != null) {
613 return getSingleTypeAdapter(g, decl, key, r, singleType, possible);
615 return getSingleSuperTypeAdapter(g, decl, key, r, r, possible);
622 private static class SingleTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
624 final private AdapterDeclaration<T> decl;
626 SingleTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource instance, Boolean possible) {
627 super(key, instance, possible);
632 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
633 return decl.findAdapter(graph, parameter2, parameter3);
638 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) {
640 @SuppressWarnings("unchecked")
641 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
642 if(adapter != null) {
643 procedure.execute(graph, adapter);
645 graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
648 public void exception(AsyncReadGraph graph, Throwable throwable) {
649 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
653 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
655 if(singleSuperType != null) {
656 getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible, procedure);
658 graph.asyncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), procedure);
670 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 {
672 @SuppressWarnings("unchecked")
673 Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
674 if(adapter != null) return adapter;
676 Layer0 L0 = Layer0.getInstance(graph);
677 Resource singleSuperType = graph.getPossibleObject(type, L0.Inherits);
678 if(singleSuperType != null) {
679 return getSingleTypeAdapter(graph, decl, key, instance, singleSuperType, possible);
681 return graph.syncRequest(new SingleTypeAdapter<T,C>(decl, key, instance, possible), TransientCacheAsyncListener.<Adapter<T,C>>instance());
686 // 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) {
688 // @SuppressWarnings("unchecked")
689 // Adapter<T,C> adapter = (Adapter<T,C>)decl.typeAdapters.get(type);
690 // if(adapter != null) {
692 // adapter.adapt(graph, instance, context, procedure);
696 // graph.forPossibleObject(type, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
699 // public void exception(AsyncReadGraph graph, Throwable throwable) {
701 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
706 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
708 // if(singleSuperType != null) {
710 // adaptSingleType(graph, decl, context, instance, singleSuperType, possible, procedure);
714 // graph.asyncRequest(new Read<T>() {
717 // public T perform(ReadGraph graph)
718 // throws DatabaseException {
719 // return decl.adapt(graph, instance, context, possible);
736 private static class SingleSuperTypeAdapter<T, C> extends TernaryRead<Pair<Class<T>, Class<?>>, Resource, Boolean, Adapter<T,C>> {
738 final private AdapterDeclaration<T> decl;
740 SingleSuperTypeAdapter(AdapterDeclaration<T> decl, Pair<Class<T>, Class<?>> key, Resource type, Boolean possible) {
741 super(key, type, possible);
746 public Adapter<T,C> perform(ReadGraph graph) throws DatabaseException {
747 return decl.findAdapter(graph, parameter2, parameter3);
752 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) {
754 @SuppressWarnings("unchecked")
755 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
756 if(adapter != null) {
757 procedure.execute(graph, adapter);
760 graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
763 public void exception(AsyncReadGraph graph, Throwable throwable) {
764 procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
768 public void execute(AsyncReadGraph graph, Resource singleSuperType) {
770 if(singleSuperType != null) {
772 getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible, procedure);
776 graph.asyncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible), procedure);
788 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 {
790 @SuppressWarnings("unchecked")
791 Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
792 if(adapter != null) return adapter;
794 Layer0 L0 = Layer0.getInstance(graph);
795 Resource singleSuperType = graph.getPossibleObject(superType, L0.Inherits);
796 if(singleSuperType != null) {
797 return getSingleSuperTypeAdapter(graph, decl, key, type, singleSuperType, possible);
799 return graph.syncRequest(new SingleSuperTypeAdapter<T,C>(decl, key, type, possible));
804 // 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) {
806 // @SuppressWarnings("unchecked")
807 // Adapter<T, C> adapter = (Adapter<T, C>)decl.instanceAdapters.get(superType);
808 // if(adapter != null) {
810 // adapter.adapt(graph, type, context, procedure);
814 // graph.forPossibleObject(superType, graph.getService(Layer0.class).Inherits, new AsyncProcedure<Resource>() {
817 // public void exception(AsyncReadGraph graph, Throwable throwable) {
819 // procedure.exception(graph, new AdaptionException("Problems in reading super types for resource. ", throwable));
824 // public void execute(AsyncReadGraph graph, Resource singleSuperType) {
826 // if(singleSuperType != null) {
828 // adaptSingleSupertype(graph, decl, context, type, singleSuperType, possible, procedure);
832 // graph.asyncRequest(new Read<T>() {
835 // public T perform(ReadGraph graph)
836 // throws DatabaseException {
837 // return decl.adapt(graph, type, context, possible);
853 public <T> void adaptNew(AsyncReadGraph g, final Resource r, final Class<T> clazz, final boolean possible, final AsyncProcedure<T> procedure) {
855 g.asyncRequest(new ReadRequest() {
858 public void run(ReadGraph graph) throws DatabaseException {
860 final Pair<Class<T>, Class<?>> key = new Pair<Class<T>, Class<?>>(clazz, Resource.class);
862 @SuppressWarnings("unchecked")
863 AdapterDeclaration<T> decl =
864 (AdapterDeclaration<T>)adapters.get(key);
868 procedure.execute(graph, null);
870 procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
874 procedure.execute(graph, decl.adaptNew(graph, r, possible));
875 } catch (AdaptionException e) {
877 procedure.execute(graph, null);
879 procedure.exception(graph, e);
881 } catch (ValidationException e) {
882 procedure.exception(graph, e);
883 } catch (DatabaseException e2) {
884 procedure.exception(graph, new ServiceException(e2));
895 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
896 addInstanceAdapter(resource, targetClass, Resource.class, adapter);
900 public <T> void addInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
901 synchronized (this) {
902 getDeclaration(targetClass, contextClass).instanceAdapters.put(resource, adapter);
907 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass) {
908 return removeInstanceAdapter(resource, targetClass, Resource.class);
912 public <T> Adapter<T,?> removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass) {
913 synchronized (this) {
914 return getDeclaration(targetClass, contextClass).instanceAdapters.remove(resource);
919 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Adapter<T,?> adapter) {
920 removeInstanceAdapter(resource, targetClass, Resource.class, adapter);
924 public <T> void removeInstanceAdapter(Resource resource, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
925 synchronized (this) {
926 AdapterDeclaration<T> decl = getDeclaration(targetClass, contextClass);
927 Adapter<T,?> existing = decl.instanceAdapters.get(resource);
928 if (existing == adapter) {
929 decl.instanceAdapters.remove(resource);
935 public <T> void addAdapter(Resource type, Class<T> targetClass, Adapter<T,?> adapter) {
936 addAdapter(type, targetClass, Resource.class, adapter);
940 public <T> void addAdapter(Resource type, Class<T> targetClass, Class<?> contextClass, Adapter<T,?> adapter) {
941 getDeclaration(targetClass, contextClass).typeAdapters.put(type, adapter);
945 public <T> void declareAdapter(Resource type, Class<T> targetClass) {
946 declareAdapter(type, targetClass, Resource.class);
950 public <T> void declareAdapter(Resource type, Class<T> targetClass, Class<?> contextClass) {
951 getDeclaration(targetClass, contextClass).baseTypes.add(type);
954 public static String safeName(ReadGraph g, Resource r) throws DatabaseException {
955 // Builtins b = g.getBuiltins();
956 // for(Resource name : g.getObjects(r, b.HasName))
957 // return g.getValue(name);
958 // for(Resource t : g.getObjects(r, b.InstanceOf))
959 // for(Resource name : g.getObjects(t, b.HasName))
960 // return ": "+ g.getValue(name);
961 // for(Resource t : g.getObjects(r, b.Inherits))
962 // for(Resource name : g.getObjects(t, b.HasName))
963 // return "<T "+ g.getValue(name);
964 // for(Resource t : g.getObjects(r, b.SubrelationOf))
965 // for(Resource name : g.getObjects(t, b.HasName))
966 // return "<R "+ g.getValue(name);
968 // return "\"" + g.getValue(r) + "\"";
969 // return "" + r.getResourceId();
970 return NameUtils.getSafeName(g, r, true);