package my;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import my.annotation.ClassInfo;
import my.annotation.ClassInfoList;
import my.annotation.Property;
import my.annotation.PropertyAccess;
/**
* We just set/get values as Object type. End users know the exact type of the
* property, and they can do the conversion themselves.
*/
public class NewObject {
private static String makeGetPropertyName(Field field) {
String fieldName = field.getName();
if (fieldName == null || fieldName.equals("")) {
return null;
}
return "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
}
private static String makeSetPropertyName(Field field) {
String fieldName = field.getName();
if (fieldName == null || fieldName.equals("")) {
return null;
}
return "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
}
/**
* Get property
* @param name
* @return
*/
public Object getProperty(String name) {
Class klass = this.getClass();
Field field = null;
while (!klass.getName().equals(NewObject.class.getName())) {
try {
field = klass.getDeclaredField(name);
break; // found
} catch (NoSuchFieldException e) {
// noop
}
klass = klass.getSuperclass();
}
if (field != null) {
Property property = field.getAnnotation(Property.class);
if (property.value() == PropertyAccess.WRITE
|| property.value() == PropertyAccess.READWRITE) {
String methodName = makeGetPropertyName(field);
try {
/**
* We can also get the value directly as below, but this
* bypass the getter function which is wrong.
* <code>
* field.setAccessible(true);
* Object value = field.get(this);
* field.setAccessible(false);
* return value;
*
*/
Method getMethod = klass.getMethod(methodName);
return getMethod.invoke(this);
} catch (IllegalAccessException e) {
// noop
} catch (IllegalArgumentException e) {
// noop
} catch (InvocationTargetException e) {
// noop
} catch (NoSuchMethodException e) {
// noop
} catch (SecurityException e) {
// noop
}
}
}
return null;
}
/**
* Set property
* @param name
* @param value
*/
public void setProperty(String name, Object value) {
Class klass = this.getClass();
Field field = null;
while (!klass.getName().equals(NewObject.class.getName())) {
try {
field = klass.getDeclaredField(name);
break; // found
} catch (NoSuchFieldException e) {
// noop
}
klass = klass.getSuperclass();
}
if (field != null) {
Property property = field.getAnnotation(Property.class);
if (property.value() == PropertyAccess.WRITE
|| property.value() == PropertyAccess.READWRITE) {
String methodName = makeSetPropertyName(field);
try {
Method setMethod = klass.getMethod(methodName, field.getType());
setMethod.invoke(this, value);
} catch (IllegalAccessException e) {
// noop
} catch (IllegalArgumentException e) {
// noop
} catch (InvocationTargetException e) {
// noop
} catch (NoSuchMethodException e) {
// noop
} catch (SecurityException e) {
// noop
}
}
}
}
/**
* Dump class info by given class
* @param klass
*/
public static void dumpClassInfo(Class klass) {
System.out.println(klass.getCanonicalName() + "(");
ClassInfo[] klassInfos = klass.getAnnotation(ClassInfoList.class).value();
for (int i = 0; i < klassInfos.length; i++) {
System.out.println(klassInfos[i].name() + "=" + klassInfos[i].value());
}
System.out.println(")");
}
/**
* Dump class info of current object
*/
public void dumpClassInfo() {
Class klass = this.getClass();
System.out.println(klass.getCanonicalName() + "(");
ClassInfo[] klassInfos = klass.getAnnotation(ClassInfoList.class).value();
for (int i = 0; i < klassInfos.length; i++) {
System.out.println(klassInfos[i].name() + "=" + klassInfos[i].value());
}
System.out.println(")");
}
/**
* Get class info by given name
* @param name
* @return
*/
public String getClassInfo(String name) {
Class klass = this.getClass();
ClassInfo[] klassInfos = klass.getAnnotation(ClassInfoList.class).value();
for (int i = 0; i < klassInfos.length; i++) {
if (klassInfos[i].name().equals(name)) {
return klassInfos[i].value();
}
}
return null;
}
}