1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.betwixt.io.read;
18
19 import java.util.Map;
20
21 import org.apache.commons.betwixt.AttributeDescriptor;
22 import org.apache.commons.betwixt.ElementDescriptor;
23 import org.apache.commons.betwixt.TextDescriptor;
24 import org.apache.commons.betwixt.XMLBeanInfo;
25 import org.apache.commons.betwixt.expression.Updater;
26 import org.apache.commons.logging.Log;
27 import org.xml.sax.Attributes;
28
29
30
31
32
33
34
35 public class BeanBindAction extends MappingAction.Base {
36
37
38 public static final BeanBindAction INSTANCE = new BeanBindAction();
39
40
41
42
43 public MappingAction begin(
44 String namespace,
45 String name,
46 Attributes attributes,
47 ReadContext context)
48 throws Exception {
49
50 Log log = context.getLog();
51
52 ElementDescriptor computedDescriptor = context.getCurrentDescriptor();
53
54 if (log.isTraceEnabled()) {
55 log.trace("Element Pushed: " + name);
56 }
57
58
59 MappingAction action = MappingAction.EMPTY;
60
61 Object instance = null;
62 Class beanClass = null;
63 if (computedDescriptor == null) {
64 log.trace("No Descriptor");
65 } else {
66 beanClass = computedDescriptor.getSingularPropertyType();
67 }
68
69
70 if (beanClass != null && !Map.class.isAssignableFrom(beanClass)) {
71
72 instance =
73 createBean(
74 namespace,
75 name,
76 attributes,
77 computedDescriptor,
78 context);
79
80 if (instance != null) {
81 action = this;
82 if (computedDescriptor.isUseBindTimeTypeForMapping())
83 {
84 beanClass = instance.getClass();
85 }
86 context.markClassMap(beanClass);
87
88 if (log.isTraceEnabled()) {
89 log.trace("Marked: " + beanClass);
90 }
91
92 context.pushBean(instance);
93
94
95
96
97
98 ElementDescriptor typeDescriptor =
99 getElementDescriptor(computedDescriptor, context);
100
101
102 AttributeDescriptor[] attributeDescriptors =
103 typeDescriptor.getAttributeDescriptors();
104 context.populateAttributes(attributeDescriptors, attributes);
105
106 if (log.isTraceEnabled()) {
107 log.trace("Created bean " + instance);
108 }
109
110
111 if (context.getMapIDs()) {
112
113
114
115 String id = attributes.getValue("id");
116 if (id != null) {
117 context.putBean(id, instance);
118 }
119 }
120 }
121 }
122 return action;
123 }
124
125
126 public void body(String text, ReadContext context) throws Exception {
127 Log log = context.getLog();
128
129 ElementDescriptor currentDescriptor = context.getCurrentDescriptor();
130 if (currentDescriptor == null) {
131 if (log.isTraceEnabled()) {
132 log.trace("path descriptor is null:");
133 }
134 } else {
135 TextDescriptor bodyTextdescriptor =
136 currentDescriptor.getPrimaryBodyTextDescriptor();
137 if (bodyTextdescriptor != null) {
138 if (log.isTraceEnabled()) {
139 log.trace("Setting mixed content for:");
140 log.trace(bodyTextdescriptor);
141 }
142 Updater updater = bodyTextdescriptor.getUpdater();
143 if (log.isTraceEnabled())
144 {
145 log.trace("Updating mixed content with:");
146 log.trace(updater);
147 }
148 if (updater != null && text != null) {
149 updater.update(context, text);
150 }
151 }
152 }
153 }
154
155 public void end(ReadContext context) throws Exception {
156
157 Object instance = context.popBean();
158 update(context, instance);
159 }
160
161 private void update(ReadContext context, Object value) throws Exception {
162 Log log = context.getLog();
163
164 Updater updater = context.getCurrentUpdater();
165
166 if ( updater == null ) {
167 if ( context.getLog().isTraceEnabled() ) {
168 context.getLog().trace("No updater for " + context.getCurrentElement());
169 }
170 } else {
171 updater.update(context, value);
172 }
173
174 String poppedElement = context.popElement();
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188 protected Object createBean(
189 String namespace,
190 String name,
191 Attributes attributes,
192 ElementDescriptor descriptor,
193 ReadContext context) {
194
195
196 ElementMapping mapping = new ElementMapping();
197 Class beanClass = descriptor.getSingularPropertyType();
198 if (beanClass != null && beanClass.isArray()) {
199 beanClass = beanClass.getComponentType();
200 }
201
202
203
204 mapping.setType(beanClass);
205 mapping.setNamespace(namespace);
206 mapping.setName(name);
207 mapping.setAttributes(attributes);
208 mapping.setDescriptor(descriptor);
209
210 Object newInstance =
211 context.getBeanCreationChain().create(mapping, context);
212
213 return newInstance;
214 }
215
216
217
218
219
220
221
222
223
224
225
226 private ElementDescriptor getElementDescriptor(
227 ElementDescriptor propertyDescriptor,
228 ReadContext context) {
229 Log log = context.getLog();
230 Class beanClass = propertyDescriptor.getSingularPropertyType();
231 if (propertyDescriptor.isUseBindTimeTypeForMapping()) {
232
233 Object current = context.getBean();
234 if (current != null) {
235 beanClass = current.getClass();
236 }
237 }
238 if (beanClass != null && !Map.class.isAssignableFrom(beanClass)) {
239 if (beanClass.isArray()) {
240 beanClass = beanClass.getComponentType();
241 }
242
243
244
245 if (log.isTraceEnabled()) {
246 log.trace("Filling descriptor for: " + beanClass);
247 }
248 try {
249 XMLBeanInfo xmlInfo =
250 context.getXMLIntrospector().introspect(beanClass);
251 return xmlInfo.getElementDescriptor();
252
253 } catch (Exception e) {
254 log.warn("Could not introspect class: " + beanClass, e);
255 }
256 }
257
258 return propertyDescriptor;
259 }
260
261 }