]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/AbstractDiagramParticipant.java
Sync git svn branch with SVN repository r33269.
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / diagram / participant / AbstractDiagramParticipant.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.diagram.participant;\r
13 \r
14 import java.lang.reflect.Field;\r
15 \r
16 import org.simantics.g2d.canvas.ICanvasContext;\r
17 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;\r
18 import org.simantics.g2d.canvas.impl.DependencyReflection;\r
19 import org.simantics.g2d.canvas.impl.DependencyReflection.ReferenceDefinition;\r
20 import org.simantics.g2d.canvas.impl.DependencyReflection.ReferenceType;\r
21 import org.simantics.g2d.canvas.impl.HintReflection.HintListener;\r
22 import org.simantics.g2d.diagram.DiagramClass;\r
23 import org.simantics.g2d.diagram.DiagramHints;\r
24 import org.simantics.g2d.diagram.IDiagram;\r
25 import org.simantics.g2d.diagram.handler.DiagramHandler;\r
26 import org.simantics.utils.datastructures.hints.IHintObservable;\r
27 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
28 \r
29 /**\r
30  * This is a base implementation for all participants that handle\r
31  * diagram.  \r
32  * \r
33  * Features:\r
34  *  - Overrideable onDiagramSet() method\r
35  *  - diagram -field points to current diagram\r
36  *  - DiagramHandlers accessible with @Dependency and @Reference annotations\r
37  * \r
38  * TODO add Diagram class handler annotations\r
39  * @author Toni Kalajainen\r
40  */\r
41 public class AbstractDiagramParticipant extends AbstractCanvasParticipant {\r
42         \r
43         public IDiagram diagram;\r
44         public DiagramClass clazz;\r
45         protected ReferenceDefinition[] handlerDefs;\r
46         boolean handlerDepsSatisfied = true; \r
47                 \r
48         public AbstractDiagramParticipant() {\r
49                 super();\r
50                 \r
51                 handlerDefs = DependencyReflection.getDependencies(this, ReferenceType.DiagramHandler);         \r
52         }\r
53         \r
54         @HintListener(Class=DiagramHints.class, Field="KEY_DIAGRAM")\r
55         public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
56                 if (oldValue==newValue) return;\r
57                 _setDiagram( (IDiagram) newValue );             \r
58         }\r
59         @HintListener(Class=DiagramHints.class, Field="KEY_DIAGRAM")\r
60         public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
61                 _setDiagram(null);              \r
62         }\r
63 \r
64         @Override\r
65         public void addedToContext(ICanvasContext ctx) {\r
66                 super.addedToContext(ctx);\r
67                 _setDiagram( (IDiagram) ctx.getHintStack().getHint(DiagramHints.KEY_DIAGRAM) );\r
68         }\r
69         \r
70         @Override\r
71         public void removedFromContext(ICanvasContext ctx) {\r
72                 _setDiagram(null);\r
73                 super.removedFromContext(ctx);\r
74         }\r
75         \r
76         @Override\r
77         public void assertDependencies() {\r
78                 super.assertDependencies();\r
79                 assert(diagram!=null);\r
80         }\r
81 \r
82         private void _setDiagram(IDiagram d)\r
83         {\r
84                 IDiagram oldDiagram = this.diagram;\r
85                 this.diagram = d;\r
86                 if (d!=null) clazz = d.getDiagramClass();\r
87                 else clazz=null;\r
88                 \r
89                 if (clazz!=null) {\r
90 \r
91                         try {\r
92                                 for (DiagramHandler h : clazz.getAll()) {\r
93                                         Class<?> c = h.getClass();\r
94                                         for (ReferenceDefinition def : handlerDefs)\r
95                                         {\r
96                                                 Class<?>        defClass = def.requirement;\r
97                                                 if (!defClass.isAssignableFrom(c)) continue;\r
98                                                 Field           f = def.field;\r
99                                                 //Object                value = f.get(this);\r
100                                                 //assert(value==null);\r
101                                                 f.set(this, h);\r
102                                         }\r
103                                 }\r
104                         } catch (Exception e) {\r
105                                 throw new RuntimeException(e);\r
106                         }               \r
107                         handlerDepsSatisfied = checkHandlerDependencies();                      \r
108                 } else {\r
109 \r
110                         try {\r
111                                 for (ReferenceDefinition def : handlerDefs)\r
112                                 {\r
113                                         Field           f = def.field;\r
114                                         f.set(this, null);\r
115                                 }\r
116                         } catch (Exception e) {\r
117                                 throw new RuntimeException(e);\r
118                         }               \r
119                         handlerDepsSatisfied = true;\r
120                 }\r
121                 onDiagramSet(this.diagram, oldDiagram);\r
122         }\r
123         \r
124         /**\r
125          * OVERRIDE THIS to hook diagram modifications \r
126          * @param newDiagram new diagram or null\r
127          * @param oldDiagram ..\r
128          */\r
129         protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram)\r
130         {\r
131         }\r
132         \r
133         private boolean checkHandlerDependencies() {\r
134                 try {\r
135                         for (ReferenceDefinition rd : handlerDefs) {\r
136                                 if (!rd.dependency)\r
137                                         continue;\r
138                                 Field f = rd.field;\r
139                                 Object o = f.get(this);\r
140                                 if (o == null)\r
141                                         return false;\r
142                         }\r
143                 } catch (Exception e) {\r
144                         throw new RuntimeException(e);\r
145                 }\r
146                 return true;\r
147         }       \r
148 \r
149         \r
150         \r
151 }\r