]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.objmap2/src/org/simantics/objmap/structural/schema/MappingSchemas.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / 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.exception.DatabaseException;\r
22 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;\r
23 import org.simantics.objmap.graph.annotations.GraphType;\r
24 import org.simantics.objmap.graph.annotations.HasCollectionAdder;\r
25 import org.simantics.objmap.graph.annotations.HasCollectionRemover;\r
26 import org.simantics.objmap.graph.annotations.HasSetter;\r
27 import org.simantics.objmap.graph.annotations.OptionalRelatedElements;\r
28 import org.simantics.objmap.graph.annotations.OrderedSetType;\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.graph.annotations.meta.IsClassRule;\r
37 import org.simantics.objmap.graph.annotations.meta.IsCollectionRule;\r
38 import org.simantics.objmap.graph.annotations.meta.IsFieldRule;\r
39 import org.simantics.objmap.graph.annotations.meta.IsGetSetRule;\r
40 import org.simantics.objmap.graph.annotations.meta.IsMethodRule;\r
41 import org.simantics.objmap.graph.rules.factory.IClassRuleFactory;\r
42 import org.simantics.objmap.graph.rules.factory.ICollectionRuleFactory;\r
43 import org.simantics.objmap.graph.rules.factory.IFieldRuleFactory;\r
44 import org.simantics.objmap.graph.rules.factory.IGetSetRuleFactory;\r
45 import org.simantics.objmap.graph.rules.factory.IMethodRuleFactory;\r
46 import org.simantics.objmap.structural.IStructuralObject;\r
47 import org.simantics.objmap.structural.StructuralResource;\r
48 import org.simantics.objmap.structural.annotations.StructuralRelatedElementsGet;\r
49 import org.simantics.objmap.structural.annotations.StructuralRelatedGetObj;\r
50 import org.simantics.objmap.structural.annotations.TypeRelatedElementsGet;\r
51 import org.simantics.objmap.structural.annotations.TypeRelatedGetObj;\r
52 import org.simantics.objmap.structural.annotations.TypeRelatedGetValue;\r
53 import org.simantics.objmap.structural.annotations.factories.OptionalRelatedElementsRuleFactory;\r
54 import org.simantics.objmap.structural.annotations.factories.RelatedElementsRuleFactory;\r
55 import org.simantics.objmap.structural.annotations.factories.RelatedElementsRuleFactory2;\r
56 import org.simantics.objmap.structural.annotations.factories.RelatedGetSetObjRuleFactory;\r
57 import org.simantics.objmap.structural.annotations.factories.RelatedGetSetValueRuleFactory;\r
58 import org.simantics.objmap.structural.annotations.factories.RelatedOrderedSetElementsRuleFactory;\r
59 import org.simantics.objmap.structural.annotations.factories.RelatedValueRuleFactory;\r
60 import org.simantics.objmap.structural.annotations.factories.StructuralRelatedElementsRuleFactory2;\r
61 import org.simantics.objmap.structural.annotations.factories.StructuralRelatedGetSetObjRuleFactory;\r
62 import org.simantics.objmap.structural.annotations.factories.TypeRelatedElementsRuleFactory2;\r
63 import org.simantics.objmap.structural.annotations.factories.TypeRelatedGetSetObjRuleFactory;\r
64 import org.simantics.objmap.structural.annotations.factories.TypeRelatedGetSetValueRuleFactory;\r
65 import org.simantics.objmap.structural.annotations.factories.UpdateMethodFactory;\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             if (graphType != null) {\r
80                     ArrayList<IBidirectionalMappingRule<StructuralResource, IStructuralObject>> rules = new ArrayList<IBidirectionalMappingRule<StructuralResource, IStructuralObject>>();\r
81                     collectRulesFromAnnotations(g, clazz, rules);\r
82                     \r
83                     return new SimpleLinkType(g.getResource(graphType.value()), clazz, rules);    \r
84             }\r
85             OrderedSetType orderedSetType = clazz.getAnnotation(OrderedSetType.class);\r
86             if (orderedSetType != null) {\r
87                 ArrayList<IBidirectionalMappingRule<StructuralResource, IStructuralObject>> rules = new ArrayList<IBidirectionalMappingRule<StructuralResource, IStructuralObject>>();\r
88                     collectRulesFromAnnotations(g, clazz, rules);\r
89                     \r
90                     return new OrderedSetSimpleLinkType(g.getResource(orderedSetType.value()), clazz, rules);\r
91             }\r
92             throw new IllegalArgumentException("Class " + clazz.toString() + " does not contain annotations.");\r
93         }\r
94         \r
95         public static void collectRulesFromAnnotations(ReadGraph g, Class<?> clazz, Collection<IBidirectionalMappingRule<StructuralResource, IStructuralObject>> rules) throws DatabaseException, InstantiationException, IllegalAccessException {\r
96                   Class<?> superclass = clazz.getSuperclass();\r
97                     if(superclass != null)\r
98                         collectRulesFromAnnotations(g, superclass, rules);\r
99                         \r
100                 for(Annotation annotation : clazz.getAnnotations()) {\r
101 \r
102                         IsClassRule tag = annotation.annotationType().getAnnotation(IsClassRule.class);\r
103                     if(tag!= null) {\r
104                         rules.add(createClassRule(g, annotation, clazz).create(g, annotation, clazz));\r
105                     }\r
106                 }\r
107 \r
108                 for(Field f : clazz.getDeclaredFields()) {\r
109                     f.setAccessible(true);\r
110 \r
111                     for(Annotation annotation : f.getAnnotations()) {\r
112 \r
113                         IsFieldRule tag = annotation.annotationType().getAnnotation(IsFieldRule.class);\r
114                         if(tag != null) {\r
115                             rules.add(createFieldRule(g, annotation, f).create(g, annotation, f));\r
116                         }\r
117                     }\r
118                 }\r
119 \r
120                 for(Method m : clazz.getDeclaredMethods()) {\r
121                     m.setAccessible(true);\r
122 \r
123                     for(Annotation annotation : m.getAnnotations()) {\r
124                         IsMethodRule tag = \r
125                                 annotation.annotationType().getAnnotation(IsMethodRule.class);\r
126                         if(tag != null) {\r
127                                 rules.add(createMethodRule(g, annotation, m).create(g, annotation, m));\r
128                         }\r
129                     }\r
130                 }\r
131                 \r
132                 for (Method m : clazz.getDeclaredMethods()) {\r
133                         m.setAccessible(true);\r
134                         for (Annotation annotation : m.getAnnotations()) {\r
135                                 Class<? extends Annotation> annotationType = annotation.annotationType();\r
136 \r
137                                  IsGetSetRule tag = \r
138                                  annotationType.getAnnotation(IsGetSetRule.class);\r
139                                  if (tag != null) {\r
140                                          \r
141                                          HasSetter setterAnnType = annotationType.getAnnotation(HasSetter.class);\r
142                                          \r
143                                          Class<? extends Annotation> setterAnn = setterAnnType.value();\r
144                                          \r
145                                          Method getter = m;\r
146                                          \r
147                                          IGetSetRuleFactory<StructuralResource, IStructuralObject> ruleFactory = createGetSetRuleFactory(g, annotation, getter);\r
148                                          \r
149                                          \r
150                                          Method setter = null;\r
151                                          \r
152                                          for (Method m2 : clazz.getDeclaredMethods()) {\r
153                                                  Annotation set = m2.getAnnotation(setterAnn);\r
154                                                  if (set != null && ruleFactory.isSetter(annotation, set))\r
155                                                          setter = m2;\r
156                                          }\r
157 \r
158                                          rules.add(ruleFactory.create(g, annotation, getter, setter));\r
159                                  }\r
160                         \r
161                         }\r
162                 }\r
163                 \r
164                 for (Method m : clazz.getDeclaredMethods()) {\r
165                         m.setAccessible(true);\r
166                         for (Annotation annotation : m.getAnnotations()) {\r
167                                 Class<? extends Annotation> annotationType = annotation.annotationType();\r
168 \r
169                                  IsCollectionRule tag = \r
170                                  annotationType.getAnnotation(IsCollectionRule.class);\r
171                                  if (tag != null) {\r
172                                          \r
173                                          HasCollectionAdder adderAnnType = annotationType.getAnnotation(HasCollectionAdder.class);\r
174                                          HasCollectionRemover removerAnnType = annotationType.getAnnotation(HasCollectionRemover.class);\r
175                         \r
176                                          Class<? extends Annotation> adderAnn = adderAnnType.value();\r
177                                          Class<? extends Annotation> removerAnn = removerAnnType.value();\r
178                                          \r
179                                          Method getter = m;\r
180                                          \r
181                                          ICollectionRuleFactory<StructuralResource, IStructuralObject> ruleFactory = createCollectionRuleFactory(g, annotation, getter);\r
182                                          \r
183                                          \r
184                                          Method adder = null;\r
185                                          Method remover = null;\r
186                                          \r
187                                          for (Method m2 : clazz.getDeclaredMethods()) {\r
188                                                  Annotation add = m2.getAnnotation(adderAnn);\r
189                                                  Annotation rem = m2.getAnnotation(removerAnn);\r
190                                                  if (add != null && ruleFactory.isAdder(annotation, add))\r
191                                                          adder = m2;\r
192                                                  if (rem != null && ruleFactory.isRemover(annotation, rem))\r
193                                                          remover = m2;\r
194                                          }\r
195                                          \r
196                                          \r
197                                          \r
198                                          rules.add(ruleFactory.create(g, annotation, getter,adder,remover));\r
199                                  }\r
200                         \r
201                         }\r
202                 }\r
203             }\r
204                 \r
205                 public static IClassRuleFactory<StructuralResource, IStructuralObject> createClassRule(ReadGraph g, Annotation annotation, Class<?> clazz) {\r
206                         return null;\r
207                 }\r
208                 \r
209                 public static IFieldRuleFactory<StructuralResource, IStructuralObject> createFieldRule(ReadGraph g, Annotation annotation, Field field) {\r
210                         if (annotation.annotationType().equals(RelatedElements.class))\r
211                                 return new RelatedElementsRuleFactory<IStructuralObject>();\r
212                         if (annotation.annotationType().equals(RelatedValue.class))\r
213                                 return new RelatedValueRuleFactory<IStructuralObject>();\r
214                         if (annotation.annotationType().equals(OptionalRelatedElements.class))\r
215                                 return new OptionalRelatedElementsRuleFactory<IStructuralObject>();\r
216                         if (annotation.annotationType().equals(RelatedOrderedSetElements.class))\r
217                                 return new RelatedOrderedSetElementsRuleFactory<IStructuralObject>();\r
218                         return null;\r
219                 }\r
220                 \r
221                 public static IMethodRuleFactory<StructuralResource, IStructuralObject> createMethodRule(ReadGraph g, Annotation annotation, Method m) {\r
222                         if (annotation.annotationType().equals(UpdateMethod.class))\r
223                                 return new UpdateMethodFactory<StructuralResource,IStructuralObject>();\r
224                         return null;\r
225                 }\r
226                 \r
227                 public static IGetSetRuleFactory<StructuralResource, IStructuralObject> createGetSetRuleFactory(ReadGraph g, Annotation annotation, Method getter) {\r
228                         if (annotation.annotationType().equals(RelatedGetValue.class))\r
229                                 return new RelatedGetSetValueRuleFactory<IStructuralObject>();\r
230                         if (annotation.annotationType().equals(RelatedGetObj.class))\r
231                                 return new RelatedGetSetObjRuleFactory<IStructuralObject>();\r
232                         if (annotation.annotationType().equals(TypeRelatedGetValue.class))\r
233                                 return new TypeRelatedGetSetValueRuleFactory<IStructuralObject>();\r
234                         if (annotation.annotationType().equals(TypeRelatedGetObj.class))\r
235                                 return new TypeRelatedGetSetObjRuleFactory<IStructuralObject>();\r
236                         if (annotation.annotationType().equals(StructuralRelatedGetObj.class))\r
237                                 return new StructuralRelatedGetSetObjRuleFactory<IStructuralObject>();\r
238                         return null;\r
239                 }\r
240                 \r
241                 public static ICollectionRuleFactory<StructuralResource, IStructuralObject> createCollectionRuleFactory(ReadGraph g, Annotation annotation, Method getter) {\r
242                         if (annotation.annotationType().equals(RelatedElementsGet.class))\r
243                                 return new RelatedElementsRuleFactory2<IStructuralObject>();\r
244                         if (annotation.annotationType().equals(TypeRelatedElementsGet.class))\r
245                                 return new TypeRelatedElementsRuleFactory2<IStructuralObject>();\r
246                         if (annotation.annotationType().equals(StructuralRelatedElementsGet.class))\r
247                                 return new StructuralRelatedElementsRuleFactory2<IStructuralObject>();\r
248                         return null;\r
249                 }\r
250         \r
251         \r
252         /**\r
253      * Creates a new SimpleLinkType based on the annotations in the given class.\r
254      * @throws IllegalAccessException \r
255      * @throws InstantiationException \r
256      * @see GraphType\r
257      * @see RelatedValue\r
258      */\r
259         public static AdaptedLinkType fromAdaptable(ReadGraph g, String type, Class<?> clazz) throws DatabaseException, InstantiationException, IllegalAccessException {\r
260             \r
261             \r
262             return new AdaptedLinkType(g.getResource(type), clazz);    \r
263         }\r
264         \r
265         \r
266 }\r