Skip to content

Commit a15edfa

Browse files
authored
Merge pull request #1562 from xael-fry/globla-unbinder
support for (custom) @global unbinders added
2 parents 11c69a9 + 77cb544 commit a15edfa

1 file changed

Lines changed: 37 additions & 1 deletion

File tree

framework/src/play/data/binding/Unbinder.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22

33
import java.lang.annotation.Annotation;
44
import java.lang.reflect.Array;
5+
import java.lang.reflect.Constructor;
56
import java.lang.reflect.Field;
7+
import java.lang.reflect.InvocationTargetException;
8+
import java.lang.reflect.ParameterizedType;
69
import java.math.BigDecimal;
710
import java.text.SimpleDateFormat;
811
import java.util.*;
912

13+
import play.Logger;
1014
import play.Play;
15+
import play.exceptions.UnexpectedException;
1116
import play.libs.I18N;
1217

1318
/**
@@ -149,7 +154,24 @@ private static void unBind(Map<String, Object> result, Object src, Class<?> srcC
149154
result.putAll(r);
150155
return;
151156
}
152-
157+
158+
// application custom types have higher priority. If unable to bind proceed with the next one
159+
for (Class<TypeUnbinder<?>> c : Play.classloader.getAssignableClasses(TypeUnbinder.class)) {
160+
if (c.isAnnotationPresent(Global.class)) {
161+
Class<?> forType = (Class<?>) ((ParameterizedType) c.getGenericInterfaces()[0]).getActualTypeArguments()[0];
162+
if (forType.isAssignableFrom(srcClazz)) {
163+
try {
164+
boolean _r = createNewInstance(c).unBind(result, src, srcClazz, name, annotations);
165+
if (_r) {
166+
return;
167+
}
168+
} catch (Exception e) {
169+
// ...
170+
}
171+
}
172+
}
173+
}
174+
153175
if (isDirect(srcClazz) || src == null) {
154176
directUnbind(result, src, srcClazz, name, annotations);
155177
}else if (src.getClass().isArray()) {
@@ -198,4 +220,18 @@ private static void unBind(Map<String, Object> result, Object src, Class<?> srcC
198220
public static boolean isDirect(Class<?> clazz) {
199221
return clazz.equals(String.class) || clazz.equals(Integer.class) || Enum.class.isAssignableFrom(clazz) || clazz.equals(Boolean.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.isPrimitive() || clazz.equals(Class.class);
200222
}
223+
224+
private static <T> T createNewInstance(Class<T> clazz) {
225+
try {
226+
Constructor<T> constructor = clazz.getDeclaredConstructor();
227+
constructor.setAccessible(true);
228+
return constructor.newInstance();
229+
} catch (InstantiationException | IllegalAccessException e) {
230+
Logger.warn("Failed to create instance of %s: %s", clazz.getName(), e);
231+
throw new UnexpectedException(e);
232+
} catch (NoSuchMethodException | InvocationTargetException e) {
233+
Logger.error("Failed to create instance of %s: %s", clazz.getName(), e);
234+
throw new UnexpectedException(e);
235+
}
236+
}
201237
}

0 commit comments

Comments
 (0)