/*********************************************************************** * Copyright (c) 2008 by SAP AG, Walldorf. * 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: * SAP AG - initial API and implementation ***********************************************************************/ package org.eclipse.jst.jee.model.internal.common; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; /** * Introduces the notation of many-to-one relation. This is where the M and O of * the type signature comes from. * * Many unique "source" objects refer to one and only "target" object. * * The class maintains a connection between the target and all the sources that * are referring to it. * * @author Kiril Mitov k.mitov@sap.com * * @param <M> * the type of the "source" objects. * @param <O> * the type of the "target" objects. */ public class ManyToOneRelation<M, O> { private Map<M, O> manyToOne = new HashMap<M, O>(); /** * Connects the given source with the given target. If this source was * previously connected with another target the old connection is lost. * * @param source * @param target * @return */ public boolean connect(M source, O target) { manyToOne.put(source, target); return false; } /** * @param source * @return <code>true</code> if the relation contains the given source */ public boolean containsSource(M source) { return manyToOne.containsKey(source); } /** * @param target * @return <code>true</code> if the relation contains the given target */ public boolean containsTarget(O target) { return manyToOne.containsValue(target); } /** * @param source * @return the target with which this source is connected */ public O getTarget(M source) { return manyToOne.get(source); } /** * @param target * @return all the targets that are connected with this source or empty * collection if there are no sources connected with this target. */ public Collection<M> getSources(O target) { Collection<M> files = new LinkedList<M>(); for (Map.Entry<M, O> entry : manyToOne.entrySet()) { if (entry.getValue().equals(target)) files.add(entry.getKey()); } return files; } /** * Removes the connection between this source and the corresponding target. * Other sources will still point to the same target. * * The target is removed if this was the only source pointing to it and * {@link #containsTarget(Object)} will return false. * * @param source */ public void disconnectSource(M source) { manyToOne.remove(source); } /** * Removes the given target from the relation. All the sources that are * pointing to this target are also removed. * * If you take the "result" of {@link #getSources(target)} and after that * call this method then {@link #containsSource(Object)} will return * <code>false</code> for every object in "result". * * @param target */ public void disconnect(O target) { for (Iterator<O> iter = manyToOne.values().iterator(); iter.hasNext();) { if (iter.next().equals(target)) iter.remove(); } } /** * @return a collection of the targets. */ public Collection<O> getTargets() { return manyToOne.values(); } }