1 /*******************************************************************************
\r
2 * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.objmap.graph.schema;
\r
14 import java.lang.reflect.InvocationTargetException;
\r
15 import java.lang.reflect.Method;
\r
16 import java.util.ArrayList;
\r
18 import org.simantics.db.ReadGraph;
\r
19 import org.simantics.db.Resource;
\r
20 import org.simantics.db.WriteGraph;
\r
21 import org.simantics.db.common.utils.NameUtils;
\r
22 import org.simantics.db.exception.DatabaseException;
\r
23 import org.simantics.layer0.Layer0;
\r
24 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;
\r
25 import org.simantics.objmap.exceptions.MappingException;
\r
26 import org.simantics.objmap.graph.annotations.GetType;
\r
27 import org.simantics.objmap.graph.annotations.SetType;
\r
29 public class DynamicSimpleLinkType<Range> extends SimpleLinkType<Range>{
\r
31 protected Method typeGetter;
\r
32 protected Method typeSetter;
\r
34 public DynamicSimpleLinkType(Resource domainType, Class<?> rangeType, ArrayList<IBidirectionalMappingRule<Resource, Range>> rules) {
\r
35 super(domainType, rangeType, rules);
\r
36 findTypeGetter(rangeType);
\r
39 public DynamicSimpleLinkType(Resource domainType, Class<?> rangeType) {
\r
40 super(domainType, rangeType);
\r
41 findTypeGetter(rangeType);
\r
44 private void findTypeGetter(Class<?> clazz) {
\r
45 for (Method m : clazz.getDeclaredMethods()) {
\r
46 m.setAccessible(true);
\r
47 GetType t = m.getAnnotation(GetType.class);
\r
51 SetType t2 = m.getAnnotation(SetType.class);
\r
56 if (typeGetter == null || typeSetter == null) {
\r
57 Class<?> superClazz = clazz.getSuperclass();
\r
58 if (superClazz != Object.class)
\r
59 findTypeGetter(superClazz);
\r
60 if (typeGetter == null || typeSetter == null) {
\r
61 throw new RuntimeException("Cannot find dynamic type methods for class " + clazz.getSimpleName());
\r
69 public Resource createDomainElement(WriteGraph g, Range rangeElement)
\r
70 throws MappingException {
\r
72 String typeUri = (String)typeGetter.invoke(rangeElement, (Object[]) null);
\r
73 if(LOGGER.isInfoEnabled())
\r
74 LOGGER.info("SimpleLinkType.createDomainElement " +
\r
75 rangeElement.toString()
\r
77 Resource actualDomainType = g.getResource(typeUri);
\r
78 Resource result = g.newResource();
\r
79 //g.claim(result, Layer0.getInstance(g).InstanceOf, null, domainType);
\r
80 g.claim(result, Layer0.getInstance(g).InstanceOf, null, actualDomainType);
\r
82 } catch(DatabaseException e) {
\r
83 throw new MappingException(e);
\r
84 } catch (IllegalArgumentException e) {
\r
85 throw new MappingException(e);
\r
86 } catch (IllegalAccessException e) {
\r
87 throw new MappingException(e);
\r
88 } catch (InvocationTargetException e) {
\r
89 throw new MappingException(e);
\r
93 @SuppressWarnings("unchecked")
\r
95 public Range createRangeElement(ReadGraph g, Resource domainElement)
\r
96 throws MappingException {
\r
98 if(LOGGER.isInfoEnabled())
\r
100 LOGGER.info("SimpleLinkType.createRangeElement " +
\r
101 NameUtils.getSafeName(g, domainElement)
\r
103 } catch(DatabaseException e) {
\r
104 throw new MappingException(e);
\r
106 Range r = (Range)rangeType.newInstance();
\r
107 Resource type = g.getSingleType(domainElement, domainType);
\r
108 String uri = g.getURI(type);
\r
109 typeSetter.invoke(r, uri);
\r
111 } catch (InstantiationException e) {
\r
112 throw new MappingException(e);
\r
113 } catch (IllegalAccessException e) {
\r
114 throw new MappingException(e);
\r
115 } catch (DatabaseException e) {
\r
116 throw new MappingException(e);
\r
117 } catch (IllegalArgumentException e) {
\r
118 throw new MappingException(e);
\r
119 } catch (InvocationTargetException e) {
\r
120 throw new MappingException(e);
\r