blob: a2b943c59970d40feadc475c4ba07de43330d67b [file] [log] [blame]
/***********************************************************************
* 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
* https://www.eclipse.org/legal/epl-2.0/
*
* 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();
}
}