1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.exolab.castor.builder.factory;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.exolab.castor.builder.BuilderConfiguration;
20 import org.exolab.castor.builder.info.CollectionInfo;
21 import org.exolab.castor.builder.info.FieldInfo;
22 import org.exolab.castor.builder.info.NodeType;
23 import org.exolab.castor.builder.info.nature.XMLInfoNature;
24 import org.exolab.castor.builder.types.XSClass;
25 import org.exolab.castor.builder.types.XSListType;
26 import org.exolab.castor.builder.types.XSType;
27 import org.exolab.javasource.JClass;
28 import org.exolab.javasource.JSourceCode;
29
30
31
32
33
34
35
36
37 public final class XMLFieldHandlerFactory {
38
39
40
41
42 private BuilderConfiguration _config;
43
44
45
46
47
48 public XMLFieldHandlerFactory(final BuilderConfiguration config) {
49 _config = config;
50 }
51
52
53
54
55
56
57
58
59
60
61
62 public void createXMLFieldHandler(final FieldInfo member,
63 final XSType xsType, final String localClassName,
64 final JSourceCode jsc, final boolean forGeneralizedHandler) {
65
66 XMLInfoNature xmlNature = new XMLInfoNature(member);
67
68 boolean any = false;
69 boolean isEnumerated = false;
70
71
72 if (member.getName().equals("_anyObject")) {
73 any = true;
74 }
75
76 if (xsType.getType() == XSType.CLASS) {
77 isEnumerated = ((XSClass) xsType).isEnumerated();
78 }
79
80 jsc.add("handler = new org.exolab.castor.xml.XMLFieldHandler() {");
81 jsc.indent();
82
83 createGetValueMethod(member, xsType, localClassName, jsc);
84
85 NodeType nodeType = xmlNature.getNodeType();
86 boolean isAttribute = (nodeType == NodeType.ATTRIBUTE);
87 boolean isContent = (nodeType == NodeType.TEXT);
88
89 createSetValueMethod(member, xsType, localClassName, jsc, any, isAttribute, isContent);
90 createResetMethod(member, localClassName, jsc);
91 createNewInstanceMethod(member, xsType, jsc, forGeneralizedHandler, any, isEnumerated);
92
93 jsc.unindent();
94 jsc.add("};");
95 }
96
97
98
99
100
101
102
103
104
105 private void createGetValueMethod(final FieldInfo member, final XSType xsType,
106 final String localClassName, final JSourceCode jsc) {
107
108
109 XMLInfoNature xmlNature = new XMLInfoNature(member);
110
111 if (_config.useJava50()) {
112 jsc.add("@Override");
113 }
114 jsc.add("public java.lang.Object getValue( java.lang.Object object ) ");
115 jsc.indent();
116 jsc.add("throws IllegalStateException");
117 jsc.unindent();
118 jsc.add("{");
119 jsc.indent();
120 jsc.add(localClassName);
121 jsc.append(" target = (");
122 jsc.append(localClassName);
123 jsc.append(") object;");
124
125 if ((!xsType.isEnumerated()) && (xsType.getJType().isPrimitive())
126 && (!xmlNature.isMultivalued())) {
127 jsc.add("if (!target." + member.getHasMethodName() + "()) { return null; }");
128 }
129
130 jsc.add("return ");
131 String value = "target." + member.getReadMethodName() + "()";
132 if (xmlNature.isMultivalued()) {
133 jsc.append(value);
134 } else {
135 jsc.append(xsType.createToJavaObjectCode(value));
136 }
137 jsc.append(";");
138 jsc.unindent();
139 jsc.add("}");
140
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155 private void createSetValueMethod(final FieldInfo member,
156 final XSType xsType, final String localClassName,
157 final JSourceCode jsc, final boolean any, final boolean isAttribute,
158 final boolean isContent) {
159 if (_config.useJava50()) {
160 jsc.add("@Override");
161 }
162 jsc.add("public void setValue( java.lang.Object object, java.lang.Object value) ");
163 jsc.indent();
164 jsc.add("throws IllegalStateException, IllegalArgumentException");
165 jsc.unindent();
166 jsc.add("{");
167 jsc.indent();
168 jsc.add("try {");
169 jsc.indent();
170 jsc.add(localClassName);
171 jsc.append(" target = (");
172 jsc.append(localClassName);
173 jsc.append(") object;");
174
175
176 XMLInfoNature xmlNature = new XMLInfoNature(member);
177
178 if (xsType.isPrimitive() && !_config.usePrimitiveWrapper()) {
179 if ((!xmlNature.isRequired()) && (!xsType.isEnumerated())
180 && (!xmlNature.isMultivalued())) {
181 jsc
182 .add("// if null, use delete method for optional primitives ");
183 jsc.add("if (value == null) {");
184 jsc.indent();
185 jsc.add("target.");
186 jsc.append(member.getDeleteMethodName());
187 jsc.append("();");
188 jsc.add("return;");
189 jsc.unindent();
190 jsc.add("}");
191 } else {
192 jsc.add("// ignore null values for non optional primitives");
193 jsc.add("if (value == null) { return; }");
194 jsc.add("");
195 }
196 }
197
198 if (xsType.isEnumerated() && StringUtils.isNotEmpty(member.getDefaultValue())) {
199 jsc.add("// default value supplied; as such, do not inject null values");
200 jsc.add("if (value == null) {");
201 jsc.addIndented("return;");
202 jsc.add("}");
203 jsc.add("");
204
205 }
206 jsc.add("target.");
207 jsc.append(member.getWriteMethodName());
208 jsc.append("( ");
209 if (xsType.isPrimitive() && !_config.usePrimitiveWrapper()) {
210 jsc.append(xsType.createFromJavaObjectCode("value"));
211 } else if (any) {
212 jsc.append(" value ");
213 } else {
214 jsc.append("(");
215 jsc.append(xsType.getJType().toString());
216
217
218
219
220
221
222
223 if ((isAttribute | isContent) && xsType.isDateTime()
224 && xsType.getType() != XSType.DATETIME_TYPE) {
225 jsc.append(".parse");
226 jsc.append(_config.getJavaNaming().toJavaClassName(xsType.getName()));
227 jsc.append("((java.lang.String) value))");
228 } else {
229 jsc.append(") value");
230 }
231 }
232 jsc.append(");");
233
234 jsc.unindent();
235 jsc.add("} catch (java.lang.Exception ex) {");
236 jsc.indent();
237 jsc.add("throw new IllegalStateException(ex.toString());");
238 jsc.unindent();
239 jsc.add("}");
240 jsc.unindent();
241 jsc.add("}");
242
243 }
244
245
246
247
248
249
250
251
252 private void createResetMethod(final FieldInfo member,
253 final String localClassName,
254 final JSourceCode jsc) {
255
256 if (new XMLInfoNature(member).isMultivalued()) {
257 CollectionInfo cInfo = (CollectionInfo) member;
258
259 jsc.add("public void resetValue(Object object)"
260 + " throws IllegalStateException, IllegalArgumentException {");
261 jsc.indent();
262 jsc.add("try {");
263 jsc.indent();
264 jsc.add(localClassName);
265 jsc.append(" target = (");
266 jsc.append(localClassName);
267 jsc.append(") object;");
268 String cName = _config.getJavaNaming().toJavaClassName(cInfo.getElementName());
269
270
271
272 jsc.add("target.removeAll" + cName + "();");
273
274 jsc.unindent();
275 jsc.add("} catch (java.lang.Exception ex) {");
276 jsc.indent();
277 jsc.add("throw new IllegalStateException(ex.toString());");
278 jsc.unindent();
279 jsc.add("}");
280 jsc.unindent();
281 jsc.add("}");
282 }
283
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297
298 private void createNewInstanceMethod(final FieldInfo member,
299 final XSType xsType, final JSourceCode jsc,
300 final boolean forGeneralizedHandler, final boolean any,
301 final boolean isEnumerated) {
302 boolean isAbstract = false;
303
304
305
306
307
308
309
310 XMLInfoNature xmlNature = new XMLInfoNature(member);
311
312 if (xmlNature.getSchemaType() != null
313 && xmlNature.getSchemaType().getJType() instanceof JClass) {
314 JClass jClass = (JClass) xmlNature.getSchemaType().getJType();
315 isAbstract = jClass.getModifiers().isAbstract();
316 }
317
318 if (!isAbstract && xsType.getJType() instanceof JClass) {
319 JClass jClass = (JClass) xsType.getJType();
320 isAbstract = jClass.getModifiers().isAbstract();
321 }
322
323 if (!isAbstract && xmlNature.getSchemaType() instanceof XSListType) {
324 XSListType xsList = (XSListType) xmlNature.getSchemaType();
325 if (xsList.getContentType().getJType() instanceof JClass) {
326 JClass componentType = (JClass) xsList.getContentType().getJType();
327 if (componentType.getModifiers().isAbstract()) {
328 isAbstract = componentType.getModifiers().isAbstract();
329 }
330 }
331 }
332
333 if (_config.useJava50()) {
334 jsc.add("@Override");
335 jsc.add("@SuppressWarnings(\"unused\")");
336 }
337
338 jsc.add("public java.lang.Object newInstance(java.lang.Object parent) {");
339 jsc.indent();
340 jsc.add("return ");
341
342 if (any || forGeneralizedHandler || isEnumerated
343 || xsType.isPrimitive()
344 || xsType.getJType().isArray()
345 || (xsType.getType() == XSType.STRING_TYPE)
346 || isAbstract) {
347 jsc.append("null;");
348 } else {
349 jsc.append(xsType.newInstanceCode());
350 }
351
352 jsc.unindent();
353 jsc.add("}");
354 }
355
356 }