MorphicArrayTransformer.java

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

import java.util.HashMap;
import java.util.Map;

public class MorphicArrayTransformer<T extends Morphic> implements
		MorphicTransformerIF<MorphicArray<T>> {

	private MorphicArrayFactory<T> arrayFactory;

	private MorphicTransformerIF<T> elementTransformer;

	private Map<MorphicArray<T>, MorphicArray<T>> cache = new HashMap<MorphicArray<T>, MorphicArray<T>>();

	public MorphicArrayTransformer(
			MorphicArrayFactory<T> arrayFactory,
			MorphicTransformerIF<T> elementTransformer) {
		this.arrayFactory = arrayFactory;
		this.elementTransformer = elementTransformer;
	}

	@Override
	public MorphicArray<T> transform(MorphicArray<T> array) {
		MorphicArray<T> newArray;

		array = arrayFactory.canonic(array);
		newArray = cache.get(array);
		if (newArray != null)
			return newArray;

		int length = array.length();

		for (int i = 0; i < length; i++) {
			T oldValue = array.get(i);

			if (oldValue != null) {
				T newValue = elementTransformer.transform(oldValue);

				if (newValue != oldValue) {
					if (newArray == null) {
						newArray = arrayFactory.newArray(length);
						for (int j = 0; j < i; j++)
							newArray.set(j, array.get(j));
					}
					newArray.set(i, newValue);
				} else if (newArray != null) {
					newArray.set(i, oldValue);
				}
			}
		}
		if (newArray != null) {
			newArray = arrayFactory.canonic(newArray);
		} else {
			newArray = array;
		}
		cache.put(array, newArray);
		return newArray;
	}

}