]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.objmap2/src/org/simantics/objmap/graph/schema/DynamicSimpleLinkType.java
e7da15a5dc0476331f66522ce9da31a8a35ec68e
[simantics/3d.git] / org.simantics.objmap2 / src / org / simantics / objmap / graph / schema / DynamicSimpleLinkType.java
1 package org.simantics.objmap.graph.schema;\r
2 \r
3 import java.lang.reflect.InvocationTargetException;\r
4 import java.lang.reflect.Method;\r
5 import java.util.ArrayList;\r
6 \r
7 import org.simantics.db.ReadGraph;\r
8 import org.simantics.db.Resource;\r
9 import org.simantics.db.WriteGraph;\r
10 import org.simantics.db.common.utils.NameUtils;\r
11 import org.simantics.db.exception.DatabaseException;\r
12 import org.simantics.layer0.Layer0;\r
13 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;\r
14 import org.simantics.objmap.exceptions.MappingException;\r
15 import org.simantics.objmap.graph.annotations.GetType;\r
16 import org.simantics.objmap.graph.annotations.SetType;\r
17 \r
18 public class DynamicSimpleLinkType<Range> extends SimpleLinkType<Range>{\r
19 \r
20         protected Method typeGetter;\r
21         protected Method typeSetter;\r
22         \r
23         public DynamicSimpleLinkType(Resource domainType, Class<?> rangeType, ArrayList<IBidirectionalMappingRule<Resource, Range>> rules) {\r
24                 super(domainType, rangeType, rules);\r
25                 findTypeGetter(rangeType);\r
26         }\r
27 \r
28         public DynamicSimpleLinkType(Resource domainType, Class<?> rangeType) {\r
29                 super(domainType, rangeType);\r
30                 findTypeGetter(rangeType);\r
31         }\r
32         \r
33         private void findTypeGetter(Class<?> clazz) {\r
34                 for (Method m : clazz.getDeclaredMethods()) {\r
35                          m.setAccessible(true);\r
36                          GetType t = m.getAnnotation(GetType.class);\r
37                          if (t != null) {\r
38                                  typeGetter = m;\r
39                          }\r
40                          SetType t2 = m.getAnnotation(SetType.class);\r
41                          if (t2 != null) {\r
42                                  typeSetter = m;\r
43                          }\r
44                 }\r
45                 if (typeGetter == null || typeSetter == null) {\r
46                         Class<?> superClazz = clazz.getSuperclass();\r
47                         if (superClazz != Object.class)\r
48                                 findTypeGetter(superClazz);\r
49                         if (typeGetter == null || typeSetter == null) {\r
50                                 throw new RuntimeException("Cannot find dynamic type methods for class " + clazz.getSimpleName());      \r
51                         }\r
52                 }\r
53                 \r
54                         \r
55         }\r
56         \r
57         @Override\r
58     public Resource createDomainElement(WriteGraph g, Range rangeElement)\r
59             throws MappingException {\r
60         try {\r
61                 String typeUri = (String)typeGetter.invoke(rangeElement, null);\r
62             if(LOGGER.isInfoEnabled())\r
63                 LOGGER.info("SimpleLinkType.createDomainElement " +\r
64                         rangeElement.toString()\r
65                 );\r
66             Resource actualDomainType = g.getResource(typeUri);\r
67             Resource result = g.newResource();\r
68             //g.claim(result, Layer0.getInstance(g).InstanceOf, null, domainType);\r
69             g.claim(result, Layer0.getInstance(g).InstanceOf, null, actualDomainType);\r
70             return result;\r
71         } catch(DatabaseException e) {\r
72             throw new MappingException(e);\r
73         } catch (IllegalArgumentException e) {\r
74                  throw new MappingException(e);\r
75                 } catch (IllegalAccessException e) {\r
76                          throw new MappingException(e);\r
77                 } catch (InvocationTargetException e) {\r
78                          throw new MappingException(e);\r
79                 }\r
80     }\r
81         \r
82          @Override\r
83             public Range createRangeElement(ReadGraph g, Resource domainElement)\r
84                     throws MappingException {\r
85                 try {\r
86                     if(LOGGER.isInfoEnabled())\r
87                         try { \r
88                             LOGGER.info("SimpleLinkType.createRangeElement " +\r
89                                         NameUtils.getSafeName(g, domainElement)\r
90                                     );\r
91                         } catch(DatabaseException e) {\r
92                             throw new MappingException(e);\r
93                         }\r
94                    Range r =  (Range)rangeType.newInstance();\r
95                    Resource type = g.getSingleType(domainElement, domainType);\r
96                    String uri = g.getURI(type);\r
97                    typeSetter.invoke(r, uri);\r
98                    return r;\r
99                 } catch (InstantiationException e) {\r
100                     throw new MappingException(e);\r
101                 } catch (IllegalAccessException e) {\r
102                     throw new MappingException(e);\r
103                 } catch (DatabaseException e) {\r
104                         throw new MappingException(e);\r
105                         } catch (IllegalArgumentException e) {\r
106                                 throw new MappingException(e);\r
107                         } catch (InvocationTargetException e) {\r
108                                 throw new MappingException(e);\r
109                         } \r
110             }\r
111 \r
112 }\r