]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.objmap2/src/org/simantics/objmap/structural/schema/MappingSchemas.java
758db0e029e53ca2608ae7bcecf9e8e5aef980d4
[simantics/3d.git] / org.simantics.objmap2 / src / org / simantics / objmap / structural / schema / MappingSchemas.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.objmap.structural.schema;\r
13 \r
14 import java.lang.annotation.Annotation;\r
15 import java.lang.reflect.Field;\r
16 import java.lang.reflect.Method;\r
17 import java.util.ArrayList;\r
18 import java.util.Collection;\r
19 \r
20 import org.simantics.db.ReadGraph;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.exception.DatabaseException;\r
23 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;\r
24 import org.simantics.objmap.graph.annotations.GraphType;\r
25 import org.simantics.objmap.graph.annotations.HasCollectionAdder;\r
26 import org.simantics.objmap.graph.annotations.HasCollectionRemover;\r
27 import org.simantics.objmap.graph.annotations.HasSetter;\r
28 import org.simantics.objmap.graph.annotations.OptionalRelatedElements;\r
29 import org.simantics.objmap.graph.annotations.RelatedElements;\r
30 import org.simantics.objmap.graph.annotations.RelatedElementsGet;\r
31 import org.simantics.objmap.graph.annotations.RelatedGetObj;\r
32 import org.simantics.objmap.graph.annotations.RelatedGetValue;\r
33 import org.simantics.objmap.graph.annotations.RelatedOrderedSetElements;\r
34 import org.simantics.objmap.graph.annotations.RelatedValue;\r
35 import org.simantics.objmap.graph.annotations.UpdateMethod;\r
36 import org.simantics.objmap.structural.annotations.StructuralRelatedElementsGet;\r
37 import org.simantics.objmap.structural.annotations.StructuralRelatedGetObj;\r
38 import org.simantics.objmap.structural.annotations.TypeRelatedElementsGet;\r
39 import org.simantics.objmap.structural.annotations.TypeRelatedGetObj;\r
40 import org.simantics.objmap.structural.annotations.TypeRelatedGetValue;\r
41 import org.simantics.objmap.structural.annotations.factories.OptionalRelatedElementsRuleFactory;\r
42 import org.simantics.objmap.structural.annotations.factories.RelatedElementsRuleFactory;\r
43 import org.simantics.objmap.structural.annotations.factories.RelatedElementsRuleFactory2;\r
44 import org.simantics.objmap.structural.annotations.factories.RelatedGetSetObjRuleFactory;\r
45 import org.simantics.objmap.structural.annotations.factories.RelatedGetSetValueRuleFactory;\r
46 import org.simantics.objmap.structural.annotations.factories.RelatedOrderedSetElementsRuleFactory;\r
47 import org.simantics.objmap.structural.annotations.factories.RelatedValueRuleFactory;\r
48 import org.simantics.objmap.structural.annotations.factories.StructuralRelatedElementsRuleFactory2;\r
49 import org.simantics.objmap.structural.annotations.factories.StructuralRelatedGetSetObjRuleFactory;\r
50 import org.simantics.objmap.structural.annotations.factories.TypeRelatedElementsRuleFactory2;\r
51 import org.simantics.objmap.structural.annotations.factories.TypeRelatedGetSetObjRuleFactory;\r
52 import org.simantics.objmap.structural.annotations.factories.TypeRelatedGetSetValueRuleFactory;\r
53 import org.simantics.objmap.structural.annotations.factories.UpdateMethodFactory;\r
54 import org.simantics.objmap.graph.annotations.meta.IsClassRule;\r
55 import org.simantics.objmap.graph.annotations.meta.IsCollectionRule;\r
56 import org.simantics.objmap.graph.annotations.meta.IsFieldRule;\r
57 import org.simantics.objmap.graph.annotations.meta.IsGetSetRule;\r
58 import org.simantics.objmap.graph.annotations.meta.IsMethodRule;\r
59 import org.simantics.objmap.graph.rules.factory.IClassRuleFactory;\r
60 import org.simantics.objmap.graph.rules.factory.ICollectionRuleFactory;\r
61 import org.simantics.objmap.graph.rules.factory.IFieldRuleFactory;\r
62 import org.simantics.objmap.graph.rules.factory.IGetSetRuleFactory;\r
63 import org.simantics.objmap.graph.rules.factory.IMethodRuleFactory;\r
64 import org.simantics.objmap.structural.IStructuralObject;\r
65 import org.simantics.objmap.structural.StructuralResource;\r
66 \r
67 \r
68 public class MappingSchemas {\r
69         /**\r
70      * Creates a new SimpleLinkType based on the annotations in the given class.\r
71      * @throws IllegalAccessException \r
72      * @throws InstantiationException \r
73      * @see GraphType\r
74      * @see RelatedValue\r
75      */\r
76         public static SimpleLinkType fromAnnotations(ReadGraph g, Class<?> clazz) throws DatabaseException, InstantiationException, IllegalAccessException {\r
77             GraphType graphType = clazz.getAnnotation(GraphType.class);\r
78             \r
79             ArrayList<IBidirectionalMappingRule<StructuralResource, IStructuralObject>> rules = new ArrayList<IBidirectionalMappingRule<StructuralResource, IStructuralObject>>();\r
80             collectRulesFromAnnotations(g, clazz, rules);\r
81             \r
82             return new SimpleLinkType(\r
83                     g.getResource(graphType.value()), \r
84                 clazz, rules);    \r
85         }\r
86         \r
87         public static void collectRulesFromAnnotations(ReadGraph g, Class<?> clazz, Collection<IBidirectionalMappingRule<StructuralResource, IStructuralObject>> rules) throws DatabaseException, InstantiationException, IllegalAccessException {\r
88                   Class<?> superclass = clazz.getSuperclass();\r
89                     if(superclass != null)\r
90                         collectRulesFromAnnotations(g, superclass, rules);\r
91                         \r
92                 for(Annotation annotation : clazz.getAnnotations()) {\r
93 \r
94                         IsClassRule tag = annotation.annotationType().getAnnotation(IsClassRule.class);\r
95                     if(tag!= null) {\r
96                         rules.add(createClassRule(g, annotation, clazz).create(g, annotation, clazz));\r
97                     }\r
98                 }\r
99 \r
100                 for(Field f : clazz.getDeclaredFields()) {\r
101                     f.setAccessible(true);\r
102 \r
103                     for(Annotation annotation : f.getAnnotations()) {\r
104 \r
105                         IsFieldRule tag = annotation.annotationType().getAnnotation(IsFieldRule.class);\r
106                         if(tag != null) {\r
107                             rules.add(createFieldRule(g, annotation, f).create(g, annotation, f));\r
108                         }\r
109                     }\r
110                 }\r
111 \r
112                 for(Method m : clazz.getDeclaredMethods()) {\r
113                     m.setAccessible(true);\r
114 \r
115                     for(Annotation annotation : m.getAnnotations()) {\r
116                         IsMethodRule tag = \r
117                                 annotation.annotationType().getAnnotation(IsMethodRule.class);\r
118                         if(tag != null) {\r
119                                 rules.add(createMethodRule(g, annotation, m).create(g, annotation, m));\r
120                         }\r
121                     }\r
122                 }\r
123                 \r
124                 for (Method m : clazz.getDeclaredMethods()) {\r
125                         m.setAccessible(true);\r
126                         for (Annotation annotation : m.getAnnotations()) {\r
127                                 Class<? extends Annotation> annotationType = annotation.annotationType();\r
128 \r
129                                  IsGetSetRule tag = \r
130                                  annotationType.getAnnotation(IsGetSetRule.class);\r
131                                  if (tag != null) {\r
132                                          \r
133                                          HasSetter setterAnnType = annotationType.getAnnotation(HasSetter.class);\r
134                                          \r
135                                          Class<? extends Annotation> setterAnn = setterAnnType.value();\r
136                                          \r
137                                          Method getter = m;\r
138                                          \r
139                                          IGetSetRuleFactory<StructuralResource, IStructuralObject> ruleFactory = createGetSetRuleFactory(g, annotation, getter);\r
140                                          \r
141                                          \r
142                                          Method setter = null;\r
143                                          \r
144                                          for (Method m2 : clazz.getDeclaredMethods()) {\r
145                                                  Annotation set = m2.getAnnotation(setterAnn);\r
146                                                  if (set != null && ruleFactory.isSetter(annotation, set))\r
147                                                          setter = m2;\r
148                                          }\r
149 \r
150                                          rules.add(ruleFactory.create(g, annotation, getter, setter));\r
151                                  }\r
152                         \r
153                         }\r
154                 }\r
155                 \r
156                 for (Method m : clazz.getDeclaredMethods()) {\r
157                         m.setAccessible(true);\r
158                         for (Annotation annotation : m.getAnnotations()) {\r
159                                 Class<? extends Annotation> annotationType = annotation.annotationType();\r
160 \r
161                                  IsCollectionRule tag = \r
162                                  annotationType.getAnnotation(IsCollectionRule.class);\r
163                                  if (tag != null) {\r
164                                          \r
165                                          HasCollectionAdder adderAnnType = annotationType.getAnnotation(HasCollectionAdder.class);\r
166                                          HasCollectionRemover removerAnnType = annotationType.getAnnotation(HasCollectionRemover.class);\r
167                         \r
168                                          Class<? extends Annotation> adderAnn = adderAnnType.value();\r
169                                          Class<? extends Annotation> removerAnn = removerAnnType.value();\r
170                                          \r
171                                          Method getter = m;\r
172                                          \r
173                                          ICollectionRuleFactory<StructuralResource, IStructuralObject> ruleFactory = createCollectionRuleFactory(g, annotation, getter);\r
174                                          \r
175                                          \r
176                                          Method adder = null;\r
177                                          Method remover = null;\r
178                                          \r
179                                          for (Method m2 : clazz.getDeclaredMethods()) {\r
180                                                  Annotation add = m2.getAnnotation(adderAnn);\r
181                                                  Annotation rem = m2.getAnnotation(removerAnn);\r
182                                                  if (add != null && ruleFactory.isAdder(annotation, add))\r
183                                                          adder = m2;\r
184                                                  if (rem != null && ruleFactory.isRemover(annotation, rem))\r
185                                                          remover = m2;\r
186                                          }\r
187                                          \r
188                                          \r
189                                          \r
190                                          rules.add(ruleFactory.create(g, annotation, getter,adder,remover));\r
191                                  }\r
192                         \r
193                         }\r
194                 }\r
195             }\r
196                 \r
197                 public static IClassRuleFactory<StructuralResource, IStructuralObject> createClassRule(ReadGraph g, Annotation annotation, Class<?> clazz) {\r
198                         return null;\r
199                 }\r
200                 \r
201                 public static IFieldRuleFactory<StructuralResource, IStructuralObject> createFieldRule(ReadGraph g, Annotation annotation, Field field) {\r
202                         if (annotation.annotationType().equals(RelatedElements.class))\r
203                                 return new RelatedElementsRuleFactory<IStructuralObject>();\r
204                         if (annotation.annotationType().equals(RelatedValue.class))\r
205                                 return new RelatedValueRuleFactory<IStructuralObject>();\r
206                         if (annotation.annotationType().equals(OptionalRelatedElements.class))\r
207                                 return new OptionalRelatedElementsRuleFactory<IStructuralObject>();\r
208                         if (annotation.annotationType().equals(RelatedOrderedSetElements.class))\r
209                                 return new RelatedOrderedSetElementsRuleFactory<IStructuralObject>();\r
210                         return null;\r
211                 }\r
212                 \r
213                 public static IMethodRuleFactory<StructuralResource, IStructuralObject> createMethodRule(ReadGraph g, Annotation annotation, Method m) {\r
214                         if (annotation.annotationType().equals(UpdateMethod.class))\r
215                                 return new UpdateMethodFactory<StructuralResource,IStructuralObject>();\r
216                         return null;\r
217                 }\r
218                 \r
219                 public static IGetSetRuleFactory<StructuralResource, IStructuralObject> createGetSetRuleFactory(ReadGraph g, Annotation annotation, Method getter) {\r
220                         if (annotation.annotationType().equals(RelatedGetValue.class))\r
221                                 return new RelatedGetSetValueRuleFactory<IStructuralObject>();\r
222                         if (annotation.annotationType().equals(RelatedGetObj.class))\r
223                                 return new RelatedGetSetObjRuleFactory<IStructuralObject>();\r
224                         if (annotation.annotationType().equals(TypeRelatedGetValue.class))\r
225                                 return new TypeRelatedGetSetValueRuleFactory<IStructuralObject>();\r
226                         if (annotation.annotationType().equals(TypeRelatedGetObj.class))\r
227                                 return new TypeRelatedGetSetObjRuleFactory<IStructuralObject>();\r
228                         if (annotation.annotationType().equals(StructuralRelatedGetObj.class))\r
229                                 return new StructuralRelatedGetSetObjRuleFactory<IStructuralObject>();\r
230                         return null;\r
231                 }\r
232                 \r
233                 public static ICollectionRuleFactory<StructuralResource, IStructuralObject> createCollectionRuleFactory(ReadGraph g, Annotation annotation, Method getter) {\r
234                         if (annotation.annotationType().equals(RelatedElementsGet.class))\r
235                                 return new RelatedElementsRuleFactory2<IStructuralObject>();\r
236                         if (annotation.annotationType().equals(TypeRelatedElementsGet.class))\r
237                                 return new TypeRelatedElementsRuleFactory2<IStructuralObject>();\r
238                         if (annotation.annotationType().equals(StructuralRelatedElementsGet.class))\r
239                                 return new StructuralRelatedElementsRuleFactory2<IStructuralObject>();\r
240                         return null;\r
241                 }\r
242         \r
243         \r
244         /**\r
245      * Creates a new SimpleLinkType based on the annotations in the given class.\r
246      * @throws IllegalAccessException \r
247      * @throws InstantiationException \r
248      * @see GraphType\r
249      * @see RelatedValue\r
250      */\r
251         public static AdaptedLinkType fromAdaptable(ReadGraph g, String type, Class<?> clazz) throws DatabaseException, InstantiationException, IllegalAccessException {\r
252             \r
253             \r
254             return new AdaptedLinkType(g.getResource(type), clazz);    \r
255         }\r
256         \r
257         \r
258 }\r