View Javadoc
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  }