1 package org.pojomatic.internal; 2 3 import java.lang.reflect.AnnotatedElement; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.InvocationTargetException; 6 import java.security.AccessController; 7 import java.security.PrivilegedActionException; 8 import java.security.PrivilegedExceptionAction; 9 10 import org.pojomatic.Pojomator; 11 import org.pojomatic.PropertyElement; 12 import org.pojomatic.annotations.PropertyFormat; 13 import org.pojomatic.formatter.DefaultEnhancedPropertyFormatter; 14 import org.pojomatic.formatter.EnhancedPropertyFormatter; 15 16 public class PojomatorFactory { 17 public static <T> Pojomator<T> makePojomator(final Class<T> pojoClass) { 18 try { 19 return AccessController.doPrivileged(new PrivilegedExceptionAction<Pojomator<T>>() { 20 @Override 21 public Pojomator<T> run() throws Exception { 22 return makePojomatorChecked(pojoClass); 23 } 24 }); 25 } catch (PrivilegedActionException e) { 26 throw new RuntimeException(e.getCause()); 27 } 28 } 29 30 private static <T> Pojomator<T> makePojomatorChecked(Class<T> pojoClass) 31 throws IllegalAccessException, NoSuchFieldException, SecurityException, InstantiationException, 32 InvocationTargetException, NoSuchMethodException { 33 ClassProperties classProperties = ClassProperties.forClass(pojoClass); 34 PojomatorByteCodeGenerator generator = new PojomatorByteCodeGenerator(pojoClass, classProperties); 35 Class<?> pojomatorClass = ClassDefinerFactory.getDefiner().defineClass(generator.pojomatorClassName, generator.makeClassBytes()); 36 @SuppressWarnings("unchecked") 37 Pojomator<T> pojomator = (Pojomator<T>) pojomatorClass.getConstructor(Class.class, ClassProperties.class) 38 .newInstance(pojoClass, classProperties); 39 for (PropertyElement propertyElement: classProperties.getToStringProperties()) { 40 setStaticField( 41 pojomatorClass, 42 PojomatorByteCodeGenerator.propertyFormatterName(propertyElement), 43 createPropertyFormatter(propertyElement.getElement())); 44 } 45 for (PropertyElement propertyElement: classProperties.getAllProperties()) { 46 setStaticField(pojomatorClass, PojomatorByteCodeGenerator.propertyElementName(propertyElement), propertyElement); 47 } 48 return pojomator; 49 } 50 51 private static void setStaticField(Class<?> clazz, String fieldName, Object value) 52 throws NoSuchFieldException, SecurityException, IllegalAccessException { 53 Field field = clazz.getDeclaredField(fieldName); 54 field.setAccessible(true); 55 field.set(null, value); 56 } 57 58 private static EnhancedPropertyFormatter createPropertyFormatter(AnnotatedElement annotatedElement) 59 throws InstantiationException, IllegalAccessException { 60 PropertyFormat propertyFormat = annotatedElement.getAnnotation(PropertyFormat.class); 61 EnhancedPropertyFormatter propertyFormatter = constructPropertyFormatter(propertyFormat); 62 propertyFormatter.initialize(annotatedElement); 63 return propertyFormatter; 64 65 } 66 67 private static EnhancedPropertyFormatter constructPropertyFormatter(PropertyFormat propertyFormat) 68 throws InstantiationException, IllegalAccessException { 69 if (propertyFormat == null) { 70 return new DefaultEnhancedPropertyFormatter(); 71 } 72 else { 73 if (EnhancedPropertyFormatter.class.isAssignableFrom(propertyFormat.value())) { 74 return (EnhancedPropertyFormatter) propertyFormat.value().newInstance(); 75 } 76 else { 77 @SuppressWarnings("deprecation") 78 EnhancedPropertyFormatterWrapper wrapper = new EnhancedPropertyFormatterWrapper(propertyFormat.value().newInstance()); 79 return wrapper; 80 } 81 } 82 } 83 }