1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.bindings.core.general.unmarshaller;
17
18 import java.lang.reflect.Constructor;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Modifier;
21
22 import org.jadira.bindings.core.api.BindingException;
23 import org.jadira.bindings.core.api.FromUnmarshaller;
24
25
26
27
28
29
30 public final class ConstructorFromUnmarshaller<S, T> implements FromUnmarshaller<S, T> {
31
32 private final Constructor<S> unmarshal;
33
34 private final Class<S> boundClass;
35
36 private final Class<T> targetClass;
37
38
39
40
41
42 public ConstructorFromUnmarshaller(Constructor<S> unmarshal) {
43
44 this.boundClass = unmarshal.getDeclaringClass();
45
46 if (getBoundClass().isInterface()
47 || Modifier.isAbstract(getBoundClass().getModifiers())
48 || getBoundClass().isLocalClass()
49 || getBoundClass().isMemberClass()) {
50 throw new IllegalStateException("unmarshal constructor must have an instantiable target class");
51 }
52
53 if (unmarshal.getParameterTypes().length != 1) {
54 throw new IllegalStateException("unmarshal constructor must have a single parameter");
55 }
56
57 this.unmarshal = unmarshal;
58
59 @SuppressWarnings("unchecked")
60 Class<T> myTarget = (Class<T>)unmarshal.getParameterTypes()[0];
61 this.targetClass = myTarget;
62 }
63
64
65
66
67
68 public S unmarshal(T object) {
69
70 if (object != null && !targetClass.isAssignableFrom(object.getClass())) {
71 throw new IllegalArgumentException("Supplied object was not instance of target class");
72 }
73
74 try {
75 return unmarshal.newInstance(object);
76 } catch (IllegalAccessException ex) {
77 throw new IllegalStateException("Constructor is not accessible");
78 } catch (InstantiationException ex) {
79 throw new IllegalStateException("Constructor is not valid");
80 } catch (InvocationTargetException ex) {
81 if (ex.getCause() instanceof RuntimeException) {
82 throw (RuntimeException) ex.getCause();
83 }
84 throw new BindingException(ex.getMessage(), ex.getCause());
85 }
86 }
87
88
89
90
91
92 public Class<S> getBoundClass() {
93 return boundClass;
94 }
95
96
97
98
99
100 public Class<T> getTargetClass() {
101 return targetClass;
102 }
103 }