1 package org.simantics.modeling.mapping;
\r
3 import java.util.HashMap;
\r
4 import java.util.Map;
\r
6 import org.simantics.databoard.Bindings;
\r
7 import org.simantics.db.ReadGraph;
\r
8 import org.simantics.db.Resource;
\r
9 import org.simantics.db.WriteGraph;
\r
10 import org.simantics.db.WriteOnlyGraph;
\r
11 import org.simantics.db.common.request.FreshEscapedName;
\r
12 import org.simantics.db.common.utils.OrderedSetUtils;
\r
13 import org.simantics.db.exception.DatabaseException;
\r
14 import org.simantics.db.layer0.request.PossibleModel;
\r
15 import org.simantics.diagram.stubs.DiagramResource;
\r
16 import org.simantics.diagram.stubs.G2DResource;
\r
17 import org.simantics.graph.db.IImportAdvisor;
\r
18 import org.simantics.graph.representation.Root;
\r
19 import org.simantics.layer0.Layer0;
\r
20 import org.simantics.modeling.ModelingResources;
\r
23 * ImportAdvisor for handling Component and Element copies.
\r
25 * The advisor can be configured to copy just component or element.
\r
27 * When copying a component, handling the element many vary:
\r
28 * 1. If copied data does not contain element, but the target composite is attached to a diagram, the advisor creates the element.
\r
29 * 2. If copied data contains element, but target composite is not attached to a diagram, the advisor deletes the element.
\r
32 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
35 public class ComponentAndElementPasteImportAdvisor implements IImportAdvisor {
\r
37 private static boolean DEBUG = false;
\r
39 protected Resource element;
\r
40 protected Resource component;
\r
42 protected Root elementRoot;
\r
43 protected Root componentRoot;
\r
45 protected Resource composite;
\r
46 protected Resource diagram;
\r
47 protected Resource model;
\r
49 protected Map<String, String> nameMappings = new HashMap<String, String>();
\r
51 protected boolean includeComponent = true;
\r
52 protected boolean includeElement = true;
\r
54 public ComponentAndElementPasteImportAdvisor(ReadGraph graph, Resource composite) throws DatabaseException{
\r
55 this.composite = composite;
\r
56 this.diagram = graph.getPossibleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram);
\r
57 this.includeElement = diagram != null;
\r
58 this.model = graph.sync(new PossibleModel(composite));
\r
61 public ComponentAndElementPasteImportAdvisor(ReadGraph graph, Resource resource, boolean includeComponent, boolean includeElement) throws DatabaseException{
\r
62 if (!includeComponent && !includeElement)
\r
63 throw new IllegalArgumentException();
\r
65 this.includeComponent = includeComponent;
\r
66 this.includeElement = includeElement;
\r
67 if (includeComponent) {
\r
68 this.composite = resource;
\r
69 this.diagram = graph.getPossibleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram);
\r
70 if (this.diagram == null)
\r
71 this.includeElement = false;
\r
73 this.diagram = resource;
\r
74 this.composite = graph.getPossibleObject(diagram, ModelingResources.getInstance(graph).DiagramToComposite);
\r
80 public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
\r
82 if("%model".equals(root.name)) return model;
\r
84 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
85 String type = root.type;
\r
87 Resource typeRes = graph.getResource(type);
\r
88 if (graph.isInheritedFrom(typeRes, DIA.Element)) {
\r
90 String newName = root.name;
\r
91 if (diagram != null)
\r
92 newName = newName(graph, diagram, root.name);
\r
93 nameMappings.put(root.name, newName);
\r
95 componentRoot = root;
\r
96 String newName = newName(graph, composite, root.name);
\r
97 nameMappings.put(root.name, newName);
\r
104 public String newName(ReadGraph graph, Resource library, String name) throws DatabaseException {
\r
105 return graph.syncRequest(new FreshEscapedName(library, Layer0.getInstance(graph).ConsistsOf, name));
\r
108 public Resource getComponent() {
\r
112 public Resource getElement() {
\r
117 public Resource createRoot(WriteOnlyGraph graph, Root root)
\r
118 throws DatabaseException {
\r
119 Layer0 l0 = graph.getService(Layer0.class);
\r
120 if (root == elementRoot) {
\r
121 element = graph.newResource();
\r
122 String name = root.name;
\r
123 String newName = nameMappings.get(name);
\r
124 graph.addLiteral(element, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING);
\r
125 if (DEBUG) System.out.println("CaECopyAdvisor created element " + element + " " + newName);
\r
127 } else if (root == componentRoot) {
\r
128 component = graph.newResource();
\r
129 String name = root.name;
\r
130 String newName = nameMappings.get(name);
\r
131 graph.addLiteral(component, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING);
\r
132 if (DEBUG) System.out.println("CaECopyAdvisor created component " + component + " " + newName);
\r
135 throw new DatabaseException("Unknown root " + root);
\r
139 * Attaches pasted component / element to composite / diagram
\r
141 * @throws DatabaseException
\r
143 public void attach(WriteGraph graph) throws DatabaseException{
\r
144 Layer0 l0 = Layer0.getInstance(graph);
\r
145 if (includeComponent) {
\r
146 if (component != null)
\r
147 graph.claim(composite, l0.ConsistsOf, l0.PartOf, component);
\r
149 if (component != null)
\r
150 graph.deny(component);
\r
152 if (!includeElement) {
\r
153 // paste target does not need the element.
\r
154 if (element != null) {
\r
155 graph.deny(element);
\r
158 // paste target needs the element.
\r
159 boolean created = false;
\r
160 if (element == null) {
\r
161 // element was not in the copied data, we must create a new one.
\r
163 ModelingResources MR = ModelingResources.getInstance(graph);
\r
164 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
165 G2DResource G2D = G2DResource.getInstance(graph);
\r
167 Resource componentType = graph.getSingleType(component);
\r
168 Resource elementType = graph.getSingleObject(componentType, MR.ComponentTypeToSymbol);
\r
170 element = graph.newResource();
\r
172 String newName = newName(graph, diagram, "element");
\r
173 graph.claimLiteral(element, l0.HasName, newName);
\r
175 graph.claim(element, l0.InstanceOf, elementType);
\r
176 graph.claim(component, MR.ComponentToElement, element);
\r
178 graph.claimLiteral(element, DIA.HasTransform, G2D.Transform, new double[]{1,0,0,1,0,0});
\r
180 if (DEBUG) System.out.println("CaECopyAdvisor created deferred element " + element + " " + newName);
\r
184 graph.claim(diagram, l0.ConsistsOf, l0.PartOf, element);
\r
185 OrderedSetUtils.add(graph, diagram, element);
\r
187 createElement(graph, element);
\r
194 * Callback called, if copied data did not contain element, and the advisor had to create the element by itself.
\r
196 * Note: default implementation does nothing.
\r
200 * @throws DatabaseException
\r
202 public void createElement(WriteGraph graph, Resource element) throws DatabaseException{
\r