PojomatorFactory.java
package org.pojomatic.internal;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import org.pojomatic.Pojomator;
import org.pojomatic.PropertyElement;
import org.pojomatic.annotations.PropertyFormat;
import org.pojomatic.formatter.DefaultEnhancedPropertyFormatter;
import org.pojomatic.formatter.EnhancedPropertyFormatter;
public class PojomatorFactory {
public static <T> Pojomator<T> makePojomator(final Class<T> pojoClass) {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Pojomator<T>>() {
@Override
public Pojomator<T> run() throws Exception {
return makePojomatorChecked(pojoClass);
}
});
} catch (PrivilegedActionException e) {
throw new RuntimeException(e.getCause());
}
}
private static <T> Pojomator<T> makePojomatorChecked(Class<T> pojoClass)
throws IllegalAccessException, NoSuchFieldException, SecurityException, InstantiationException,
InvocationTargetException, NoSuchMethodException {
ClassProperties classProperties = ClassProperties.forClass(pojoClass);
PojomatorByteCodeGenerator generator = new PojomatorByteCodeGenerator(pojoClass, classProperties);
Class<?> pojomatorClass = ClassDefinerFactory.getDefiner().defineClass(generator.pojomatorClassName, generator.makeClassBytes());
@SuppressWarnings("unchecked")
Pojomator<T> pojomator = (Pojomator<T>) pojomatorClass.getConstructor(Class.class, ClassProperties.class)
.newInstance(pojoClass, classProperties);
for (PropertyElement propertyElement: classProperties.getToStringProperties()) {
setStaticField(
pojomatorClass,
PojomatorByteCodeGenerator.propertyFormatterName(propertyElement),
createPropertyFormatter(propertyElement.getElement()));
}
for (PropertyElement propertyElement: classProperties.getAllProperties()) {
setStaticField(pojomatorClass, PojomatorByteCodeGenerator.propertyElementName(propertyElement), propertyElement);
}
return pojomator;
}
private static void setStaticField(Class<?> clazz, String fieldName, Object value)
throws NoSuchFieldException, SecurityException, IllegalAccessException {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, value);
}
private static EnhancedPropertyFormatter createPropertyFormatter(AnnotatedElement annotatedElement)
throws InstantiationException, IllegalAccessException {
PropertyFormat propertyFormat = annotatedElement.getAnnotation(PropertyFormat.class);
EnhancedPropertyFormatter propertyFormatter = constructPropertyFormatter(propertyFormat);
propertyFormatter.initialize(annotatedElement);
return propertyFormatter;
}
private static EnhancedPropertyFormatter constructPropertyFormatter(PropertyFormat propertyFormat)
throws InstantiationException, IllegalAccessException {
if (propertyFormat == null) {
return new DefaultEnhancedPropertyFormatter();
}
else {
if (EnhancedPropertyFormatter.class.isAssignableFrom(propertyFormat.value())) {
return (EnhancedPropertyFormatter) propertyFormat.value().newInstance();
}
else {
@SuppressWarnings("deprecation")
EnhancedPropertyFormatterWrapper wrapper = new EnhancedPropertyFormatterWrapper(propertyFormat.value().newInstance());
return wrapper;
}
}
}
}