]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/symbolcontribution/CompositeSymbolProviderFactory.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / symbolcontribution / CompositeSymbolProviderFactory.java
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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.diagram.symbolcontribution;\r
13 \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
22 \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
28 \r
29 /**\r
30  * @author Tuukka Lehtonen\r
31  */\r
32 public class CompositeSymbolProviderFactory implements SymbolProviderFactory {\r
33 \r
34     Collection<SymbolProviderFactory> factories;\r
35 \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
40     }\r
41 \r
42     @Override\r
43     public int hashCode() {\r
44         return factories.hashCode();\r
45     }\r
46 \r
47     @Override\r
48     public boolean equals(Object obj) {\r
49         if (this == obj)\r
50             return true;\r
51         if (obj == null)\r
52             return false;\r
53         if (getClass() != obj.getClass())\r
54             return false;\r
55         CompositeSymbolProviderFactory other = (CompositeSymbolProviderFactory) obj;\r
56         return factories.equals(other.factories);\r
57     }\r
58 \r
59     @Override\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
65         }\r
66         return new CompositeSymbolProvider(providers);\r
67     }\r
68 \r
69     static class CompositeSymbolProvider extends AbstractSymbolProvider {\r
70 \r
71         Collection<ISymbolProvider> providers;\r
72 \r
73         public CompositeSymbolProvider(Collection<ISymbolProvider> providers) {\r
74             this.providers = providers;\r
75         }\r
76 \r
77         @Override\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
88                             continue;\r
89                     }\r
90                     groupsByName.add(name, group);\r
91                 }\r
92             }\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
105                         cgroup.add(grp);\r
106                     groups.put(name, cgroup);\r
107                 }\r
108             }\r
109             return new ArrayList<ISymbolGroup>(groups.values());\r
110         }\r
111 \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
117                 }\r
118             }\r
119             return id;\r
120         }\r
121 \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
127                 return "";\r
128             if (descs.size() == 1)\r
129                 return descs.iterator().next();\r
130             return EString.implode(descs);\r
131         }\r
132 \r
133         @Override\r
134         public void setListener(Runnable listener) {\r
135             for (ISymbolProvider provider : providers)\r
136                 provider.setListener(listener);\r
137         }\r
138 \r
139     }\r
140 \r
141 }\r