/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.diagram.handler; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; import org.simantics.g2d.connection.handler.ConnectionHandler; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.handler.BendsHandler; import org.simantics.g2d.element.handler.TerminalTopology; import org.simantics.g2d.elementclass.BranchPoint; import org.simantics.g2d.elementclass.FlagHandler; import org.simantics.g2d.elementclass.MonitorHandler; import org.simantics.g2d.elementclass.NonCopyable; import org.simantics.g2d.elementclass.ReferenceElement; /** * @author Tuukka Lehtonen */ public class ElementAssortment implements IElementAssortment { public Set all; public final List nodeList = new ArrayList(); public final Set nodes = new HashSet(); public final Set connections = new HashSet(); public final Set edges = new HashSet(); public final Set branchPoints = new HashSet(); public final Set flags = new HashSet(); public final Set references = new HashSet(); public final Set monitors = new HashSet(); public final Set others = new HashSet(); public final Set noncopyables = new HashSet(); EnumSet contents; /** * @param set all the elements to initially sort out. This object assumes * ownership of the set. */ public ElementAssortment(Set set) { if (set == null) throw new IllegalArgumentException("null element set"); this.all = new HashSet(set); sort(set); } private void sort(Set set) { EnumSet es = EnumSet.noneOf(ElementType.class); contents = es; for (IElement el : set) { ElementClass ec = el.getElementClass(); NonCopyable nc = ec.getAtMostOneItemOfClass(NonCopyable.class); ReferenceElement re = ec.getAtMostOneItemOfClass(ReferenceElement.class); MonitorHandler mh = ec.getAtMostOneItemOfClass(MonitorHandler.class); FlagHandler fh = ec.getAtMostOneItemOfClass(FlagHandler.class); TerminalTopology tt = ec.getAtMostOneItemOfClass(TerminalTopology.class); BendsHandler bh = ec.getAtMostOneItemOfClass(BendsHandler.class); BranchPoint bp = ec.getAtMostOneItemOfClass(BranchPoint.class); ConnectionHandler ch = ec.getAtMostOneItemOfClass(ConnectionHandler.class); if (nc != null) { noncopyables.add(el); es.add(ElementType.NonCopyable); // Don't count inherently non-copyables in "all" elements. all.remove(el); } else if (mh != null) { monitors.add(el); es.add(ElementType.Monitor); } else if (re != null) { references.add(el); es.add(ElementType.Reference); } else if (fh != null) { flags.add(el); es.add(ElementType.Flag); } else if (ch != null) { connections.add(el); es.add(ElementType.Connection); } else if (bp != null) { branchPoints.add(el); es.add(ElementType.BranchPoint); } else if (tt != null) { nodes.add(el); nodeList.add(el); es.add(ElementType.Node); } else if (bh != null) { edges.add(el); es.add(ElementType.Edge); } else { others.add(el); es.add(ElementType.Other); } } } public Set getAll() { return new HashSet(all); } public boolean contains(ElementType et) { return contents.contains(et); } public boolean contains(Collection ets) { return contents.containsAll(ets); } public boolean containsAny(Collection ets) { for (ElementType et : ets) if (contents.contains(et)) return true; return false; } @Override public int count(ElementType et) { switch (et) { case BranchPoint: return branchPoints.size(); case Connection: return connections.size(); case Edge: return edges.size(); case Flag: return flags.size(); case Monitor: return monitors.size(); case Reference: return references.size(); case Node: return nodes.size(); case Other: return others.size(); case NonCopyable: return noncopyables.size(); default: return 0; } } boolean add(ElementType et) { return contents.add(et); } boolean remove(ElementType et) { return contents.remove(et); } private boolean addType(Set set, IElement e, ElementType et) { if (all.add(e)) { boolean ret = set.add(e); if (ret) contents.add(et); return ret; } return false; } private boolean removeType(Set set, IElement e, ElementType et) { if (all.remove(e)) { boolean ret = set.remove(e); if (set.isEmpty()) contents.remove(et); return ret; } return false; } private int removeAllType(Set set, Collection es, ElementType et) { int result = 0; for (IElement e : es) if (removeType(set, e, et)) ++result; return result; } private int clearType(Set set, ElementType et) { int ret = set.size(); all.removeAll(set); contents.remove(et); return ret; } public int clear(ElementType et) { switch (et) { case BranchPoint: return clearType(branchPoints, et); case Connection: return clearType(connections, et); case Edge: return clearType(edges, et); case Flag: return clearType(flags, et); case Monitor: return clearType(monitors, et); case Reference: return clearType(references, et); case Node: return clearType(nodes, et); case Other: return clearType(others, et); case NonCopyable: return clearType(noncopyables, et); default: return 0; } } public boolean add(ElementType et, IElement e) { switch (et) { case BranchPoint: return addType(branchPoints, e, et); case Connection: return addType(connections, e, et); case Edge: return addType(edges, e, et); case Flag: return addType(flags, e, et); case Monitor: return addType(monitors, e, et); case Reference: return addType(references, e, et); case Node: return addType(nodes, e, et); case Other: return addType(others, e, et); case NonCopyable: return addType(noncopyables, e, et); default: return false; } } boolean remove(ElementType et, IElement e) { switch (et) { case BranchPoint: return removeType(branchPoints, e, et); case Connection: return removeType(connections, e, et); case Edge: return removeType(edges, e, et); case Flag: return removeType(flags, e, et); case Monitor: return removeType(monitors, e, et); case Reference: return removeType(references, e, et); case Node: return removeType(nodes, e, et); case Other: return removeType(others, e, et); case NonCopyable: return removeType(noncopyables, e, et); default: return false; } } public int removeAll(ElementType et, Collection es) { if (es.isEmpty()) return 0; switch (et) { case BranchPoint: return removeAllType(branchPoints, es, et); case Connection: return removeAllType(connections, es, et); case Edge: return removeAllType(edges, es, et); case Flag: return removeAllType(flags, es, et); case Monitor: return removeAllType(monitors, es, et); case Reference: return removeAllType(references, es, et); case Node: return removeAllType(nodes, es, et); case Other: return removeAllType(others, es, et); case NonCopyable: return removeAllType(noncopyables, es, et); default: return 0; } } @Override public String toString() { StringBuilder b = new StringBuilder(); b.append("ElementAssortment:\n"); b.append("\t CONTAINS: "); b.append(contents); b.append("\n"); for(IElement e : nodes) b.append("\t-node " + e + "\n"); for(IElement e : connections) b.append("\t-connection " + e + "\n"); for(IElement e : edges) b.append("\t-edge " + e + "\n"); for(IElement e : branchPoints) b.append("\t-branch " + e + "\n"); for(IElement e : flags) b.append("\t-flag " + e + "\n"); for(IElement e : references) b.append("\t-reference " + e + "\n"); for(IElement e : monitors) b.append("\t-monitor " + e + "\n"); for(IElement e : others) b.append("\t-other " + e + "\n"); for(IElement e : noncopyables) b.append("\t-non-copyable " + e + "\n"); return b.toString(); } public boolean isEmpty() { return all.isEmpty(); } }