package rtt.annotations.processing;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import rtt.annotations.Node.Initialize;
import rtt.annotations.Node.Value;
import rtt.core.utils.RTTLogging;
public class ClassElement {
private static final String ONLY_NONVOID_METHODS =
"Only methods with a non-void return type allowed.";
private static final String ONLY_PARAMETERLESS_METHODS =
"Only methods without parameters allowed.";
private static final Class<Value> VALUE_ANNOTATION = Value.class;
private static final Class<Initialize> INIT_ANNOTATION = Initialize.class;
private SortedSet<ValueMember<?>> valueMembers;
private SortedSet<InitMember<?>> initMembers;
public ClassElement(Class<?> objectType) {
valueMembers = populateValueMembers(objectType, null);
initMembers = populateInitMembers(objectType, null);
}
public ClassElement(Class<?> objectType, ClassElement parent) {
valueMembers = populateValueMembers(objectType, parent.getValueMembers());
initMembers = populateInitMembers(objectType, parent.getInitMembers());
}
private SortedSet<ValueMember<?>> populateValueMembers(Class<?> objectType,
SortedSet<ValueMember<?>> parentMembers) {
SortedSet<ValueMember<?>> members = new TreeSet<>();
if (parentMembers != null) {
members.addAll(parentMembers);
}
addValueFields(objectType, members);
addValueMethods(objectType, members);
return members;
}
private void addValueFields(Class<?> objectType,
Set<ValueMember<?>> annotatedFields) {
for (Class<?> interfaceType : objectType.getInterfaces()) {
addValueFields(interfaceType, annotatedFields);
}
for (Field field : objectType.getDeclaredFields()){
if (field.isAnnotationPresent(VALUE_ANNOTATION)) {
annotatedFields.add(ValueMember.create(field));
}
}
}
private void addValueMethods(Class<?> objectType,
Set<ValueMember<?>> annotatedMethods) {
for (Class<?> interfaceType : objectType.getInterfaces()) {
addValueMethods(interfaceType, annotatedMethods);
}
for (Method method : objectType.getDeclaredMethods()) {
if (method.isAnnotationPresent(VALUE_ANNOTATION)) {
if (method.getReturnType() == Void.TYPE) {
RTTLogging.warn(ONLY_NONVOID_METHODS);
continue;
}
if (method.getParameterTypes().length > 0) {
RTTLogging.warn(ONLY_PARAMETERLESS_METHODS);
continue;
}
annotatedMethods.add(ValueMember.create(method));
}
}
}
public SortedSet<ValueMember<?>> getValueMembers() {
return valueMembers;
}
private SortedSet<InitMember<?>> populateInitMembers(Class<?> objectType,
SortedSet<InitMember<?>> parentMembers) {
SortedSet<InitMember<?>> members = new TreeSet<>();
addInitConstructors(objectType, members);
addInitMethods(objectType, members);
return members;
}
private void addInitConstructors(Class<?> objectType,
Set<InitMember<?>> annotatedConstructors) {
for (Constructor<?> constructor : objectType.getDeclaredConstructors()) {
if (constructor.isAnnotationPresent(INIT_ANNOTATION)) {
annotatedConstructors.add(InitMember.create(constructor));
}
}
}
private void addInitMethods(Class<?> objectType,
Set<InitMember<?>> annotatedMethods) {
for (Method method : objectType.getDeclaredMethods()) {
if (method.isAnnotationPresent(INIT_ANNOTATION)) {
annotatedMethods.add(InitMember.create(method));
}
}
}
public SortedSet<InitMember<?>> getInitMembers() {
return initMembers;
}
}