--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.diagram.handler;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.content.EdgeResource;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.modeling.ModelingResources;\r
+\r
+/**\r
+ * An element assortment is used to categorize diagram contents in diagram\r
+ * cut-copy-paste operations.\r
+ * \r
+ * <p>\r
+ * This version of {@link ElementAssortment} contains only the back-end objects\r
+ * (see {@link ElementHints#KEY_OBJECT}) of IElement instances instead of the\r
+ * IElement instances themselves. This version doesn't have the dependency on\r
+ * the diagram runtime model that {@link ElementAssortment} has. This object can\r
+ * be used even if the diagram runtime model and its elements are disposed.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ElementObjectAssortment implements IElementAssortment {\r
+\r
+ private EnumSet<ElementType> contents;\r
+\r
+ public Set<Object> all;\r
+\r
+ public final List<Resource> nodeList = new ArrayList<Resource>();\r
+ public final Set<Resource> nodes = new HashSet<Resource>();\r
+ public final Set<Resource> connections = new HashSet<Resource>();\r
+ public final Set<EdgeResource> edges = new HashSet<EdgeResource>();\r
+ public final Set<Resource> branchPoints = new HashSet<Resource>();\r
+ public final Set<Resource> flags = new HashSet<Resource>();\r
+ public final Set<Resource> references = new HashSet<Resource>();\r
+ public final Set<Resource> monitors = new HashSet<Resource>();\r
+ public final Set<Resource> others = new HashSet<Resource>();\r
+ public final Set<Object> noncopyables = new HashSet<Object>();\r
+\r
+ public ElementObjectAssortment(ReadGraph graph, Collection<Resource> elements) throws DatabaseException {\r
+ all = new HashSet<Object>(elements); \r
+ contents = EnumSet.noneOf(ElementType.class);\r
+ sort(graph, elements);\r
+ }\r
+\r
+ private void sort(ReadGraph graph, Collection<Resource> elements) throws DatabaseException {\r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+ ModelingResources MOD = ModelingResources.getInstance(graph);\r
+ for (Resource element : elements) {\r
+ if (graph.isInstanceOf(element, DIA.Flag)) {\r
+ flags.add(element);\r
+ contents.add(ElementType.Flag);\r
+ } else if (graph.isInstanceOf(element, DIA.Connection)) {\r
+ connections.add(element);\r
+ contents.add(ElementType.Connection);\r
+ } else if (graph.isInstanceOf(element, DIA.Monitor)) {\r
+ monitors.add(element);\r
+ contents.add(ElementType.Monitor);\r
+ } else if (graph.isInstanceOf(element, MOD.ReferenceElement)) {\r
+ references.add(element);\r
+ contents.add(ElementType.Reference);\r
+ } else if (graph.isInstanceOf(element, DIA.DefinedElement)) {\r
+ nodeList.add(element);\r
+ nodes.add(element);\r
+ contents.add(ElementType.Node);\r
+ } else if (graph.isInstanceOf(element, DIA.Element)) {\r
+ others.add(element);\r
+ contents.add(ElementType.Other);\r
+ } \r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param set all the elements to initially sort out. This object assumes\r
+ * ownership of the set.\r
+ */\r
+ public static ElementObjectAssortment fromElements(Set<IElement> set) {\r
+ return new ElementObjectAssortment( new ElementAssortment( set ) );\r
+ }\r
+\r
+ /**\r
+ * @param set all the elements to initially sort out. This object assumes\r
+ * ownership of the set.\r
+ */\r
+ public ElementObjectAssortment(ElementAssortment assortment) {\r
+ if (assortment == null)\r
+ throw new IllegalArgumentException("null element assortment");\r
+ load(assortment);\r
+ }\r
+\r
+ private void load(ElementAssortment es) {\r
+ this.contents = es.contents;\r
+ this.all = getElementObjectSet(es.all, Object.class);\r
+ getElementObjects(es.nodeList, Resource.class, this.nodeList);\r
+ getElementObjects(es.nodes, Resource.class, this.nodes);\r
+ getElementObjects(es.connections, Resource.class, this.connections);\r
+ getElementObjects(es.connections, Resource.class, this.connections);\r
+ getElementObjects(es.edges, EdgeResource.class, this.edges);\r
+ getElementObjects(es.branchPoints, Resource.class, this.branchPoints);\r
+ getElementObjects(es.flags, Resource.class, this.flags);\r
+ getElementObjects(es.references, Resource.class, this.references);\r
+ getElementObjects(es.monitors, Resource.class, this.monitors);\r
+ getElementObjects(es.others, Resource.class, this.others);\r
+ getElementObjects(es.noncopyables, Object.class, this.noncopyables);\r
+ }\r
+\r
+ public Set<Object> getAll() {\r
+ return new HashSet<Object>(all);\r
+ }\r
+\r
+ public boolean contains(ElementType et) {\r
+ return contents.contains(et);\r
+ }\r
+\r
+ public boolean contains(Collection<ElementType> ets) {\r
+ return contents.containsAll(ets);\r
+ }\r
+\r
+ public boolean containsAny(Collection<ElementType> ets) {\r
+ for (ElementType et : ets)\r
+ if (contents.contains(et))\r
+ return true;\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public int count(ElementType et) {\r
+ switch (et) {\r
+ case BranchPoint: return branchPoints.size();\r
+ case Connection: return connections.size();\r
+ case Edge: return edges.size();\r
+ case Flag: return flags.size();\r
+ case Reference: return references.size();\r
+ case Monitor: return monitors.size();\r
+ case Node: return nodes.size();\r
+ case Other: return others.size();\r
+ case NonCopyable: return noncopyables.size();\r
+ default: return 0;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuilder b = new StringBuilder();\r
+ b.append("ElementObjectAssortment:\n");\r
+ b.append("\t CONTAINS: ");\r
+ b.append(contents);\r
+ b.append("\n");\r
+ for(Resource e : nodes) b.append("\t-node " + e + "\n");\r
+ for(Resource e : connections) b.append("\t-connection " + e + "\n");\r
+ for(EdgeResource e : edges) b.append("\t-edge " + e + "\n");\r
+ for(Resource e : branchPoints) b.append("\t-branch " + e + "\n");\r
+ for(Resource e : flags) b.append("\t-flag " + e + "\n");\r
+ for(Resource e : references) b.append("\t-reference " + e + "\n");\r
+ for(Resource e : monitors) b.append("\t-monitor " + e + "\n");\r
+ for(Object e : others) b.append("\t-other " + e + "\n");\r
+ for(Object e : noncopyables) b.append("\t-non-copyable " + e + "\n");\r
+ return b.toString();\r
+ }\r
+\r
+ public boolean isEmpty() {\r
+ return all.isEmpty();\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public static <T> Collection<T> getElementObjects(Collection<IElement> elements, Class<T> clazz, Collection<T> result) {\r
+ for (IElement e : elements) {\r
+ Object o = ElementUtils.getObject(e);\r
+ if (clazz.isInstance(o))\r
+ result.add((T) o);\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public static <T> Set<T> getElementObjectSet(Collection<IElement> elements, Class<T> clazz) {\r
+ Set<T> result = new HashSet<T>();\r
+ getElementObjects(elements, clazz, result);\r
+ return result;\r
+ }\r
+\r
+}\r