--- /dev/null
+package org.simantics.modeling.mapping;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.NamedResource;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;\r
+import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+\r
+\r
+/**\r
+ * Copy handler for Component and it's Element.\r
+ * \r
+ * FIXME: Requires patched ModelTransferableGraphSourceRequest\r
+ * \r
+ * in classifyPredicates(), excluded resources must be filtered. Otherwise the code fails with :Diagram.hasInverse having no URI.\r
+ * \r
+ * Resource predicate = stm.getPredicate();\r
+ * Resource object = stm.getObject(); \r
+ * if (exclusions.contains(object) || exclusions.contains(predicate))\r
+ * continue; \r
+ *\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class ComponentAndElementCopyHandler extends DefaultCopyHandler{\r
+\r
+ protected boolean includeComponent = true;\r
+ protected boolean includeElement = true;\r
+ \r
+ public ComponentAndElementCopyHandler(Resource resource) {\r
+ super(resource);\r
+ }\r
+ \r
+ /**\r
+ * \r
+ * @param resource Component, if component is included. Otherwise the Element.\r
+ * @param includeComponent\r
+ * @param includeElement\r
+ */\r
+ public ComponentAndElementCopyHandler(Resource resource, boolean includeComponent, boolean includeElement) {\r
+ super(resource);\r
+ if (!includeComponent && !includeElement)\r
+ throw new IllegalArgumentException();\r
+ this.includeComponent = includeComponent;\r
+ this.includeElement = includeElement;\r
+ }\r
+ \r
+ \r
+\r
+ \r
+ @Override\r
+ protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {\r
+ ModelingResources MR = ModelingResources.getInstance(graph);\r
+\r
+ ArrayList<Resource> exclusions = new ArrayList<Resource>();\r
+\r
+ ArrayList<NamedResource> roots = new ArrayList<NamedResource>();\r
+ \r
+ Resource component = null;\r
+ Resource element = null;\r
+ \r
+ if (includeComponent) {\r
+ component = getResource();\r
+ element = graph.getPossibleObject(component, MR.ComponentToElement);\r
+ } else {\r
+ element = getResource();\r
+ component = graph.getPossibleObject(element, MR.ElementToComponent);\r
+ }\r
+ // Include component as root\r
+ if (component != null) {\r
+ processComponent(graph, component, includeComponent, roots, exclusions);\r
+ }\r
+ \r
+ if (element != null) {\r
+ processElement(graph, element, includeElement, roots, exclusions);\r
+ }\r
+ \r
+ return TransferableGraphConfiguration2.createWithNames(graph, roots, exclusions, true, false);\r
+ }\r
+ \r
+ protected void processComponent(ReadGraph graph, Resource component, boolean includeComponent, ArrayList<NamedResource> roots, ArrayList<Resource> exclusions) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ StructuralResource2 SR = StructuralResource2.getInstance(graph);\r
+ Resource resource = getResource();\r
+ if (includeComponent) {\r
+ String rootName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);\r
+ roots.add(new NamedResource(rootName, resource));\r
+ } else {\r
+ exclusions.add(component);\r
+ }\r
+\r
+ // filter connections\r
+ for (Resource connection : graph.getObjects(resource, SR.IsConnectedTo))\r
+ exclusions.add(connection);\r
+ }\r
+ \r
+ protected void processElement(ReadGraph graph, Resource element, boolean includeElement, ArrayList<NamedResource> roots, ArrayList<Resource> exclusions) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+ StructuralResource2 SR = StructuralResource2.getInstance(graph);\r
+ \r
+ if (includeElement) {\r
+ // Add element as a root.\r
+ String name = graph.getRelatedValue(element, L0.HasName, Bindings.STRING);\r
+ roots.add(new NamedResource(name, element));\r
+ } else {\r
+ exclusions.add(element);\r
+ }\r
+ \r
+ // exclude diagram from copied data.\r
+ Collection<Resource> diagram_ = OrderedSetUtils.getOwnerLists(graph, element, DIA.Diagram);\r
+ for (Resource diagram : diagram_) {\r
+ \r
+ Resource inv = graph.getInverse(diagram);\r
+ exclusions.add(diagram);\r
+ exclusions.add(inv);\r
+ \r
+ // Exclude next and previous elements in the diagram\r
+ Resource next = OrderedSetUtils.next(graph, diagram, element);\r
+ Resource previous = OrderedSetUtils.prev(graph, diagram, element);\r
+ if (next != null && !next.equals(element))\r
+ exclusions.add(next);\r
+ if (previous != null && !previous.equals(element) && !previous.equals(next))\r
+ exclusions.add(previous);\r
+ }\r
+ // filter connections\r
+ for (Resource connection : graph.getObjects(element, SR.IsConnectedTo))\r
+ exclusions.add(connection);\r
+ }\r
+ \r
+}\r