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 }