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.symbolcontribution;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collection;
\r
16 import java.util.HashSet;
\r
17 import java.util.List;
\r
18 import java.util.Map;
\r
19 import java.util.Set;
\r
20 import java.util.TreeMap;
\r
21 import java.util.TreeSet;
\r
23 import org.simantics.db.ReadGraph;
\r
24 import org.simantics.db.exception.DatabaseException;
\r
25 import org.simantics.diagram.symbollibrary.ISymbolGroup;
\r
26 import org.simantics.utils.datastructures.MapList;
\r
27 import org.simantics.utils.strings.EString;
\r
30 * @author Tuukka Lehtonen
\r
32 public class CompositeSymbolProviderFactory implements SymbolProviderFactory {
\r
34 Collection<SymbolProviderFactory> factories;
\r
36 public CompositeSymbolProviderFactory(Collection<SymbolProviderFactory> factories) {
\r
37 if (factories == null)
\r
38 throw new NullPointerException("null factories");
\r
39 this.factories = factories;
\r
43 public int hashCode() {
\r
44 return factories.hashCode();
\r
48 public boolean equals(Object obj) {
\r
53 if (getClass() != obj.getClass())
\r
55 CompositeSymbolProviderFactory other = (CompositeSymbolProviderFactory) obj;
\r
56 return factories.equals(other.factories);
\r
60 public ISymbolProvider create(ReadGraph graph) throws DatabaseException {
\r
61 ArrayList<ISymbolProvider> providers = new ArrayList<ISymbolProvider>(factories.size());
\r
62 for (SymbolProviderFactory factory : factories) {
\r
63 ISymbolProvider provider = factory.create(graph);
\r
64 providers.add(provider);
\r
66 return new CompositeSymbolProvider(providers);
\r
69 static class CompositeSymbolProvider extends AbstractSymbolProvider {
\r
71 Collection<ISymbolProvider> providers;
\r
73 public CompositeSymbolProvider(Collection<ISymbolProvider> providers) {
\r
74 this.providers = providers;
\r
78 public Collection<ISymbolGroup> getSymbolGroups() {
\r
79 MapList<String, ISymbolGroup> groupsByName = new MapList<String, ISymbolGroup>();
\r
80 Set<Object> processedIds = new HashSet<Object>();
\r
81 Map<String, ISymbolGroup> groups = new TreeMap<String, ISymbolGroup>();
\r
82 for(ISymbolProvider provider : providers) {
\r
83 for(ISymbolGroup group : provider.getSymbolGroups()) {
\r
84 String name = group.getName();
\r
85 if (group instanceof IIdentifiedObject) {
\r
86 Object id = ((IIdentifiedObject) group).getId();
\r
87 if (!processedIds.add(id))
\r
90 groupsByName.add(name, group);
\r
93 // Process groups with multiple ISymbolGroup contributions
\r
94 // into CompositeSymbolGroupsand leave single ISymbolGroups as such.
\r
95 for (String name : groupsByName.getKeys()) {
\r
96 List<ISymbolGroup> grps = groupsByName.getValues(name);
\r
97 int grpCount = grps.size();
\r
98 if (grpCount == 1) {
\r
99 groups.put(name, grps.get(0));
\r
100 } else if (grpCount > 1) {
\r
101 Object id = combineIdentification(grps);
\r
102 String description = combineDescriptions(grps);
\r
103 CompositeSymbolGroup cgroup = new CompositeSymbolGroup(id, name, description);
\r
104 for (ISymbolGroup grp : grps)
\r
106 groups.put(name, cgroup);
\r
109 return new ArrayList<ISymbolGroup>(groups.values());
\r
112 private Object combineIdentification(List<ISymbolGroup> grps) {
\r
113 Set<Object> id = new HashSet<Object>();
\r
114 for (ISymbolGroup grp : grps) {
\r
115 if (grp instanceof IIdentifiedObject) {
\r
116 id.add( ((IIdentifiedObject) grp).getId() );
\r
122 private String combineDescriptions(List<ISymbolGroup> grps) {
\r
123 Set<String> descs = new TreeSet<String>();
\r
124 for (ISymbolGroup grp : grps)
\r
125 descs.add(grp.getDescription());
\r
126 if (descs.isEmpty())
\r
128 if (descs.size() == 1)
\r
129 return descs.iterator().next();
\r
130 return EString.implode(descs);
\r
134 public void setListener(Runnable listener) {
\r
135 for (ISymbolProvider provider : providers)
\r
136 provider.setListener(listener);
\r