/******************************************************************************* * 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.symbolcontribution; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import org.simantics.db.ReadGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.diagram.symbollibrary.ISymbolGroup; import org.simantics.utils.datastructures.MapList; import org.simantics.utils.strings.EString; /** * @author Tuukka Lehtonen */ public class CompositeSymbolProviderFactory implements SymbolProviderFactory { Collection factories; public CompositeSymbolProviderFactory(Collection factories) { if (factories == null) throw new NullPointerException("null factories"); this.factories = factories; } @Override public int hashCode() { return factories.hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CompositeSymbolProviderFactory other = (CompositeSymbolProviderFactory) obj; return factories.equals(other.factories); } @Override public ISymbolProvider create(ReadGraph graph) throws DatabaseException { ArrayList providers = new ArrayList(factories.size()); for (SymbolProviderFactory factory : factories) { ISymbolProvider provider = factory.create(graph); providers.add(provider); } return new CompositeSymbolProvider(providers); } static class CompositeSymbolProvider extends AbstractSymbolProvider { Collection providers; public CompositeSymbolProvider(Collection providers) { this.providers = providers; } @Override public Collection getSymbolGroups() { MapList groupsByName = new MapList(); Set processedIds = new HashSet(); Map groups = new TreeMap(); for(ISymbolProvider provider : providers) { for(ISymbolGroup group : provider.getSymbolGroups()) { String name = group.getName(); if (group instanceof IIdentifiedObject) { Object id = ((IIdentifiedObject) group).getId(); if (!processedIds.add(id)) continue; } groupsByName.add(name, group); } } // Process groups with multiple ISymbolGroup contributions // into CompositeSymbolGroupsand leave single ISymbolGroups as such. for (String name : groupsByName.getKeys()) { List grps = groupsByName.getValues(name); int grpCount = grps.size(); if (grpCount == 1) { groups.put(name, grps.get(0)); } else if (grpCount > 1) { Object id = combineIdentification(grps); String description = combineDescriptions(grps); CompositeSymbolGroup cgroup = new CompositeSymbolGroup(id, name, description); for (ISymbolGroup grp : grps) cgroup.add(grp); groups.put(name, cgroup); } } return new ArrayList(groups.values()); } private Object combineIdentification(List grps) { Set id = new HashSet(); for (ISymbolGroup grp : grps) { if (grp instanceof IIdentifiedObject) { id.add( ((IIdentifiedObject) grp).getId() ); } } return id; } private String combineDescriptions(List grps) { Set descs = new TreeSet(); for (ISymbolGroup grp : grps) descs.add(grp.getDescription()); if (descs.isEmpty()) return ""; if (descs.size() == 1) return descs.iterator().next(); return EString.implode(descs); } @Override public void setListener(Runnable listener) { for (ISymbolProvider provider : providers) provider.setListener(listener); } } }