]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/objmap/schema/MappingSchemas.java
Copyrights
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / objmap / 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.g3d.objmap.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.g3d.objmap.annotations.HasCollectionAdder;\r
23 import org.simantics.g3d.objmap.annotations.HasCollectionRemover;\r
24 import org.simantics.g3d.objmap.annotations.HasCollectionRuleFactory;\r
25 import org.simantics.g3d.objmap.annotations.HasGetSetRuleFactory;\r
26 import org.simantics.g3d.objmap.annotations.HasSetter;\r
27 import org.simantics.g3d.objmap.rules.factory.ICollectionRuleFactory;\r
28 import org.simantics.g3d.objmap.rules.factory.IGetSetRuleFactory;\r
29 import org.simantics.objmap.ILinkType;\r
30 import org.simantics.objmap.IMappingRule;\r
31 import org.simantics.objmap.annotations.GraphType;\r
32 import org.simantics.objmap.annotations.RelatedValue;\r
33 import org.simantics.objmap.annotations.meta.HasClassRuleFactory;\r
34 import org.simantics.objmap.annotations.meta.HasFieldRuleFactory;\r
35 import org.simantics.objmap.annotations.meta.HasMethodRuleFactory;\r
36 import org.simantics.objmap.schema.SimpleLinkType;\r
37 \r
38 public class MappingSchemas {\r
39         /**\r
40      * Creates a new SimpleLinkType based on the annotations in the given class.\r
41      * @throws IllegalAccessException \r
42      * @throws InstantiationException \r
43      * @see GraphType\r
44      * @see RelatedValue\r
45      */\r
46         public static SimpleLinkType fromAnnotations(ReadGraph g, Class<?> clazz) throws DatabaseException, InstantiationException, IllegalAccessException {\r
47             GraphType graphType = clazz.getAnnotation(GraphType.class);\r
48             \r
49             ArrayList<IMappingRule> rules = new ArrayList<IMappingRule>();\r
50             collectRulesFromAnnotations(g, clazz, rules);\r
51             \r
52             return new SimpleLinkType(\r
53                     g.getResource(graphType.value()), \r
54                 clazz, rules);    \r
55         }\r
56         \r
57         public static void collectRulesFromAnnotations(ReadGraph g, Class<?> clazz, Collection<IMappingRule> rules) throws DatabaseException, InstantiationException, IllegalAccessException {\r
58             Class<?> superclass = clazz.getSuperclass();\r
59             if(superclass != null)\r
60                 collectRulesFromAnnotations(g, superclass, rules);\r
61                 \r
62         for(Annotation annotation : clazz.getAnnotations()) {\r
63             HasClassRuleFactory factory = \r
64                 annotation.annotationType().getAnnotation(HasClassRuleFactory.class);\r
65             if(factory != null) {\r
66                 rules.add(factory.value().newInstance()\r
67                         .create(g, annotation, clazz));\r
68             }\r
69         }\r
70 \r
71         for(Field f : clazz.getDeclaredFields()) {\r
72             f.setAccessible(true);\r
73 \r
74             for(Annotation annotation : f.getAnnotations()) {\r
75                 HasFieldRuleFactory factory = \r
76                     annotation.annotationType().getAnnotation(HasFieldRuleFactory.class);\r
77                 if(factory != null) {\r
78                     rules.add(factory.value().newInstance()\r
79                             .create(g, annotation, f));\r
80                 }\r
81             }\r
82         }\r
83 \r
84         for(Method m : clazz.getDeclaredMethods()) {\r
85             m.setAccessible(true);\r
86 \r
87             for(Annotation annotation : m.getAnnotations()) {\r
88                 HasMethodRuleFactory factory = \r
89                     annotation.annotationType().getAnnotation(HasMethodRuleFactory.class);\r
90                 if(factory != null) {\r
91                         rules.add(factory.value().newInstance().create(g, annotation, m));\r
92                 }\r
93             }\r
94         }\r
95         \r
96         for (Method m : clazz.getDeclaredMethods()) {\r
97                 m.setAccessible(true);\r
98                 for (Annotation annotation : m.getAnnotations()) {\r
99                         Class<? extends Annotation> annotationType = annotation.annotationType();\r
100                          HasGetSetRuleFactory factory = \r
101                          annotationType.getAnnotation(HasGetSetRuleFactory.class);\r
102                          if (factory != null) {\r
103                                  \r
104                                  HasSetter setterAnnType = annotationType.getAnnotation(HasSetter.class);\r
105                                  \r
106                                  Class<? extends Annotation> setterAnn = setterAnnType.value();\r
107                                  \r
108                                  IGetSetRuleFactory ruleFactory = factory.value().newInstance();\r
109                                  \r
110                                  Method getter = m;\r
111                                  Method setter = null;\r
112                                  \r
113                                  for (Method m2 : clazz.getDeclaredMethods()) {\r
114                                          Annotation set = m2.getAnnotation(setterAnn);\r
115                                          if (set != null && ruleFactory.isSetter(annotation, set))\r
116                                                  setter = m2;\r
117                                  }\r
118 \r
119                                  rules.add(ruleFactory.create(g, annotation, getter, setter));\r
120                          }\r
121                 \r
122                 }\r
123         }\r
124         \r
125         for (Method m : clazz.getDeclaredMethods()) {\r
126                 m.setAccessible(true);\r
127                 for (Annotation annotation : m.getAnnotations()) {\r
128                         Class<? extends Annotation> annotationType = annotation.annotationType();\r
129                          HasCollectionRuleFactory factory = \r
130                          annotationType.getAnnotation(HasCollectionRuleFactory.class);\r
131                          if (factory != null) {\r
132                                  \r
133                                  HasCollectionAdder adderAnnType = annotationType.getAnnotation(HasCollectionAdder.class);\r
134                                  HasCollectionRemover removerAnnType = annotationType.getAnnotation(HasCollectionRemover.class);\r
135                 \r
136                                  Class<? extends Annotation> adderAnn = adderAnnType.value();\r
137                                  Class<? extends Annotation> removerAnn = removerAnnType.value();\r
138                                  \r
139                                  ICollectionRuleFactory ruleFactory = factory.value().newInstance();\r
140                                  \r
141                                  Method getter = m;\r
142                                  Method adder = null;\r
143                                  Method remover = null;\r
144                                  \r
145                                  for (Method m2 : clazz.getDeclaredMethods()) {\r
146                                          Annotation add = m2.getAnnotation(adderAnn);\r
147                                          Annotation rem = m2.getAnnotation(removerAnn);\r
148                                          if (add != null && ruleFactory.isAdder(annotation, add))\r
149                                                  adder = m2;\r
150                                          if (rem != null && ruleFactory.isRemover(annotation, rem))\r
151                                                  remover = m2;\r
152                                  }\r
153                                  \r
154                                  \r
155                                  \r
156                                  rules.add(ruleFactory.create(g, annotation, getter,adder,remover));\r
157                          }\r
158                 \r
159                 }\r
160         }\r
161     }\r
162         \r
163         /**\r
164      * Creates a new SimpleLinkType based on the annotations in the given class.\r
165      * @throws IllegalAccessException \r
166      * @throws InstantiationException \r
167      * @see GraphType\r
168      * @see RelatedValue\r
169      */\r
170         public static AdaptedLinkType fromAdaptable(ReadGraph g, String type, Class<?> clazz) throws DatabaseException, InstantiationException, IllegalAccessException {\r
171             \r
172             \r
173             return new AdaptedLinkType(g.getResource(type), clazz);    \r
174         }\r
175         \r
176         \r
177 }\r