package de.tudresden.inf.lat.tabula.datatype;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Default implementation of a composite type.
 *
 */
public class CompositeTypeImpl implements CompositeType {

	private final List<String> fields = new ArrayList<>();
	private final Map<String, String> fieldType = new TreeMap<>();

	/**
	 * Constructs a new default implementation of type.
	 */
	public CompositeTypeImpl() {
	}

	@Override
	public List<String> getFields() {
		return Collections.unmodifiableList(this.fields);
	}

	@Override
	public String getFieldType(String field) {
		if (field == null) {
			return null;
		} else {
			return this.fieldType.get(field);
		}
	}

	/**
	 * Declares a field.
	 * 
	 * @param field
	 *            field name
	 * @param typeStr
	 *            type of the field
	 */
	public void declareField(String field, String typeStr) {
		if (this.fields.contains(field)) {
			throw new ParseException("Field '" + field + "' has been already defined.");
		} else {
			this.fields.add(field);
			this.fieldType.put(field, typeStr);
		}
	}

	@Override
	public int hashCode() {
		return this.fields.hashCode() + (0x1F * this.fieldType.hashCode());
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof CompositeType) {
			CompositeType other = (CompositeType) obj;
			boolean ret = getFields().equals(other.getFields());
			if (ret) {
				List<String> fields = getFields();
				ret = ret && fields.stream().allMatch(field -> getFieldType(field).equals(other.getFieldType(field)));
			}
			return ret;
		}
		return false;
	}

	@Override
	public String toString() {
		StringBuffer sbuf = new StringBuffer();
		this.fields.forEach(field -> sbuf.append(field + ":" + this.fieldType.get(field) + " "));
		return sbuf.toString();
	}

}

@@ -438,39 +438,174 @@
 new 
-default implementation of
+composite type.%0A%09 */%0A%09public CompositeTypeImpl() %7B%0A%09%7D%0A%0A%09/**%0A%09 * Constructs a new composite type using another one.%0A%09 * %0A%09 * @param otherType%0A%09 *            other
  type
-.
 %0A%09 *
@@ -628,27 +628,144 @@
 iteTypeImpl(
-) %7B
+CompositeType otherType) %7B%0A%09%09otherType.getFields().forEach(field -%3E declareField(field, otherType.getFieldType(field)));
 %0A%09%7D%0A%0A%09@Overr

Add copy constructor to implementation of composite type