]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/handler/ElementAssortment.java
(refs #7595) Started SCL/Reflection module
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / handler / ElementAssortment.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.handler;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.EnumSet;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Set;
20
21 import org.simantics.g2d.connection.handler.ConnectionHandler;
22 import org.simantics.g2d.element.ElementClass;
23 import org.simantics.g2d.element.IElement;
24 import org.simantics.g2d.element.handler.BendsHandler;
25 import org.simantics.g2d.element.handler.TerminalTopology;
26 import org.simantics.g2d.elementclass.BranchPoint;
27 import org.simantics.g2d.elementclass.FlagHandler;
28 import org.simantics.g2d.elementclass.MonitorHandler;
29 import org.simantics.g2d.elementclass.NonCopyable;
30 import org.simantics.g2d.elementclass.ReferenceElement;
31
32 /**
33  * @author Tuukka Lehtonen
34  */
35 public class ElementAssortment implements IElementAssortment {
36
37     public Set<IElement>        all;
38
39     public final List<IElement> nodeList     = new ArrayList<IElement>();
40     public final Set<IElement>  nodes        = new HashSet<IElement>();
41     public final Set<IElement>  connections  = new HashSet<IElement>();
42     public final Set<IElement>  edges        = new HashSet<IElement>();
43     public final Set<IElement>  branchPoints = new HashSet<IElement>();
44     public final Set<IElement>  flags        = new HashSet<IElement>();
45     public final Set<IElement>  references   = new HashSet<IElement>();
46     public final Set<IElement>  monitors     = new HashSet<IElement>();
47     public final Set<IElement>  others       = new HashSet<IElement>();
48     public final Set<IElement>  noncopyables = new HashSet<IElement>();
49
50     EnumSet<ElementType>        contents;
51
52     /**
53      * @param set all the elements to initially sort out. This object assumes
54      *        ownership of the set.
55      */
56     public ElementAssortment(Set<IElement> set) {
57         if (set == null)
58             throw new IllegalArgumentException("null element set");
59         this.all = new HashSet<IElement>(set);
60         sort(set);
61     }
62
63     private void sort(Set<IElement> set) {
64         EnumSet<ElementType> es = EnumSet.noneOf(ElementType.class);
65         contents = es;
66         for (IElement el : set) {
67             ElementClass ec = el.getElementClass();
68             NonCopyable nc = ec.getAtMostOneItemOfClass(NonCopyable.class);
69             ReferenceElement re = ec.getAtMostOneItemOfClass(ReferenceElement.class);
70             MonitorHandler mh = ec.getAtMostOneItemOfClass(MonitorHandler.class);
71             FlagHandler fh = ec.getAtMostOneItemOfClass(FlagHandler.class);
72             TerminalTopology tt = ec.getAtMostOneItemOfClass(TerminalTopology.class);
73             BendsHandler bh = ec.getAtMostOneItemOfClass(BendsHandler.class);
74             BranchPoint bp = ec.getAtMostOneItemOfClass(BranchPoint.class);
75             ConnectionHandler ch = ec.getAtMostOneItemOfClass(ConnectionHandler.class);
76             if (nc != null) {
77                 noncopyables.add(el);
78                 es.add(ElementType.NonCopyable);
79                 // Don't count inherently non-copyables in "all" elements.
80                 all.remove(el);
81             } else if (mh != null) {
82                 monitors.add(el);
83                 es.add(ElementType.Monitor);
84             } else if (re != null) {
85                 references.add(el);
86                 es.add(ElementType.Reference);
87             } else if (fh != null) {
88                 flags.add(el);
89                 es.add(ElementType.Flag);
90             } else if (ch != null) {
91                 connections.add(el);
92                 es.add(ElementType.Connection);
93             } else if (bp != null) {
94                 branchPoints.add(el);
95                 es.add(ElementType.BranchPoint);
96             } else if (tt != null) {
97                 nodes.add(el);
98                 nodeList.add(el);
99                 es.add(ElementType.Node);
100             } else if (bh != null) {
101                 edges.add(el);
102                 es.add(ElementType.Edge);
103             } else {
104                 others.add(el);
105                 es.add(ElementType.Other);
106             }
107         }
108     }
109
110     public Set<IElement> getAll() {
111         return new HashSet<IElement>(all);
112     }
113
114     public boolean contains(ElementType et) {
115         return contents.contains(et);
116     }
117
118     public boolean contains(Collection<ElementType> ets) {
119         return contents.containsAll(ets);
120     }
121
122     public boolean containsAny(Collection<ElementType> ets) {
123         for (ElementType et : ets)
124             if (contents.contains(et))
125                 return true;
126         return false;
127     }
128
129     @Override
130     public int count(ElementType et) {
131         switch (et) {
132             case BranchPoint: return branchPoints.size();
133             case Connection: return connections.size();
134             case Edge: return edges.size();
135             case Flag: return flags.size();
136             case Monitor: return monitors.size();
137             case Reference: return references.size();
138             case Node: return nodes.size();
139             case Other: return others.size();
140             case NonCopyable: return noncopyables.size();
141             default: return 0;
142         }
143     }
144
145     boolean add(ElementType et) {
146         return contents.add(et);
147     }
148
149     boolean remove(ElementType et) {
150         return contents.remove(et);
151     }
152
153     private boolean addType(Set<IElement> set, IElement e, ElementType et) {
154         if (all.add(e)) {
155             boolean ret = set.add(e);
156             if (ret)
157                 contents.add(et);
158             return ret;
159         }
160         return false;
161     }
162
163     private boolean removeType(Set<IElement> set, IElement e, ElementType et) {
164         if (all.remove(e)) {
165             boolean ret = set.remove(e);
166             if (set.isEmpty())
167                 contents.remove(et);
168             return ret;
169         }
170         return false;
171     }
172
173     private int removeAllType(Set<IElement> set, Collection<IElement> es, ElementType et) {
174         int result = 0;
175         for (IElement e : es)
176             if (removeType(set, e, et))
177                 ++result;
178         return result;
179     }
180
181     private int clearType(Set<IElement> set, ElementType et) {
182         int ret = set.size();
183         all.removeAll(set);
184         contents.remove(et);
185         return ret;
186     }
187
188     public int clear(ElementType et) {
189         switch (et) {
190             case BranchPoint: return clearType(branchPoints, et);
191             case Connection: return clearType(connections, et);
192             case Edge: return clearType(edges, et);
193             case Flag: return clearType(flags, et);
194             case Monitor: return clearType(monitors, et);
195             case Reference: return clearType(references, et);
196             case Node: return clearType(nodes, et);
197             case Other: return clearType(others, et);
198             case NonCopyable: return clearType(noncopyables, et);
199             default: return 0;
200         }
201     }
202
203     public boolean add(ElementType et, IElement e) {
204         switch (et) {
205             case BranchPoint: return addType(branchPoints, e, et);
206             case Connection: return addType(connections, e, et);
207             case Edge: return addType(edges, e, et);
208             case Flag: return addType(flags, e, et);
209             case Monitor: return addType(monitors, e, et);
210             case Reference: return addType(references, e, et);
211             case Node: return addType(nodes, e, et);
212             case Other: return addType(others, e, et);
213             case NonCopyable: return addType(noncopyables, e, et);
214             default: return false;
215         }
216     }
217
218     boolean remove(ElementType et, IElement e) {
219         switch (et) {
220             case BranchPoint: return removeType(branchPoints, e, et);
221             case Connection: return removeType(connections, e, et);
222             case Edge: return removeType(edges, e, et);
223             case Flag: return removeType(flags, e, et);
224             case Monitor: return removeType(monitors, e, et);
225             case Reference: return removeType(references, e, et);
226             case Node: return removeType(nodes, e, et);
227             case Other: return removeType(others, e, et);
228             case NonCopyable: return removeType(noncopyables, e, et);
229             default: return false;
230         }
231     }
232
233     public int removeAll(ElementType et, Collection<IElement> es) {
234         if (es.isEmpty())
235            return 0;
236         switch (et) {
237             case BranchPoint: return removeAllType(branchPoints, es, et);
238             case Connection: return removeAllType(connections, es, et);
239             case Edge: return removeAllType(edges, es, et);
240             case Flag: return removeAllType(flags, es, et);
241             case Monitor: return removeAllType(monitors, es, et);
242             case Reference: return removeAllType(references, es, et);
243             case Node: return removeAllType(nodes, es, et);
244             case Other: return removeAllType(others, es, et);
245             case NonCopyable: return removeAllType(noncopyables, es, et);
246             default: return 0;
247         }
248     }
249
250     @Override
251     public String toString() {
252         StringBuilder b = new StringBuilder();
253         b.append("ElementAssortment:\n");
254         b.append("\t CONTAINS: ");
255         b.append(contents);
256         b.append("\n");
257         for(IElement e : nodes) b.append("\t-node " + e + "\n");
258         for(IElement e : connections) b.append("\t-connection " + e + "\n");
259         for(IElement e : edges) b.append("\t-edge " + e + "\n");
260         for(IElement e : branchPoints) b.append("\t-branch " + e + "\n");
261         for(IElement e : flags) b.append("\t-flag " + e + "\n");
262         for(IElement e : references) b.append("\t-reference " + e + "\n");
263         for(IElement e : monitors) b.append("\t-monitor " + e + "\n");
264         for(IElement e : others) b.append("\t-other " + e + "\n");
265         for(IElement e : noncopyables) b.append("\t-non-copyable " + e + "\n");
266         return b.toString();
267     }
268
269     public boolean isEmpty() {
270         return all.isEmpty();
271     }
272
273 }