1
2
3
4
5
6
7
8
9 package com.codebox.instance;
10
11 import com.codebox.bean.ValueBuilder;
12 import com.codebox.enums.LoadData;
13 import com.codebox.enums.LoadType;
14 import com.codebox.util.LombokBuilderUtil;
15
16 import java.lang.reflect.Constructor;
17 import java.lang.reflect.InvocationTargetException;
18 import java.lang.reflect.Method;
19 import java.util.Arrays;
20
21 import org.junit.jupiter.api.Assertions;
22
23
24
25
26
27
28
29 public class ClassInstance<T> {
30
31
32
33
34
35
36
37
38
39
40 @SuppressWarnings("unchecked")
41 public final T newInstance(final Class<T> clazz) {
42
43 if (clazz == null) {
44 return null;
45 }
46
47
48 Method builderMethod = LombokBuilderUtil.getLombokBuilderMethod(clazz);
49 if (builderMethod != null) {
50 try {
51 return this.createInstanceWithBuilder(clazz, builderMethod);
52 } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException
53 | NoSuchMethodException | SecurityException e) {
54 Assertions.fail(String.format(
55 "An exception was thrown while creating instance using Lombok @Builder for class '%s': '%s'",
56 clazz.getName(), e.toString()));
57 }
58 }
59
60
61 for (final Constructor<?> constructor : clazz.getConstructors()) {
62
63 if (constructor.isAnnotationPresent(Deprecated.class)) {
64 continue;
65 }
66
67
68 if (constructor.getParameterCount() == 0) {
69 try {
70 return (T) constructor.newInstance();
71 } catch (final InstantiationException | IllegalAccessException | InvocationTargetException e) {
72 Assertions.fail(String.format(
73 "An exception was thrown while testing class no-arg constructor (new instance) '%s': '%s'",
74 constructor.getName(), e.toString()));
75 }
76 }
77 }
78
79
80 for (final Constructor<?> constructor : clazz.getConstructors()) {
81
82
83 if (constructor.isAnnotationPresent(Deprecated.class)) {
84 continue;
85 }
86
87 final Class<?>[] types = constructor.getParameterTypes();
88
89 final Object[] values = new Object[constructor.getParameterTypes().length];
90
91
92 for (int i = 0; i < values.length; i++) {
93 values[i] = this.buildValue(types[i], LoadType.STANDARD_DATA);
94 }
95
96 try {
97 return (T) constructor.newInstance(values);
98 } catch (final InstantiationException | IllegalAccessException | InvocationTargetException e) {
99 Assertions.fail(String.format(
100 "An exception was thrown while testing the class (new instance) '%s' with '%s': '%s'",
101 constructor.getName(), Arrays.toString(values), e.toString()));
102 }
103 }
104 return null;
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 @SuppressWarnings("unchecked")
127 private T createInstanceWithBuilder(final Class<T> clazz, final Method builderMethod) throws IllegalAccessException,
128 IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
129
130 final T builder = (T) builderMethod.invoke(null);
131
132 Method buildMethod = builder.getClass().getMethod("build");
133
134 return (T) buildMethod.invoke(builder);
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149 public <R> Object buildValue(final Class<R> returnType, final LoadType loadType) {
150 final ValueBuilder valueBuilder = new ValueBuilder();
151 valueBuilder.setLoadData(LoadData.ON);
152 return valueBuilder.buildValue(returnType, loadType);
153 }
154
155 }