/*******************************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.common.infra;

// Java Classes
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

// Library Classes
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.set.AbstractSerializableSetDecorator;
import org.apache.commons.lang.Validate;

// Framework Classes

// Common Classes

/**
 * @author Martin Francisco
 */
public class RemoveTransformedSet extends AbstractSerializableSetDecorator {
	
	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 6226884980920409498L;
	
	protected final Transformer transformer;

	public static Set decorate(Set set, Transformer transformer) {
		return new RemoveTransformedSet(set, transformer);
	}

	private RemoveTransformedSet(Set set, Transformer transformer) {
		super(set);
		Validate.notNull(transformer, "Transformer must not be null");
		this.transformer = transformer;
	}

	protected Collection contains(Collection coll) {
		List list = new ArrayList(coll.size());
		for (Iterator it = coll.iterator(); it.hasNext();) {
			Object obj = it.next();
			if (super.getCollection().contains(obj)) {
				list.add(obj);
			}
		}
		return list;
	}

	protected Collection notContains(Collection coll) {
		List list = new ArrayList(super.getCollection().size());
		for (Iterator it = super.getCollection().iterator(); it.hasNext();) {
			Object obj = it.next();
			if (!coll.contains(obj)) {
				list.add(obj);
			}
		}
		return list;
	}

	protected Object transform(Object object) {
		return this.transformer.transform(object);
	}

	protected Collection transform(Collection coll) {
		List list = new ArrayList(coll.size());
		for (Iterator it = coll.iterator(); it.hasNext();) {
			list.add(this.transform(it.next()));
		}
		return list;
	}

	public void clear() {
		List list = new ArrayList(super.getCollection());
		super.getCollection().clear();
		this.transform(list);
	}

	public boolean remove(Object object) {
		boolean returnValue = super.getCollection().remove(object);
		if (returnValue) {
			this.transform(object);
		}
		return returnValue;
	}

	public boolean removeAll(Collection coll) {
		boolean retValue = super.getCollection().removeAll(coll);
		this.transform(coll);
		return retValue;
	}

	public boolean retainAll(Collection coll) {
		boolean retValue = super.getCollection().retainAll(coll);
		this.transform(coll);
		return retValue;
	}
}