package com.mattunderscore.trees.construction;

import com.mattunderscore.trees.tree.Tree;

import java.lang.reflect.ParameterizedType;

/**
 * Type key to support generics when constructing trees.
 * @author Matt Champion
 */
public abstract class TypeKey<T extends Tree<?, ?>> {
    private final Class<T> type;

    @SuppressWarnings("unchecked")
    public TypeKey() {
        final ParameterizedType concreteParameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
        final ParameterizedType parameterizedType = (ParameterizedType) concreteParameterizedType.getActualTypeArguments()[0];
        type = (Class<T>) parameterizedType.getRawType();
    }

    public final Class<T> getType() {
        return type;
    }

    @Override
    public final boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final TypeKey typeKey = (TypeKey) o;

        return type.equals(typeKey.type);
    }

    @Override
    public final int hashCode() {
        return type.hashCode();
    }

    @Override
    public final String toString() {
        return "TypeKey:" + type.getName();
    }
}

@@ -128,16 +128,47 @@
 zedType;
+%0Aimport java.lang.reflect.Type;
 %0A%0A/**%0A *
@@ -530,178 +530,488 @@
 nal 
-ParameterizedType parameterizedType = (ParameterizedType) concreteParameterizedType.getActualTypeArguments()%5B0%5D;%0A        type = (Class%3CT%3E) parameterizedType.getRawType();
+Type treeType = concreteParameterizedType.getActualTypeArguments()%5B0%5D;%0A        if (treeType instanceof ParameterizedType) %7B%0A            final ParameterizedType parameterizedType = (ParameterizedType) treeType;%0A            type = (Class%3CT%3E) parameterizedType.getRawType();%0A        %7D%0A        else if (treeType instanceof Class) %7B%0A            type = (Class%3CT%3E) treeType;%0A        %7D%0A        else %7B%0A            throw new IllegalStateException(%22Unable to identify tree class%22);%0A        %7D
 %0A   

Allow exactly specified trees to be represented by type keys