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