1 package org.simantics.modeling.utils;
\r
3 import gnu.trove.map.hash.THashMap;
\r
4 import gnu.trove.set.hash.THashSet;
\r
6 import java.util.Map;
\r
7 import java.util.Set;
\r
9 import org.simantics.databoard.adapter.AdaptException;
\r
10 import org.simantics.db.Resource;
\r
11 import org.simantics.db.WriteGraph;
\r
12 import org.simantics.db.common.utils.NameUtils;
\r
13 import org.simantics.db.exception.DatabaseException;
\r
14 import org.simantics.layer0.Layer0;
\r
15 import org.simantics.utils.datastructures.map.Tuple;
\r
18 * @author Tuukka Lehtonen
\r
20 public class StructuralModelChanges {
\r
22 @SuppressWarnings("unused")
\r
23 private static final boolean TRACE_REFERENCE_FIXES = false;
\r
25 private Resource model;
\r
26 private THashMap<Resource, Resource> moves = new THashMap<Resource, Resource>();
\r
27 private THashMap<Resource, String> renames = new THashMap<Resource, String>();
\r
28 // private THashMap<Resource, Reference> references = new THashMap<Resource, Reference>();
\r
30 public StructuralModelChanges(Resource model) {
\r
34 public void move(Resource component, Resource target) {
\r
35 moves.put(component, target);
\r
38 public void rename(Resource component, String newName) {
\r
39 renames.put(component, newName);
\r
42 static class Info extends Tuple {
\r
43 public Info(Resource component, String rvi) {
\r
44 super(component, rvi);
\r
46 public Resource getComponent() {
\r
47 return (Resource) getField(0);
\r
49 public String getRvi() {
\r
50 return (String) getField(1);
\r
54 public void apply(final WriteGraph graph) throws DatabaseException {
\r
55 final Layer0 L0 = Layer0.getInstance(graph);
\r
58 loadAllReferences(graph, model, new THashSet<Resource>());
\r
59 } catch (AdaptException e) {
\r
60 throw new DatabaseException(e);
\r
63 // 1. Get information on current state of components that are about to
\r
64 // be modified somehow
\r
65 // Map<Resource, Info> before = getInfo(graph);
\r
67 // 2. Perform modifications
\r
68 for (Map.Entry<Resource, Resource> entry : moves.entrySet()) {
\r
69 Resource component = entry.getKey();
\r
70 Resource target = entry.getValue();
\r
72 for (Resource source : graph.getObjects(component, L0.PartOf))
\r
73 graph.deny(component, L0.PartOf, source);
\r
74 graph.claim(component, L0.PartOf, L0.ConsistsOf, target);
\r
77 for (Map.Entry<Resource, String> entry : renames.entrySet()) {
\r
78 Resource component = entry.getKey();
\r
79 Resource container = graph.getSingleObject(component, L0.PartOf);
\r
80 String freshName = NameUtils.findFreshName(graph, entry.getValue(), container, L0.ConsistsOf, "%s%d");
\r
81 graph.claimLiteral(component, L0.HasName, freshName);
\r
84 // // 3. Get information on the state of modified components after the modifications
\r
85 // Map<Resource, Info> after = getInfo(graph);
\r
86 // Map<String, String> toNewPath = new HashMap<String, String>();
\r
87 // for (Resource component : before.keySet()) {
\r
88 // Info b = before.get(component);
\r
89 // Info a = after.get(component);
\r
90 // toNewPath.put(b.getRvi(), a.getRvi());
\r
93 // 4. Fix all references
\r
95 // for (Reference ref : references.values()) {
\r
96 // for (String beforePath : toNewPath.keySet()) {
\r
97 // if (ref.getRVI().startsWith(beforePath)) {
\r
98 // String afterPath = toNewPath.get(beforePath);
\r
99 // String newRvi = afterPath + ref.getRVI().substring(beforePath.length());
\r
100 // if (TRACE_REFERENCE_FIXES)
\r
101 // System.out.println("FIX REFERENCE: " + ref.getRVI() + " -> " + newRvi);
\r
102 // writeReference(graph, ref.getReferee(), newRvi);
\r
103 // continue next_reference;
\r
109 // private Map<Resource, Info> getInfo(ReadGraph graph) throws DatabaseException {
\r
110 // Map<Resource, Info> state = new THashMap<Resource, Info>();
\r
111 // Set<Resource> modifiedObjects = new THashSet<Resource>();
\r
112 // modifiedObjects.addAll(moves.keySet());
\r
113 // modifiedObjects.addAll(renames.keySet());
\r
114 // for (Resource component : modifiedObjects) {
\r
115 // Variable v = graph.getPossibleAdapter(component, Variable.class);
\r
116 // String rvi = Variables.getPossibleRVI(graph, v);
\r
117 // if (rvi != null) {
\r
118 // state.put(component, new Info(component, rvi));
\r
124 // private String lastChildSegment(String rvi) {
\r
125 // int propIndex = rvi.indexOf(Role.PROPERTY.getIdentifier());
\r
126 // if (propIndex == -1)
\r
127 // propIndex = rvi.length();
\r
128 // int childIndex = rvi.lastIndexOf(Role.CHILD.getIdentifier(), propIndex);
\r
129 // if (childIndex == -1)
\r
131 // return rvi.substring(childIndex);
\r
134 private void loadAllReferences(WriteGraph graph, Resource root, Set<Resource> visited) throws DatabaseException, AdaptException {
\r
135 if (!visited.add(root))
\r
138 // Layer0 L0 = Layer0.getInstance(graph);
\r
139 // ModelingResources MOD = ModelingResources.getInstance(graph);
\r
140 // ChartResource CHART = ChartResource.getInstance(graph);
\r
142 // for (Resource r : graph.getObjects(root, L0.ConsistsOf)) {
\r
143 // if (graph.isInstanceOf(r, MOD.Subscription)) {
\r
144 // loadAllReferences(graph, r, visited);
\r
145 // } else if (graph.isInstanceOf(r, CHART.ChartGroup)) {
\r
146 // loadAllReferences(graph, r, visited);
\r
147 // } else if (graph.isInstanceOf(r, CHART.Chart)) {
\r
148 // loadAllReferences(graph, r, visited);
\r
149 // } else if (graph.isInstanceOf(r, MOD.Subscription_Item)) {
\r
150 //// addPossibleReference(graph, r);
\r
151 // } else if (graph.isInstanceOf(r, CHART.Chart_Item)) {
\r
152 //// addPossibleReference(graph, r);
\r
157 // public Reference addPossibleReference(ReadGraph graph, Resource referee) throws DatabaseException, AdaptException {
\r
158 // Reference r = readPossibleReference(graph, referee);
\r
159 // if (r != null) {
\r
160 // references.put(referee, r);
\r
161 // //System.out.println("FOUND REFERENCE: " + r);
\r
166 // public Reference readPossibleReference(ReadGraph graph, Resource referee) throws DatabaseException, AdaptException {
\r
167 // ModelingResources MOD = ModelingResources.getInstance(graph);
\r
168 // String v = graph.getPossibleRelatedValue(referee, MOD.Subscription_Item_VariableId, Bindings.STRING);
\r
171 // return new Reference(referee, Role.CHILD.getIdentifier() + v);
\r
174 // public void writeReference(WriteGraph graph, Resource referee, String newReference) throws DatabaseException {
\r
175 // if (newReference.startsWith(Role.CHILD.getIdentifier()))
\r
176 // newReference = newReference.substring(Role.CHILD.getIdentifier().length());
\r
177 // ModelingResources MOD = ModelingResources.getInstance(graph);
\r
178 // graph.claimLiteral(referee, MOD.Subscription_Item_VariableId, newReference, Bindings.STRING);
\r
181 static class Reference extends Tuple {
\r
182 public Reference(Resource referee, String rvi) {
\r
183 super(referee, rvi);
\r
185 public Resource getReferee() {
\r
186 return (Resource) getField(0);
\r
188 public String getRVI() {
\r
189 return (String) getField(1);
\r