VectorValue.java

package edu.udel.cis.vsl.tass.dynamic.impl.value;

import java.util.EmptyStackException;
import java.util.Iterator;

import edu.udel.cis.vsl.tass.dynamic.IF.DynamicException;
import edu.udel.cis.vsl.tass.dynamic.IF.DynamicException.DynamicErrorKind;
import edu.udel.cis.vsl.tass.dynamic.IF.type.VectorValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.VectorValueIF;
import edu.udel.cis.vsl.tass.dynamic.impl.type.ValueTypeFactory;
import edu.udel.cis.vsl.tass.morph.Morphic;
import edu.udel.cis.vsl.tass.morph.MorphicVector;

public class VectorValue extends Value implements VectorValueIF {

	private static int classHashCode = VectorValue.class.hashCode();

	private MorphicVector<ValueIF> data;

	/** Constructs new vector value. */
	public VectorValue(MorphicVector<ValueIF> data, VectorValueTypeIF valueType) {
		super(valueType);
		assert data != null;
		this.data = data;
	}

	public MorphicVector<ValueIF> data() {
		return data;
	}

	public void setData(MorphicVector<ValueIF> data) {
		this.data = data;
	}

	@Override
	protected int computeHashCode() {
		return super.computeHashCode() + classHashCode + data.hashCode();
	}

	@Override
	public int size() {
		return data.size();
	}

	@Override
	public VectorValueTypeIF valueType() {
		return (VectorValueTypeIF) super.valueType();
	}

	@Override
	protected boolean computeEquals(Morphic component) {
		if (component instanceof VectorValue) {
			VectorValue that = (VectorValue) component;

			return super.equals(that) && data.equals(that.data);
		}
		return false;
	}

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

	@Override
	protected void commitChildren() {
		super.commitChildren();
		data.commit();
	}

	@Override
	protected void canonicalizeChildren(ValueFactory valueFactory,
			ValueTypeFactory typeFactory) {
		super.canonicalizeChildren(valueFactory, typeFactory);
		data = valueFactory.valueVectorFactory().canonic(data);
	}

	@Override
	public void add(ValueIF element) {
		data.add(element);
	}

	@Override
	public ValueIF get(int index) throws DynamicException {
		try {
			return data.get(index);
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new DynamicException(DynamicErrorKind.OUT_OF_BOUNDS,
					"Vector index out of bounds: index=" + index + ", size="
							+ data.size());
		}
	}

	@Override
	public Iterator<ValueIF> iterator() {
		return data.iterator();
	}

	@Override
	public ValueIF peek() throws DynamicException {
		try {
			return data.peek();
		} catch (EmptyStackException e) {
			throw new DynamicException(DynamicErrorKind.OUT_OF_BOUNDS,
					"Attempt to peek at empty stack.");
		}
	}

	@Override
	public ValueIF pop() throws DynamicException {
		try {
			return data.pop();
		} catch (EmptyStackException e) {
			throw new DynamicException(DynamicErrorKind.OUT_OF_BOUNDS,
					"Attempt to pop empty stack.");
		}
	}

	@Override
	public void push(ValueIF element) {
		data.push(element);
	}

	@Override
	public ValueIF removeElementAt(int position) throws DynamicException {
		try {
			return data.removeElementAt(position);
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new DynamicException(DynamicErrorKind.OUT_OF_BOUNDS,
					"Attempt to remove element from vector with index out of bounds: "
							+ e);
		}
	}

	@Override
	public void set(int index, ValueIF element) throws DynamicException {
		try {
			data.set(index, element);
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new DynamicException(DynamicErrorKind.OUT_OF_BOUNDS,
					"Attempt to set vector element with index out of bounds: "
							+ e);
		}
	}

	@Override
	public void setExtend(int index, ValueIF value) {
		data.setExtend(index, value);
	}

	@Override
	public void setSize(int newSize) {
		data.setSize(newSize);
	}
}