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