MorphicSet.java

package edu.udel.cis.vsl.tass.morph;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

public class MorphicSet<T extends Morphic> extends MorphicObject implements
		Iterable<T> {

	private LinkedHashSet<T> elements;

	MorphicSet(LinkedHashSet<T> elements) {
		this.elements = elements;
	}

	MorphicSet() {
		this(new LinkedHashSet<T>());
	}

	MorphicSet(MorphicSet<T> oldSet) {
		this(oldSet.elements);
	}

	public Set<T> elements() {
		return elements;
	}

	public boolean contains(T element) {
		return elements.contains(element);
	}

	public boolean add(T element) {
		assert !isCommitted();
		return elements.add(element);
	}

	public boolean remove(T element) {
		assert !isCommitted();
		return elements.remove(element);
	}

	@Override
	public Iterator<T> iterator() {
		return elements.iterator();
	}

	// @Override
	// public String toString() {
	// String result = "{";
	// boolean first = true;
	//
	// for (T element : elements) {
	// if (!first)
	// result += ", ";
	// result += element.toString();
	// }
	// result += "}";
	// return result;
	// }

	protected int computeHashCode() {
		return elements.hashCode();
	}

	protected boolean computeEquals(Morphic component) {
		return component instanceof MorphicSet<?>
				&& elements.equals(((MorphicSet<?>) component).elements);
	}

	@SuppressWarnings("unchecked")
	void canonicalizeChildren(MorphicFactoryIF<? super T> elementFactory) {
		LinkedHashSet<T> newSet = null;

		for (T element : elements) {
			T newElement = (T) elementFactory.canonic(element);

			if (element != newElement && newSet == null) {
				newSet = new LinkedHashSet<T>();
				for (T element2 : elements) {
					if (element2 == element)
						break;
					newSet.add(element2);
				}
			}
			if (newSet != null)
				newSet.add(newElement);
		}
		if (newSet != null)
			elements = newSet;
	}

	@Override
	protected void commitChildren() {
		for (T element : elements) {
			element.commit();
		}
	}

	@Override
	public String toString() {
		return elements.toString();
	}

}