]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/canvas/impl/DependencyReflection.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / canvas / impl / DependencyReflection.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.g2d.canvas.impl;\r
13 \r
14 import java.lang.annotation.ElementType;\r
15 import java.lang.annotation.Retention;\r
16 import java.lang.annotation.RetentionPolicy;\r
17 import java.lang.annotation.Target;\r
18 import java.lang.reflect.Field;\r
19 import java.util.ArrayList;\r
20 import java.util.Collection;\r
21 import java.util.List;\r
22 \r
23 import org.simantics.g2d.canvas.ICanvasParticipant;\r
24 import org.simantics.g2d.diagram.handler.DiagramHandler;\r
25 \r
26 /**\r
27  * @author Toni Kalajainen\r
28  */\r
29 public class DependencyReflection {\r
30 \r
31         private final static ReferenceDefinition[] EMPTY = new ReferenceDefinition[0]; \r
32         \r
33         @Retention(RetentionPolicy.RUNTIME)\r
34         @Target(ElementType.FIELD)\r
35         public static @interface Dependency {}\r
36         @Retention(RetentionPolicy.RUNTIME)\r
37         @Target(ElementType.FIELD)\r
38         public static @interface Reference {}\r
39         \r
40         /**\r
41          * Scans an object with reflection for all dependencies \r
42          * <p>\r
43          * Example:\r
44          * \r
45          * @Dependency\r
46          * ViewportInteractor vi;\r
47          * \r
48          * @param obj object to scan\r
49          * @return an array of painters and their priorities\r
50          */\r
51         public static ReferenceDefinition[] getDependencies(final Object obj, ReferenceType type)\r
52         {\r
53                 List<ReferenceDefinition> result = new ArrayList<ReferenceDefinition>();\r
54                 Class<?> clazz = obj.getClass();\r
55                 _addDependencies(clazz, result, type);\r
56                 //if (result==null) return EMPTY;\r
57                 return result.toArray(EMPTY);\r
58         }\r
59 \r
60     private static void _addDependencies(Class<?> clazz, Collection<ReferenceDefinition> result, ReferenceType type)\r
61         {\r
62                 for (final Field f : clazz.getDeclaredFields()) {\r
63                         Class<?> c = f.getType();\r
64                         Dependency dep = (Dependency) f.getAnnotation(Dependency.class);\r
65                         Reference ref = (Reference) f.getAnnotation(Reference.class);\r
66                         if (dep==null && ref==null) continue;\r
67                         ReferenceType referenceType = null;                     \r
68                         if ( ICanvasParticipant.class.isAssignableFrom( c ) )\r
69                                 referenceType = ReferenceType.CanvasParticipant;\r
70                         else if ( DiagramHandler.class.isAssignableFrom( c ) )\r
71                                 referenceType = ReferenceType.DiagramHandler;\r
72                         else assert(false);\r
73                         if (referenceType!=type) continue;\r
74                         \r
75                         assert(!(dep!=null && ref!=null));\r
76                         ReferenceDefinition rd = new ReferenceDefinition();\r
77                         rd.dependency = dep!=null;\r
78                         rd.field = f;\r
79                         rd.requirement = c;\r
80                         rd.referenceType = referenceType;\r
81                         \r
82                         f.setAccessible(true);\r
83                         result.add(rd);\r
84                 }\r
85                 Class<?> superClass = clazz.getSuperclass();\r
86                 if (superClass!=null)\r
87                         _addDependencies(superClass, result, type);\r
88         }\r
89         \r
90         public final static class ReferenceDefinition {\r
91                 public Class<?> requirement;\r
92                 public Field field;\r
93                 public boolean dependency;\r
94                 public ReferenceType referenceType; \r
95         }       \r
96         \r
97         public static enum ReferenceType {\r
98                 CanvasParticipant, DiagramHandler\r
99         }\r
100         \r
101 }\r