1 package org.pojomatic.internal.factory;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.InvocationTargetException;
6
7 import org.pojomatic.Pojomator;
8 import org.pojomatic.internal.PojomatorFactory;
9
10 public class PojoFactory {
11 public static class PojoAssembler {
12 private final Object pojo;
13
14 public PojoAssembler(Object pojo) {
15 this.pojo = pojo;
16 }
17
18
19 public PojoAssembler with(String propertyName, Object value) {
20 Field field;
21 try {
22 field = pojo.getClass().getDeclaredField(propertyName);
23 } catch (NoSuchFieldException | SecurityException e) {
24 throw new RuntimeException(e);
25 }
26 field.setAccessible(true);
27 try {
28 field.set(pojo, value);
29 } catch (IllegalArgumentException | IllegalAccessException e) {
30 throw new RuntimeException(e);
31 }
32 return this;
33 }
34
35 public PojoAssembler withParent(String propertyName, Object value) {
36 Field field;
37 try {
38 field = pojo.getClass().getSuperclass().getDeclaredField(propertyName);
39 } catch (NoSuchFieldException | SecurityException e) {
40 throw new RuntimeException(e);
41 }
42 field.setAccessible(true);
43 try {
44 field.set(pojo, value);
45 } catch (IllegalArgumentException | IllegalAccessException e) {
46 throw new RuntimeException(e);
47 }
48 return this;
49 }
50
51 public Object pojo() {
52 return pojo;
53 }
54 }
55
56 private final PojoDescriptor pojoDescriptor;
57 private final Class<?> pojoClass;
58 private final Pojomator<Object> pojomator;
59
60 public PojoFactory(PojoDescriptor pojoDescriptor) {
61 this(new PojoClassFactory(), pojoDescriptor);
62 }
63
64 @SuppressWarnings("unchecked")
65 public PojoFactory(PojoClassFactory classFactory, PojoDescriptor pojoDescriptor) {
66 this.pojoDescriptor = pojoDescriptor;
67 this.pojoClass = classFactory.generateClass(pojoDescriptor);
68 this.pojomator = (Pojomator<Object>) PojomatorFactory.makePojomator(pojoClass);
69
70 }
71
72 public PojoAssembler create() {
73 try {
74 Constructor<?> constructor = pojoClass.getConstructor();
75 constructor.setAccessible(true);
76 return new PojoAssembler(constructor.newInstance());
77 } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
78 throw new RuntimeException(e);
79 }
80 }
81
82 public Object create(Object value) {
83 if (pojoDescriptor.properties.size() != 1) {
84 throw new IllegalArgumentException("expected one property, found " + pojoDescriptor.properties.size());
85 }
86 return create().with(pojoDescriptor.properties.get(0).name, value).pojo();
87 }
88
89 public Pojomator<Object> pojomator() {
90 return pojomator;
91 }
92
93 }