]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/typicals/TypicalDiagramTemplateListener.java
Merge "InputStream returns -1 on EOF instead of throwing IOException"
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / typicals / TypicalDiagramTemplateListener.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2012 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.modeling.typicals;\r
13 \r
14 import gnu.trove.set.hash.THashSet;\r
15 \r
16 import java.util.Map;\r
17 \r
18 import org.simantics.db.MetadataI;\r
19 import org.simantics.db.ReadGraph;\r
20 import org.simantics.db.Resource;\r
21 import org.simantics.db.common.changeset.GenericChangeListener;\r
22 import org.simantics.db.exception.DatabaseException;\r
23 import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest;\r
24 import org.simantics.db.layer0.genericrelation.DependencyChanges;\r
25 import org.simantics.db.layer0.genericrelation.DependencyChanges.Change;\r
26 import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentAddition;\r
27 import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentModification;\r
28 import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentRemoval;\r
29 import org.simantics.diagram.content.ConnectionUtil;\r
30 import org.simantics.diagram.stubs.DiagramResource;\r
31 import org.simantics.layer0.Layer0;\r
32 import org.simantics.modeling.ModelingResources;\r
33 import org.simantics.structural.stubs.StructuralResource2;\r
34 import org.simantics.utils.datastructures.Callback;\r
35 import org.simantics.utils.datastructures.MapSet;\r
36 import org.simantics.utils.ui.ErrorLogger;\r
37 \r
38 /**\r
39  * This listener needs to discover if changes are made to typical diagram\r
40  * templates.\r
41  * \r
42  * It uses DependencyChange contents to find out if the changes affect any\r
43  * dependencies of typical diagram templates.\r
44  * \r
45  * @author Tuukka Lehtonen\r
46  * \r
47  * @see SyncTypicalTemplatesToInstances\r
48  * @deprecated not to be used anymore, will be removed\r
49  */\r
50 public class TypicalDiagramTemplateListener extends GenericChangeListener<DependencyChangesRequest, DependencyChanges> {\r
51 \r
52     private static final boolean   DEBUG = false;\r
53 \r
54     Layer0                         L0;\r
55     StructuralResource2            STR;\r
56     DiagramResource                DIA;\r
57     ModelingResources              MOD;\r
58 \r
59     THashSet<Resource>             visited  = new THashSet<Resource>();\r
60     THashSet<Resource>             typicals = new THashSet<Resource>();\r
61 \r
62     /**\r
63      * For optimizing the synchronization visual element properties (transform)\r
64      */\r
65     MapSet<Resource, Resource>     changedElementsByDiagram = new MapSet.Hash<Resource, Resource>();\r
66 \r
67     @Override\r
68     public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException {\r
69         this.L0 = Layer0.getInstance(graph);\r
70         this.STR = StructuralResource2.getInstance(graph);\r
71         this.DIA = DiagramResource.getInstance(graph);\r
72         this.MOD = ModelingResources.getInstance(graph);\r
73 \r
74         visited.clear();\r
75         typicals.clear();\r
76         try {\r
77             processChanges(graph, event);\r
78         } finally {\r
79             // Clear unwanted references\r
80             visited.clear();\r
81             typicals.clear();\r
82             visited.compact();\r
83         }\r
84     }\r
85 \r
86     private void processChanges(ReadGraph graph, DependencyChanges event) throws DatabaseException {\r
87         for (Map.Entry<Resource, Change[]> entry : event.modelChanges.entrySet()) {\r
88             Change[] changes = entry.getValue();\r
89             if (changes == null)\r
90                 continue;\r
91 \r
92             if (DEBUG)\r
93                 for (Change change : changes)\r
94                     System.out.println("CH: -" + change.toString(graph));\r
95 \r
96             for (Change c : changes) {\r
97                 if (c instanceof ComponentAddition) {\r
98                     // element/module addition\r
99                     ComponentAddition add = (ComponentAddition) c;\r
100                     resolveDependentTypicalDiagrams(graph, add.component, false);\r
101                 } else if (c instanceof ComponentRemoval) {\r
102                     // element/module removal\r
103                     ComponentRemoval rm = (ComponentRemoval) c;\r
104                     resolveDependentTypicalDiagrams(graph, rm.parent, false);\r
105                 } else if (c instanceof ComponentModification) {\r
106                     // element transform changes\r
107                     // module property changes\r
108                     ComponentModification mod = (ComponentModification) c;\r
109                     resolveDependentTypicalDiagrams(graph, mod.component, true);\r
110                 }\r
111             }\r
112         }\r
113 \r
114         if (!typicals.isEmpty())\r
115             scheduleSynchronization(graph, typicals.toArray(Resource.NONE));\r
116     }\r
117 \r
118     private void scheduleSynchronization(ReadGraph graph, final Resource[] templates) {\r
119         MapSet<Resource, Resource> changes = this.changedElementsByDiagram;\r
120         this.changedElementsByDiagram = new MapSet.Hash<Resource, Resource>();\r
121 \r
122         graph.asyncRequest(new SyncTypicalTemplatesToInstances(null, templates, changes), new Callback<DatabaseException>() {\r
123             @Override\r
124             public void run(DatabaseException parameter) {\r
125                 if (parameter != null)\r
126                     ErrorLogger.defaultLogError("Typical template diagram synchronization to instances failes, see exception for details.", parameter);\r
127             }\r
128         });\r
129     }\r
130 \r
131     private void resolveDependentTypicalDiagrams(ReadGraph graph, Resource component, boolean modification) throws DatabaseException {\r
132         if (visited.contains(component))\r
133             return;\r
134 \r
135         if (graph.isInstanceOf(component, DIA.Diagram)) {\r
136             addVisited(component, graph.hasStatement(component, MOD.DiagramHasInstance));\r
137         } else if (graph.isInstanceOf(component, STR.Composite)) {\r
138             Resource diagram = graph.getPossibleObject(component, MOD.CompositeToDiagram);\r
139             addVisited(diagram, diagram != null && graph.hasStatement(diagram, MOD.DiagramHasInstance));\r
140         } else if (graph.isInstanceOf(component, STR.Component)) {\r
141             Resource parent = graph.getPossibleObject(component, L0.PartOf);\r
142             if (parent != null) {\r
143                 if (graph.isInstanceOf(component, DIA.Element)) {\r
144                     addVisited(parent, graph.hasStatement(parent, MOD.DiagramHasInstance));\r
145                     if (modification)\r
146                         changedElementsByDiagram.add(parent, component);\r
147                 } else {\r
148                     Resource diagram = graph.getPossibleObject(parent, MOD.CompositeToDiagram);\r
149                     if (diagram != null) {\r
150                         addVisited(diagram, graph.hasStatement(diagram, MOD.DiagramHasInstance));\r
151                         if (modification) {\r
152                             Resource element = graph.getPossibleObject(component, MOD.ComponentToElement);\r
153                             if (element != null)\r
154                                 changedElementsByDiagram.add(diagram, element);\r
155                         }\r
156                     }\r
157                 }\r
158             }\r
159         } else {\r
160             // handle changes to properties of components/elements ??\r
161         }\r
162 \r
163         if (modification) {\r
164             // Recognize changes in template diagram connections.\r
165             if (graph.isInstanceOf(component, DIA.RouteNode)) {\r
166                 Resource connection = ConnectionUtil.tryGetConnection(graph, component);\r
167                 if (connection != null) {\r
168                     Resource parent = graph.getPossibleObject(connection, L0.PartOf);\r
169                     if (parent != null) {\r
170                         boolean isTypical = graph.hasStatement(parent, MOD.DiagramHasInstance);\r
171                         addVisited(parent, isTypical);\r
172                         if (isTypical)\r
173                             changedElementsByDiagram.add(parent, connection);\r
174                     }\r
175                 }\r
176             }\r
177         }\r
178 \r
179         addVisited(component, false);\r
180     }\r
181 \r
182     private void addVisited(Resource r, boolean isTypical) {\r
183         if (r != null && visited.add(r)) {\r
184             if (DEBUG)\r
185                 System.out.println("Visited: " + r);\r
186             if (isTypical) {\r
187                 typicals.add(r);\r
188                 if (DEBUG)\r
189                     System.out.println("Added typical: " + r);\r
190             }\r
191         }\r
192     }\r
193 \r
194 }\r