package org.simantics.modeling.utils; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; import java.util.Map; import java.util.Set; import org.simantics.databoard.adapter.AdaptException; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; import org.simantics.utils.datastructures.map.Tuple; /** * @author Tuukka Lehtonen */ public class StructuralModelChanges { @SuppressWarnings("unused") private static final boolean TRACE_REFERENCE_FIXES = false; private Resource model; private THashMap moves = new THashMap(); private THashMap renames = new THashMap(); // private THashMap references = new THashMap(); public StructuralModelChanges(Resource model) { this.model = model; } public void move(Resource component, Resource target) { moves.put(component, target); } public void rename(Resource component, String newName) { renames.put(component, newName); } static class Info extends Tuple { public Info(Resource component, String rvi) { super(component, rvi); } public Resource getComponent() { return (Resource) getField(0); } public String getRvi() { return (String) getField(1); } } public void apply(final WriteGraph graph) throws DatabaseException { final Layer0 L0 = Layer0.getInstance(graph); try { loadAllReferences(graph, model, new THashSet()); } catch (AdaptException e) { throw new DatabaseException(e); } // 1. Get information on current state of components that are about to // be modified somehow // Map before = getInfo(graph); // 2. Perform modifications for (Map.Entry entry : moves.entrySet()) { Resource component = entry.getKey(); Resource target = entry.getValue(); for (Resource source : graph.getObjects(component, L0.PartOf)) graph.deny(component, L0.PartOf, source); graph.claim(component, L0.PartOf, L0.ConsistsOf, target); } for (Map.Entry entry : renames.entrySet()) { Resource component = entry.getKey(); Resource container = graph.getSingleObject(component, L0.PartOf); String freshName = NameUtils.findFreshName(graph, entry.getValue(), container, L0.ConsistsOf, "%s%d"); graph.claimLiteral(component, L0.HasName, freshName); } // // 3. Get information on the state of modified components after the modifications // Map after = getInfo(graph); // Map toNewPath = new HashMap(); // for (Resource component : before.keySet()) { // Info b = before.get(component); // Info a = after.get(component); // toNewPath.put(b.getRvi(), a.getRvi()); // } // 4. Fix all references // next_reference: // for (Reference ref : references.values()) { // for (String beforePath : toNewPath.keySet()) { // if (ref.getRVI().startsWith(beforePath)) { // String afterPath = toNewPath.get(beforePath); // String newRvi = afterPath + ref.getRVI().substring(beforePath.length()); // if (TRACE_REFERENCE_FIXES) // System.out.println("FIX REFERENCE: " + ref.getRVI() + " -> " + newRvi); // writeReference(graph, ref.getReferee(), newRvi); // continue next_reference; // } // } // } } // private Map getInfo(ReadGraph graph) throws DatabaseException { // Map state = new THashMap(); // Set modifiedObjects = new THashSet(); // modifiedObjects.addAll(moves.keySet()); // modifiedObjects.addAll(renames.keySet()); // for (Resource component : modifiedObjects) { // Variable v = graph.getPossibleAdapter(component, Variable.class); // String rvi = Variables.getPossibleRVI(graph, v); // if (rvi != null) { // state.put(component, new Info(component, rvi)); // } // } // return state; // } // private String lastChildSegment(String rvi) { // int propIndex = rvi.indexOf(Role.PROPERTY.getIdentifier()); // if (propIndex == -1) // propIndex = rvi.length(); // int childIndex = rvi.lastIndexOf(Role.CHILD.getIdentifier(), propIndex); // if (childIndex == -1) // return null; // return rvi.substring(childIndex); // } private void loadAllReferences(WriteGraph graph, Resource root, Set visited) throws DatabaseException, AdaptException { if (!visited.add(root)) return; // Layer0 L0 = Layer0.getInstance(graph); // ModelingResources MOD = ModelingResources.getInstance(graph); // ChartResource CHART = ChartResource.getInstance(graph); // for (Resource r : graph.getObjects(root, L0.ConsistsOf)) { // if (graph.isInstanceOf(r, MOD.Subscription)) { // loadAllReferences(graph, r, visited); // } else if (graph.isInstanceOf(r, CHART.ChartGroup)) { // loadAllReferences(graph, r, visited); // } else if (graph.isInstanceOf(r, CHART.Chart)) { // loadAllReferences(graph, r, visited); // } else if (graph.isInstanceOf(r, MOD.Subscription_Item)) { //// addPossibleReference(graph, r); // } else if (graph.isInstanceOf(r, CHART.Chart_Item)) { //// addPossibleReference(graph, r); // } // } } // public Reference addPossibleReference(ReadGraph graph, Resource referee) throws DatabaseException, AdaptException { // Reference r = readPossibleReference(graph, referee); // if (r != null) { // references.put(referee, r); // //System.out.println("FOUND REFERENCE: " + r); // } // return r; // } // public Reference readPossibleReference(ReadGraph graph, Resource referee) throws DatabaseException, AdaptException { // ModelingResources MOD = ModelingResources.getInstance(graph); // String v = graph.getPossibleRelatedValue(referee, MOD.Subscription_Item_VariableId, Bindings.STRING); // if (v == null) // return null; // return new Reference(referee, Role.CHILD.getIdentifier() + v); // } // // public void writeReference(WriteGraph graph, Resource referee, String newReference) throws DatabaseException { // if (newReference.startsWith(Role.CHILD.getIdentifier())) // newReference = newReference.substring(Role.CHILD.getIdentifier().length()); // ModelingResources MOD = ModelingResources.getInstance(graph); // graph.claimLiteral(referee, MOD.Subscription_Item_VariableId, newReference, Bindings.STRING); // } static class Reference extends Tuple { public Reference(Resource referee, String rvi) { super(referee, rvi); } public Resource getReferee() { return (Resource) getField(0); } public String getRVI() { return (String) getField(1); } } }