package rtt.annotations.processing; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import rtt.annotations.Node.Value; import rtt.core.archive.output.GeneratorType; public abstract class ValueMember<T extends Member> implements Comparable<ValueMember<?>> { private static final class ValueField extends ValueMember<Field> { private final Field field; private ValueField(Field field) { super(field, GeneratorType.FIELD, field.getAnnotation(VALUE_ANNOTATION)); this.field = field; } @Override public Object getResult(Object object) throws ReflectiveOperationException { field.setAccessible(true); return field.get(object); } @Override public String getReturnType() { return field.getType().getName(); } } private static final class ValueMethod extends ValueMember<Method> { private final Method method; private ValueMethod(Method method) { super(method, GeneratorType.METHOD, method.getAnnotation(VALUE_ANNOTATION)); this.method = method; } @Override public Object getResult(Object object) throws ReflectiveOperationException { method.setAccessible(true); return method.invoke(object); } @Override public String getReturnType() { return method.getReturnType().getName(); } } private static final Class<Value> VALUE_ANNOTATION = Value.class; private Value valueAnnotation; private T member; private int index; private String name; private boolean informational; private GeneratorType type; private String signature; private ValueMember(T member, GeneratorType type, Value valueAnnotation) { this.member = member; this.type = type; this.signature = member.getDeclaringClass().getSimpleName() + "." + member.getName(); this.valueAnnotation = valueAnnotation; this.index = valueAnnotation.index(); this.informational = valueAnnotation.informational(); this.name = valueAnnotation.name(); if (this.name == null) { this.name = ""; } } public abstract Object getResult(Object object) throws ReflectiveOperationException; public abstract String getReturnType(); public static final ValueMember<Field> create(final Field field) { return new ValueField(field); } public static final ValueMember<Method> create(final Method method) { return new ValueMethod(method); } public T getMember() { return member; } public Value getAnnotation() { return valueAnnotation; } public final boolean isInformational() { return informational; } public final GeneratorType getType() { return type; } public final String getSignature() { return signature; } public final String getName() { if (name == null || name.equals("")) { return signature; } return name; } @Override public int compareTo(ValueMember<?> other) { if (this.equals(other)) { return 0; } if (this.index != other.index) { return Integer.compare(this.index, other.index); } if (this.informational != other.informational) { return Boolean.compare(this.informational, other.informational); } if (this.type != other.type) { return type.compareTo(other.type); } if (!this.name.equals(other.name)) { return this.name.compareTo(other.name); } return this.signature.compareTo(other.signature); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + index; result = prime * result + (informational ? 1231 : 1237); result = prime * result + type.hashCode(); result = prime * result + name.hashCode(); result = prime * result + signature.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof ValueMember)) { return false; } ValueMember<?> other = (ValueMember<?>) obj; if (index != other.index) { return false; } if (informational != other.informational) { return false; } if (type != other.type) { return false; } if (!name.equals(other.name)) { return false; } if (!signature.equals(other.signature)) { return false; } return true; } }