/******************************************************************************* * 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.g2d.diagram.impl; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.simantics.utils.datastructures.MapList; /** * @author Toni Kalajainen */ public class AbstractHandlerClass implements Serializable { private static final long serialVersionUID = 4137854678128072467L; private final MapList, Handler> handlers = new MapList, Handler>(); private final List snapshot; private final int hash; public AbstractHandlerClass(Collection contributions) { for (Handler c : contributions) _addClass(c.getClass(), c); this.handlers.makeImmutable(); this.snapshot = Collections.unmodifiableList(new ArrayList(contributions)); this.hash = snapshot.hashCode(); } private void _addClass(Class clazz, Handler ec) { if (handlers.contains(clazz, ec)) return; handlers.add(clazz, ec); Class superClazz = clazz.getSuperclass(); if (superClazz!=null) _addClass(superClazz, ec); for (Class interphase : clazz.getInterfaces()) _addClass(interphase, ec); } /** * Get all interactors by class * @param clazz * @return collection */ @SuppressWarnings("unchecked") public List getItemsByClass(Class clazz) { List result = (List) handlers.getValuesUnsafe(clazz); if (result!=null) return result; return Collections.emptyList(); } /** * Get a single item by class. * (Convenience method) * * @param * @param clazz * @return the item * @throws RuntimeException if single interactor was not found */ @SuppressWarnings("unchecked") public R getSingleItem(Class clazz) { List list = (List) handlers.getValuesUnsafe(clazz); if (list==null || list.size()!=1) throw new RuntimeException("Invalid element class "+toString()+": One and only one "+clazz.getName()+" is expected, got " + (list != null ? list.size() : 0)); return list.get(0); } /** * Get a single item by class. * (Convenience method) * * @param * @param clazz * @return the item or null * @throws RuntimeException if more than one items were found */ @SuppressWarnings("unchecked") public R getAtMostOneItemOfClass(Class clazz) { List list = (List) handlers.getValuesUnsafe(clazz); if (list==null || list.size()==0) return null; if (list.size()==1) return list.get(0); throw new RuntimeException("At most one was "+clazz.getName()+" expected in "+this.getClass().getName() + ", got " + list.size()); } public R[] getAtMostItemsOfClass(Class clazz, R[] result) { handlers.getAtMostValues(clazz, result); return result; } public List getAll() { return snapshot; } public boolean contains(Handler handler) { return getAll().contains(handler); } @SuppressWarnings("unchecked") public boolean containsClass(Class clazz) { List list = (List) handlers.getValuesUnsafe(clazz); if (list==null || list.size()==0) return false; return list.size()>0; } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof AbstractHandlerClass)) return false; AbstractHandlerClass other = (AbstractHandlerClass) obj; return snapshot.equals(other.snapshot); } }