1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.bindings.core.general.binding;
17
18 import java.lang.invoke.MethodHandle;
19 import java.lang.invoke.MethodHandles;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22
23 import org.jadira.bindings.core.api.Binding;
24 import org.jadira.bindings.core.api.BindingException;
25 import org.jadira.bindings.core.general.marshaller.MethodToMarshaller;
26
27
28
29
30
31
32
33
34
35
36
37 public final class MethodsBinding<S, T> extends MethodToMarshaller<S, T> implements Binding<S, T> {
38
39 private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
40
41 private final MethodHandle unmarshalHandle;
42
43
44
45
46
47
48
49
50 public MethodsBinding(Method marshal, Method unmarshal, Class<S> boundClass, Class<T> targetClass) {
51
52 super(boundClass, targetClass, marshal);
53
54 if (unmarshal.getParameterTypes().length != 1) {
55 throw new IllegalStateException("unmarshal method must define a single parameter");
56 }
57 if (!Modifier.isStatic(unmarshal.getModifiers())) {
58 throw new IllegalStateException("unmarshal method must be defined as static");
59 }
60
61 if (unmarshal.getParameterTypes()[0] != targetClass) {
62 throw new IllegalStateException("unmarshal method must be parameterized by " + targetClass.getSimpleName());
63 }
64 if (!boundClass.isAssignableFrom(unmarshal.getReturnType())) {
65 throw new IllegalStateException("unmarshal method must return " + boundClass.getSimpleName());
66 }
67
68 try {
69 this.unmarshalHandle = LOOKUP.unreflect(unmarshal);
70 } catch (IllegalAccessException e) {
71 throw new IllegalStateException("Method is not accessible" + unmarshal);
72 }
73 }
74
75
76
77
78
79 public S unmarshal(T string) {
80
81 try {
82 return getBoundClass().cast(unmarshalHandle.invoke(string));
83 } catch (Throwable ex) {
84 if (ex.getCause() instanceof RuntimeException) {
85 throw (RuntimeException) ex.getCause();
86 }
87 throw new BindingException(ex.getMessage(), ex.getCause());
88 }
89 }
90 }