Skip to content

Commit c5a38dd

Browse files
committed
Introduce PropifyException and ReflectionUtils for improved error handling and reflection
1 parent 61ec6eb commit c5a38dd

8 files changed

Lines changed: 77 additions & 17 deletions

File tree

propify/src/main/java/com/vgerbot/propify/PropifyProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.vgerbot.propify.loader.CompileTimeResourceLoaderProvider;
1010
import com.vgerbot.propify.logger.CompileTimeLogger;
1111
import org.apache.commons.configuration2.Configuration;
12+
import com.vgerbot.propify.common.PropifyException;
1213

1314
import javax.annotation.processing.*;
1415
import javax.lang.model.SourceVersion;
@@ -138,7 +139,7 @@ public boolean process(final Set<? extends TypeElement> annotations, final Round
138139
"Failed to process annotation: " + message, element);
139140
}
140141
} else {
141-
throw new RuntimeException(e);
142+
throw new PropifyException("Failed to process annotation", e);
142143
}
143144
}
144145
}

propify/src/main/java/com/vgerbot/propify/common/FlatDottedMapConfiguration.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
1212
import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
1313

14+
import com.vgerbot.propify.common.ReflectionUtils;
15+
1416
/**
1517
* A configuration class that extends MapConfiguration to provide support for accessing
1618
* nested properties using dot notation and array/list indexing.
@@ -212,8 +214,7 @@ private Object getNestedProperty(Object container, String propertyKey) {
212214
return ((Map<?, ?>) container).get(propertyKey);
213215
} else {
214216
try {
215-
Field field = container.getClass().getDeclaredField(propertyKey);
216-
field.setAccessible(true);
217+
Field field = ReflectionUtils.getDeclaredField(container.getClass(), propertyKey);
217218
return field.get(container);
218219
} catch (Exception e) {
219220
return null;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.vgerbot.propify.common;
2+
3+
public class PropifyException extends RuntimeException {
4+
public PropifyException(String message) {
5+
super(message);
6+
}
7+
8+
public PropifyException(String message, Throwable cause) {
9+
super(message, cause);
10+
}
11+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.vgerbot.propify.common;
2+
3+
import java.lang.reflect.AccessibleObject;
4+
import java.lang.reflect.Field;
5+
import java.lang.reflect.Method;
6+
import java.lang.reflect.Constructor;
7+
8+
public class ReflectionUtils {
9+
private ReflectionUtils() {
10+
throw new PropifyException("Cannot instantiate ReflectionUtils class");
11+
}
12+
13+
public static void makeAccessible(AccessibleObject object) {
14+
if (!object.isAccessible()) {
15+
object.setAccessible(true);
16+
}
17+
}
18+
19+
public static <T> Constructor<T> getDeclaredConstructor(Class<T> clazz, Class<?>... parameterTypes) {
20+
try {
21+
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
22+
makeAccessible(constructor);
23+
return constructor;
24+
} catch (NoSuchMethodException e) {
25+
throw new PropifyException("Failed to get constructor", e);
26+
}
27+
}
28+
29+
public static Field getDeclaredField(Class<?> clazz, String fieldName) {
30+
try {
31+
Field field = clazz.getDeclaredField(fieldName);
32+
makeAccessible(field);
33+
return field;
34+
} catch (NoSuchFieldException e) {
35+
throw new PropifyException("Failed to get field", e);
36+
}
37+
}
38+
39+
public static Method getDeclaredMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
40+
try {
41+
Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
42+
makeAccessible(method);
43+
return method;
44+
} catch (NoSuchMethodException e) {
45+
throw new PropifyException("Failed to get method", e);
46+
}
47+
}
48+
}

propify/src/main/java/com/vgerbot/propify/common/Utils.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class Utils {
2929
)));
3030

3131
private Utils() {
32-
throw new RuntimeException("Cannot instantiate Utils class");
32+
throw new PropifyException("Cannot instantiate Utils class");
3333
}
3434

3535
/**
@@ -236,13 +236,12 @@ public static String[] getClassesFromAnnotationValue(AnnotationValue annotationV
236236
Object type = getValueMethod.invoke(classInfo);
237237
return type.toString();
238238
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
239-
throw new RuntimeException(e);
239+
throw new PropifyException("Failed to get class info", e);
240240
}
241241
}).toArray(String[]::new);
242242
}
243243
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
244-
System.err.println("access javac util list error" + e.toString());
245-
throw new RuntimeException(e);
244+
throw new PropifyException("Failed to access javac util list", e);
246245
}
247246
}
248247
return new String[]{};

propify/src/main/java/com/vgerbot/propify/core/PropifyContext.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.vgerbot.propify.lookup.PropifyLookup;
66
import com.vgerbot.propify.lookup.PropifyLookupAdaptor;
77
import org.apache.commons.configuration2.interpol.Lookup;
8+
import com.vgerbot.propify.common.PropifyException;
9+
import com.vgerbot.propify.common.ReflectionUtils;
810

911
import java.io.IOException;
1012
import java.io.InputStream;
@@ -168,12 +170,10 @@ public Map<String, Lookup> getAllLookups() {
168170
return Arrays.stream(this.lookups).map(it -> {
169171
try {
170172
Class<PropifyLookup> cls = (Class<PropifyLookup>)Class.forName(it);
171-
Constructor<PropifyLookup> constructor = cls.getDeclaredConstructor();
172-
constructor.setAccessible(true);
173+
Constructor<PropifyLookup> constructor = ReflectionUtils.getDeclaredConstructor(cls);
173174
return constructor.newInstance();
174-
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException |
175-
InvocationTargetException e) {
176-
throw new RuntimeException(e);
175+
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
176+
throw new PropifyException("Failed to instantiate lookup class", e);
177177
}
178178
}).collect(Collectors.toMap(PropifyLookup::getPrefix, PropifyLookupAdaptor::new));
179179
}

propify/src/main/java/com/vgerbot/propify/i18n/PropifyI18nResourceBundle.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.concurrent.ConcurrentHashMap;
66
import java.util.stream.Collectors;
77
import java.util.stream.IntStream;
8+
import com.vgerbot.propify.common.PropifyException;
89

910
public class PropifyI18nResourceBundle {
1011
private final String baseName;
@@ -25,7 +26,7 @@ public <T> T getMessageBundle(Class<T> type, Locale locale) {
2526
return Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, (proxy, method, args) -> {
2627
Message annotation = method.getAnnotation(Message.class);
2728
if (annotation == null) {
28-
throw new RuntimeException(method + " is not annotated with @Message");
29+
throw new PropifyException(method + " is not annotated with @Message");
2930
}
3031
String keyName = annotation.key();
3132
String[] arguments = annotation.arguments();

propify/src/test/java/com/vgerbot/propify/PropifyProcessorTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.vgerbot.propify.core.Propify;
44
import com.vgerbot.propify.i18n.I18n;
5+
import com.vgerbot.propify.common.ReflectionUtils;
56
import org.junit.Before;
67
import org.junit.Test;
78
import org.mockito.Mock;
@@ -73,10 +74,8 @@ public void setUp() {
7374
public void testInit() throws NoSuchFieldException, IllegalAccessException {
7475
// Verify that the processor was initialized correctly
7576
assertEquals(processingEnv, PropifyProcessor.processingEnvironment);
76-
Field field = processor.getClass().getDeclaredField("messager");
77-
field.setAccessible(true);
78-
79-
assertNotNull("Messager should be initialized", field.get(processor));
77+
Field field = ReflectionUtils.getDeclaredField(PropifyProcessor.class, "messager");
78+
assertEquals(messager, field.get(processor));
8079
}
8180

8281
@Test

0 commit comments

Comments
 (0)