1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.diagram.handler;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collection;
\r
16 import java.util.EnumSet;
\r
17 import java.util.HashSet;
\r
18 import java.util.List;
\r
19 import java.util.Set;
\r
21 import org.simantics.db.ReadGraph;
\r
22 import org.simantics.db.Resource;
\r
23 import org.simantics.db.exception.DatabaseException;
\r
24 import org.simantics.diagram.content.EdgeResource;
\r
25 import org.simantics.diagram.stubs.DiagramResource;
\r
26 import org.simantics.g2d.element.ElementHints;
\r
27 import org.simantics.g2d.element.ElementUtils;
\r
28 import org.simantics.g2d.element.IElement;
\r
29 import org.simantics.modeling.ModelingResources;
\r
32 * An element assortment is used to categorize diagram contents in diagram
\r
33 * cut-copy-paste operations.
\r
36 * This version of {@link ElementAssortment} contains only the back-end objects
\r
37 * (see {@link ElementHints#KEY_OBJECT}) of IElement instances instead of the
\r
38 * IElement instances themselves. This version doesn't have the dependency on
\r
39 * the diagram runtime model that {@link ElementAssortment} has. This object can
\r
40 * be used even if the diagram runtime model and its elements are disposed.
\r
42 * @author Tuukka Lehtonen
\r
44 public class ElementObjectAssortment implements IElementAssortment {
\r
46 private EnumSet<ElementType> contents;
\r
48 public Set<Object> all;
\r
50 public final List<Resource> nodeList = new ArrayList<Resource>();
\r
51 public final Set<Resource> nodes = new HashSet<Resource>();
\r
52 public final Set<Resource> connections = new HashSet<Resource>();
\r
53 public final Set<EdgeResource> edges = new HashSet<EdgeResource>();
\r
54 public final Set<Resource> branchPoints = new HashSet<Resource>();
\r
55 public final Set<Resource> flags = new HashSet<Resource>();
\r
56 public final Set<Resource> references = new HashSet<Resource>();
\r
57 public final Set<Resource> monitors = new HashSet<Resource>();
\r
58 public final Set<Resource> others = new HashSet<Resource>();
\r
59 public final Set<Object> noncopyables = new HashSet<Object>();
\r
61 public ElementObjectAssortment(ReadGraph graph, Collection<Resource> elements) throws DatabaseException {
\r
62 all = new HashSet<Object>(elements);
\r
63 contents = EnumSet.noneOf(ElementType.class);
\r
64 sort(graph, elements);
\r
67 private void sort(ReadGraph graph, Collection<Resource> elements) throws DatabaseException {
\r
68 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
69 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
70 for (Resource element : elements) {
\r
71 if (graph.isInstanceOf(element, DIA.Flag)) {
\r
73 contents.add(ElementType.Flag);
\r
74 } else if (graph.isInstanceOf(element, DIA.Connection)) {
\r
75 connections.add(element);
\r
76 contents.add(ElementType.Connection);
\r
77 } else if (graph.isInstanceOf(element, DIA.Monitor)) {
\r
78 monitors.add(element);
\r
79 contents.add(ElementType.Monitor);
\r
80 } else if (graph.isInstanceOf(element, MOD.ReferenceElement)) {
\r
81 references.add(element);
\r
82 contents.add(ElementType.Reference);
\r
83 } else if (graph.isInstanceOf(element, DIA.DefinedElement)) {
\r
84 nodeList.add(element);
\r
86 contents.add(ElementType.Node);
\r
87 } else if (graph.isInstanceOf(element, DIA.Element)) {
\r
88 others.add(element);
\r
89 contents.add(ElementType.Other);
\r
95 * @param set all the elements to initially sort out. This object assumes
\r
96 * ownership of the set.
\r
98 public static ElementObjectAssortment fromElements(Set<IElement> set) {
\r
99 return new ElementObjectAssortment( new ElementAssortment( set ) );
\r
103 * @param set all the elements to initially sort out. This object assumes
\r
104 * ownership of the set.
\r
106 public ElementObjectAssortment(ElementAssortment assortment) {
\r
107 if (assortment == null)
\r
108 throw new IllegalArgumentException("null element assortment");
\r
112 private void load(ElementAssortment es) {
\r
113 this.contents = es.contents;
\r
114 this.all = getElementObjectSet(es.all, Object.class);
\r
115 getElementObjects(es.nodeList, Resource.class, this.nodeList);
\r
116 getElementObjects(es.nodes, Resource.class, this.nodes);
\r
117 getElementObjects(es.connections, Resource.class, this.connections);
\r
118 getElementObjects(es.connections, Resource.class, this.connections);
\r
119 getElementObjects(es.edges, EdgeResource.class, this.edges);
\r
120 getElementObjects(es.branchPoints, Resource.class, this.branchPoints);
\r
121 getElementObjects(es.flags, Resource.class, this.flags);
\r
122 getElementObjects(es.references, Resource.class, this.references);
\r
123 getElementObjects(es.monitors, Resource.class, this.monitors);
\r
124 getElementObjects(es.others, Resource.class, this.others);
\r
125 getElementObjects(es.noncopyables, Object.class, this.noncopyables);
\r
128 public Set<Object> getAll() {
\r
129 return new HashSet<Object>(all);
\r
132 public boolean contains(ElementType et) {
\r
133 return contents.contains(et);
\r
136 public boolean contains(Collection<ElementType> ets) {
\r
137 return contents.containsAll(ets);
\r
140 public boolean containsAny(Collection<ElementType> ets) {
\r
141 for (ElementType et : ets)
\r
142 if (contents.contains(et))
\r
148 public int count(ElementType et) {
\r
150 case BranchPoint: return branchPoints.size();
\r
151 case Connection: return connections.size();
\r
152 case Edge: return edges.size();
\r
153 case Flag: return flags.size();
\r
154 case Reference: return references.size();
\r
155 case Monitor: return monitors.size();
\r
156 case Node: return nodes.size();
\r
157 case Other: return others.size();
\r
158 case NonCopyable: return noncopyables.size();
\r
164 public String toString() {
\r
165 StringBuilder b = new StringBuilder();
\r
166 b.append("ElementObjectAssortment:\n");
\r
167 b.append("\t CONTAINS: ");
\r
168 b.append(contents);
\r
170 for(Resource e : nodes) b.append("\t-node " + e + "\n");
\r
171 for(Resource e : connections) b.append("\t-connection " + e + "\n");
\r
172 for(EdgeResource e : edges) b.append("\t-edge " + e + "\n");
\r
173 for(Resource e : branchPoints) b.append("\t-branch " + e + "\n");
\r
174 for(Resource e : flags) b.append("\t-flag " + e + "\n");
\r
175 for(Resource e : references) b.append("\t-reference " + e + "\n");
\r
176 for(Resource e : monitors) b.append("\t-monitor " + e + "\n");
\r
177 for(Object e : others) b.append("\t-other " + e + "\n");
\r
178 for(Object e : noncopyables) b.append("\t-non-copyable " + e + "\n");
\r
179 return b.toString();
\r
182 public boolean isEmpty() {
\r
183 return all.isEmpty();
\r
186 @SuppressWarnings("unchecked")
\r
187 public static <T> Collection<T> getElementObjects(Collection<IElement> elements, Class<T> clazz, Collection<T> result) {
\r
188 for (IElement e : elements) {
\r
189 Object o = ElementUtils.getObject(e);
\r
190 if (clazz.isInstance(o))
\r
196 public static <T> Set<T> getElementObjectSet(Collection<IElement> elements, Class<T> clazz) {
\r
197 Set<T> result = new HashSet<T>();
\r
198 getElementObjects(elements, clazz, result);
\r