1 |
526 |
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
package org.apache.commons.betwixt.io.read; |
17 |
|
|
18 |
|
import java.beans.IntrospectionException; |
19 |
|
import java.lang.reflect.Constructor; |
20 |
|
|
21 |
|
import org.apache.commons.betwixt.ElementDescriptor; |
22 |
|
import org.apache.commons.betwixt.XMLBeanInfo; |
23 |
|
import org.apache.commons.logging.Log; |
24 |
|
|
25 |
|
|
26 |
|
|
27 |
|
|
28 |
|
|
29 |
|
|
30 |
|
|
31 |
|
|
32 |
406 |
public class ChainedBeanCreatorFactory { |
33 |
120 |
|
34 |
406 |
private static final Class[] EMPTY_CLASS_ARRAY = {}; |
35 |
526 |
private static final Object[] EMPTY_OBJECT_ARRAY = {}; |
36 |
120 |
|
37 |
|
|
38 |
406 |
private static final ChainedBeanCreator derivedBeanCreator |
39 |
406 |
= new ChainedBeanCreator() { |
40 |
120 |
public Object create( |
41 |
|
ElementMapping elementMapping, |
42 |
|
ReadContext context, |
43 |
|
BeanCreationChain chain) { |
44 |
|
|
45 |
2756 |
Log log = context.getLog(); |
46 |
3572 |
String className |
47 |
3572 |
= elementMapping |
48 |
3572 |
.getAttributes().getValue( context.getClassNameAttribute() ); |
49 |
3572 |
if ( className != null ) { |
50 |
816 |
try { |
51 |
|
|
52 |
90 |
ClassLoader classLoader = context.getClassLoader(); |
53 |
117 |
Class clazz = null; |
54 |
117 |
if ( classLoader == null ) { |
55 |
27 |
log.warn("Read context classloader not set." ); |
56 |
0 |
} else { |
57 |
|
try |
58 |
|
{ |
59 |
90 |
clazz = classLoader.loadClass( className ); |
60 |
27 |
} catch (ClassNotFoundException e) { |
61 |
0 |
log.info("Class not found in context classloader:"); |
62 |
0 |
log.debug(clazz, e); |
63 |
0 |
} |
64 |
|
} |
65 |
90 |
if (clazz == null) { |
66 |
27 |
clazz = Class.forName(className); |
67 |
0 |
} |
68 |
90 |
return newInstance(clazz, log); |
69 |
27 |
|
70 |
0 |
} catch (Exception e) { |
71 |
0 |
|
72 |
0 |
log.warn( "Could not create instance of type: " + className ); |
73 |
0 |
log.debug( "Create new instance failed: ", e ); |
74 |
0 |
return null; |
75 |
0 |
} |
76 |
|
|
77 |
|
} else { |
78 |
|
|
79 |
2666 |
return chain.create( elementMapping, context ); |
80 |
789 |
} |
81 |
|
} |
82 |
|
}; |
83 |
|
|
84 |
|
|
85 |
|
|
86 |
|
|
87 |
|
|
88 |
|
|
89 |
|
public static final ChainedBeanCreator createDerivedBeanCreator() { |
90 |
886 |
return derivedBeanCreator; |
91 |
264 |
} |
92 |
|
|
93 |
|
|
94 |
|
|
95 |
|
|
96 |
|
|
97 |
|
|
98 |
|
|
99 |
|
|
100 |
|
|
101 |
2608 |
private static final Object newInstance(Class theClass, Log log) throws Exception { |
102 |
3385 |
Object result = null; |
103 |
777 |
try { |
104 |
2608 |
Constructor constructor = theClass.getConstructor(EMPTY_CLASS_ARRAY); |
105 |
3375 |
if (!constructor.isAccessible()) { |
106 |
3372 |
constructor.setAccessible(true); |
107 |
774 |
} |
108 |
2598 |
result = constructor.newInstance(EMPTY_OBJECT_ARRAY); |
109 |
774 |
} catch (SecurityException e) { |
110 |
0 |
log.debug("Cannot force accessibility to constructor", e); |
111 |
0 |
|
112 |
10 |
} catch (NoSuchMethodException e) { |
113 |
13 |
if (log.isDebugEnabled()) { |
114 |
3 |
log.debug("Class " + theClass + " has no empty constructor."); |
115 |
0 |
} |
116 |
|
} |
117 |
|
|
118 |
2608 |
if (result == null) { |
119 |
787 |
result = theClass.newInstance(); |
120 |
3 |
} |
121 |
2598 |
return result; |
122 |
774 |
} |
123 |
|
|
124 |
|
|
125 |
406 |
private static final ChainedBeanCreator elementTypeBeanCreator |
126 |
406 |
= new ChainedBeanCreator() { |
127 |
120 |
public Object create( |
128 |
|
ElementMapping element, |
129 |
|
ReadContext context, |
130 |
|
BeanCreationChain chain) { |
131 |
|
|
132 |
2666 |
Log log = context.getLog(); |
133 |
3455 |
Class theClass = null; |
134 |
789 |
|
135 |
2666 |
ElementDescriptor descriptor = element.getDescriptor(); |
136 |
3455 |
if ( descriptor != null ) { |
137 |
789 |
|
138 |
2666 |
theClass = context.resolvePolymorphicType(element); |
139 |
789 |
|
140 |
2666 |
if (theClass == null) |
141 |
789 |
{ |
142 |
|
|
143 |
2484 |
theClass = descriptor.getImplementationClass(); |
144 |
738 |
} |
145 |
|
} |
146 |
|
|
147 |
2666 |
if ( theClass == null ) { |
148 |
789 |
|
149 |
2484 |
theClass = element.getType(); |
150 |
738 |
} |
151 |
|
|
152 |
2666 |
if (descriptor != null && descriptor.isPolymorphic()) { |
153 |
789 |
|
154 |
|
try { |
155 |
380 |
XMLBeanInfo xmlBeanInfo = context.getXMLIntrospector().introspect(theClass); |
156 |
485 |
String namespace = element.getNamespace(); |
157 |
485 |
String name = element.getName(); |
158 |
485 |
if (namespace == null) { |
159 |
105 |
if (!name.equals(xmlBeanInfo.getElementDescriptor().getQualifiedName())) { |
160 |
0 |
context.getLog().debug("Polymorphic type does not match element"); |
161 |
0 |
return null; |
162 |
0 |
} |
163 |
380 |
} else if (!namespace.equals(xmlBeanInfo.getElementDescriptor().getURI()) |
164 |
485 |
|| !name.equals(xmlBeanInfo.getElementDescriptor().getLocalName())) { |
165 |
253 |
context.getLog().debug("Polymorphic type does not match element"); |
166 |
187 |
return null; |
167 |
39 |
} |
168 |
0 |
} catch (IntrospectionException e) { |
169 |
0 |
context.getLog().warn( |
170 |
0 |
"Could not introspect type to test introspection: " + theClass.getName() ); |
171 |
0 |
context.getLog().debug( "Introspection failed: ", e ); |
172 |
0 |
return null; |
173 |
0 |
} |
174 |
|
|
175 |
|
} |
176 |
|
|
177 |
2518 |
if ( log.isTraceEnabled() ) { |
178 |
750 |
log.trace( |
179 |
0 |
"Creating instance of class " + theClass.getName() |
180 |
0 |
+ " for element " + element.getName()); |
181 |
0 |
} |
182 |
|
|
183 |
|
try { |
184 |
|
|
185 |
2518 |
Object result = newInstance(theClass, log); |
186 |
3258 |
return result; |
187 |
747 |
|
188 |
10 |
} catch (Exception e) { |
189 |
3 |
|
190 |
20 |
context.getLog().warn( |
191 |
16 |
"Could not create instance of type: " + theClass.getName() ); |
192 |
13 |
context.getLog().debug( "Create new instance failed: ", e ); |
193 |
13 |
return null; |
194 |
3 |
} |
195 |
|
} |
196 |
|
}; |
197 |
|
|
198 |
|
|
199 |
|
|
200 |
|
|
201 |
|
|
202 |
|
public static final ChainedBeanCreator createElementTypeBeanCreator() { |
203 |
886 |
return elementTypeBeanCreator; |
204 |
264 |
} |
205 |
|
|
206 |
|
|
207 |
406 |
private static final ChainedBeanCreator idRefBeanCreator |
208 |
406 |
= new ChainedBeanCreator() { |
209 |
120 |
public Object create( |
210 |
|
ElementMapping elementMapping, |
211 |
|
ReadContext context, |
212 |
|
BeanCreationChain chain) { |
213 |
2826 |
if ( context.getMapIDs() ) { |
214 |
3187 |
String idref = elementMapping.getAttributes().getValue( "idref" ); |
215 |
3055 |
if ( idref != null ) { |
216 |
705 |
|
217 |
|
|
218 |
|
|
219 |
|
|
220 |
30 |
context.getLog().trace( "Found IDREF" ); |
221 |
39 |
Object bean = context.getBean( idref ); |
222 |
39 |
if ( bean != null ) { |
223 |
39 |
if ( context.getLog().isTraceEnabled() ) { |
224 |
9 |
context.getLog().trace( "Matched bean " + bean ); |
225 |
0 |
} |
226 |
30 |
return bean; |
227 |
9 |
} |
228 |
0 |
context.getLog().trace( "No match found" ); |
229 |
0 |
} |
230 |
|
} |
231 |
2796 |
return chain.create( elementMapping, context ); |
232 |
828 |
} |
233 |
|
}; |
234 |
|
|
235 |
|
|
236 |
|
|
237 |
|
|
238 |
|
|
239 |
|
public static final ChainedBeanCreator createIDREFBeanCreator() { |
240 |
886 |
return idRefBeanCreator; |
241 |
264 |
} |
242 |
|
} |