1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.codehaus.modello.plugin.jdom;
18
19 import javax.inject.Named;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.codehaus.modello.ModelloException;
27 import org.codehaus.modello.model.Model;
28 import org.codehaus.modello.model.ModelAssociation;
29 import org.codehaus.modello.model.ModelClass;
30 import org.codehaus.modello.model.ModelDefault;
31 import org.codehaus.modello.model.ModelField;
32 import org.codehaus.modello.plugin.java.javasource.JClass;
33 import org.codehaus.modello.plugin.java.javasource.JConstructor;
34 import org.codehaus.modello.plugin.java.javasource.JField;
35 import org.codehaus.modello.plugin.java.javasource.JMethod;
36 import org.codehaus.modello.plugin.java.javasource.JParameter;
37 import org.codehaus.modello.plugin.java.javasource.JSourceCode;
38 import org.codehaus.modello.plugin.java.javasource.JSourceWriter;
39 import org.codehaus.modello.plugin.java.javasource.JType;
40 import org.codehaus.modello.plugin.java.metadata.JavaFieldMetadata;
41 import org.codehaus.modello.plugin.model.ModelClassMetadata;
42 import org.codehaus.modello.plugins.xml.metadata.XmlAssociationMetadata;
43 import org.codehaus.modello.plugins.xml.metadata.XmlFieldMetadata;
44 import org.codehaus.modello.plugins.xml.metadata.XmlModelMetadata;
45
46
47
48
49 @Named("jdom-writer")
50 public class JDOMWriterGenerator extends AbstractJDOMGenerator {
51
52 private boolean requiresDomSupport;
53
54 @Override
55 public void generate(Model model, Map<String, Object> parameters) throws ModelloException {
56 initialize(model, parameters);
57
58 requiresDomSupport = false;
59
60 try {
61 generateJDOMWriter();
62 } catch (IOException ex) {
63 throw new ModelloException("Exception while generating JDOM Writer.", ex);
64 }
65 }
66
67 private void generateJDOMWriter() throws ModelloException, IOException {
68 Model objectModel = getModel();
69
70 String packageName =
71 objectModel.getDefaultPackageName(isPackageWithVersion(), getGeneratedVersion()) + ".io.jdom";
72
73 String marshallerName = getFileName("JDOMWriter");
74
75 JClass jClass = new JClass(packageName + '.' + marshallerName);
76 initHeader(jClass);
77 suppressAllWarnings(objectModel, jClass);
78
79
80
81
82 jClass.addImport("java.io.OutputStream");
83 jClass.addImport("java.io.OutputStreamWriter");
84 jClass.addImport("java.io.Writer");
85 jClass.addImport("java.text.DateFormat");
86 jClass.addImport("java.util.ArrayList");
87 jClass.addImport("java.util.Arrays");
88 jClass.addImport("java.util.Collection");
89 jClass.addImport("java.util.Iterator");
90 jClass.addImport("java.util.List");
91 jClass.addImport("java.util.ListIterator");
92 jClass.addImport("java.util.Locale");
93 jClass.addImport("java.util.Map");
94 jClass.addImport("java.util.Properties");
95 jClass.addImport("org.jdom2.Content");
96 jClass.addImport("org.jdom2.DefaultJDOMFactory");
97 jClass.addImport("org.jdom2.Document");
98 jClass.addImport("org.jdom2.Element");
99 jClass.addImport("org.jdom2.JDOMFactory");
100 jClass.addImport("org.jdom2.Namespace");
101 jClass.addImport("org.jdom2.Parent");
102 jClass.addImport("org.jdom2.Text");
103 jClass.addImport("org.jdom2.output.Format");
104 jClass.addImport("org.jdom2.output.XMLOutputter");
105
106 addModelImports(jClass, null);
107
108 JField factoryField = new JField(new JClass("JDOMFactory"), "factory");
109 factoryField.getModifiers().setFinal(true);
110 jClass.addField(factoryField);
111
112 JField lineSeparatorField = new JField(new JClass("String"), "lineSeparator");
113 lineSeparatorField.getModifiers().setFinal(true);
114 jClass.addField(lineSeparatorField);
115
116 createCounter(jClass);
117
118
119 JConstructor constructor = jClass.createConstructor();
120 JSourceCode constCode = constructor.getSourceCode();
121 constCode.add("this( new DefaultJDOMFactory() );");
122
123 constructor = jClass.createConstructor();
124 constructor.addParameter(new JParameter(new JClass("JDOMFactory"), "factory"));
125 constCode = constructor.getSourceCode();
126 constCode.add("this.factory = factory;");
127 constCode.add("this.lineSeparator = \"\\n\";");
128
129 String root = objectModel.getRoot(getGeneratedVersion());
130
131 ModelClass rootClass = objectModel.getClass(root, getGeneratedVersion());
132
133 String rootElement = resolveTagName(rootClass);
134
135
136 jClass.addMethod(generateWriteModel2(root, rootElement));
137 jClass.addMethod(generateWriteModel3(root, rootElement));
138
139 jClass.addMethods(generateUtilityMethods());
140
141 writeAllClasses(objectModel, jClass, rootClass);
142
143 if (requiresDomSupport) {
144 jClass.addImport("org.codehaus.plexus.util.xml.Xpp3Dom");
145 jClass.addMethods(generateDomMethods());
146 }
147
148 try (JSourceWriter sourceWriter = newJSourceWriter(packageName, marshallerName)) {
149 jClass.print(sourceWriter);
150 }
151 }
152
153 private void createCounter(final JClass jClass) throws IllegalArgumentException {
154
155 JClass counter = jClass.createInnerClass("Counter");
156 counter.getModifiers().setStatic(true);
157
158 JField fld = new JField(new JType("int"), "currentIndex");
159 fld.setInitString("0");
160 counter.addField(fld);
161
162 fld = new JField(new JType("int"), "level");
163 counter.addField(fld);
164
165 JConstructor constr =
166 counter.createConstructor(new JParameter[] {new JParameter(new JType("int"), "depthLevel")});
167 constr.getSourceCode().append("level = depthLevel;");
168
169 JMethod inc = new JMethod("increaseCount");
170 inc.getSourceCode().add("currentIndex = currentIndex + 1;");
171 counter.addMethod(inc);
172
173 JMethod getter = new JMethod("getCurrentIndex", new JType("int"), null);
174 getter.getSourceCode().add("return currentIndex;");
175 counter.addMethod(getter);
176
177 getter = new JMethod("getDepth", new JType("int"), null);
178 getter.getSourceCode().add("return level;");
179 counter.addMethod(getter);
180 }
181
182 private JMethod generateWriteModel2(String root, String rootElement) {
183 String variableName = uncapitalise(root);
184
185 JMethod marshall = new JMethod("write");
186
187 marshall.addParameter(new JParameter(new JClass(root), variableName));
188 marshall.addParameter(new JParameter(new JClass("OutputStreamWriter"), "writer"));
189 marshall.addException(new JClass("java.io.IOException"));
190
191 JSourceCode sc = marshall.getSourceCode();
192 sc.add("Format format = Format.getRawFormat()");
193 sc.add(" .setEncoding( writer.getEncoding() )");
194 sc.add(" .setLineSeparator( System.getProperty( \"line.separator\" ) );");
195 sc.add("write( " + variableName + ", writer, format );");
196 return marshall;
197 }
198
199 private JMethod generateWriteModel3(String root, String rootElement) {
200 String variableName = uncapitalise(root);
201
202 JMethod marshall = new JMethod("write");
203
204 marshall.addParameter(new JParameter(new JClass(root), variableName));
205 marshall.addParameter(new JParameter(new JClass("Writer"), "writer"));
206 marshall.addParameter(new JParameter(new JClass("Format"), "jdomFormat"));
207 marshall.addException(new JClass("java.io.IOException"));
208
209 JSourceCode sc = marshall.getSourceCode();
210 sc.add("Document document = factory.document( null );");
211 sc.add("update" + root + "( " + variableName + ", \"" + rootElement + "\", new Counter( 0 ), document );");
212 sc.add("XMLOutputter outputter = new XMLOutputter();");
213 sc.add("outputter.setFormat( jdomFormat );");
214 sc.add("outputter.output( document, writer );");
215
216 return marshall;
217 }
218
219 private JMethod[] generateUtilityMethods() {
220 JMethod findRSElement = new JMethod("findAndReplaceSimpleElement", new JClass("Element"), null);
221 findRSElement.addParameter(new JParameter(new JClass("Counter"), "counter"));
222 findRSElement.addParameter(new JParameter(new JClass("Element"), "parent"));
223 findRSElement.addParameter(new JParameter(new JClass("String"), "name"));
224 findRSElement.addParameter(new JParameter(new JClass("String"), "text"));
225 findRSElement.addParameter(new JParameter(new JClass("String"), "defaultValue"));
226
227 findRSElement.getModifiers().makeProtected();
228 JSourceCode sc = findRSElement.getSourceCode();
229 sc.add("if ( ( defaultValue != null ) && ( text != null ) && defaultValue.equals( text ) )");
230 sc.add("{");
231 sc.indent();
232 sc.add("Element element = parent.getChild( name, parent.getNamespace() );");
233 sc.add("// if exist and is default value or if doesn't exist.. just keep the way it is..");
234 sc.add("if ( ( element != null && defaultValue.equals( element.getText() ) ) || element == null )");
235 sc.add("{");
236 sc.addIndented("return element;");
237 sc.add("}");
238 sc.unindent();
239 sc.add("}");
240
241 sc.add("boolean shouldExist = ( text != null ) && ( text.trim().length() > 0 );");
242 sc.add("Element element = updateElement( counter, parent, name );");
243 sc.add("if ( shouldExist )");
244 sc.add("{");
245 sc.addIndented("element.setText( text );");
246 sc.add("}");
247 sc.add("return element;");
248
249 JMethod updateElement = new JMethod("updateElement", new JClass("Element"), null);
250 updateElement.addParameter(new JParameter(new JClass("Counter"), "counter"));
251 updateElement.addParameter(new JParameter(new JClass("Element"), "parent"));
252 updateElement.addParameter(new JParameter(new JClass("String"), "name"));
253 updateElement.getModifiers().makeProtected();
254 sc = updateElement.getSourceCode();
255 sc.add("Element element = factory.element( name, parent.getNamespace() );");
256 sc.add("insertAtPreferredLocation( parent, element, counter );");
257 sc.add("counter.increaseCount();");
258 sc.add("return element;");
259
260 JMethod insAtPref = new JMethod("insertAtPreferredLocation");
261 insAtPref.addParameter(new JParameter(new JClass("Element"), "parent"));
262 insAtPref.addParameter(new JParameter(new JClass("Element"), "child"));
263 insAtPref.addParameter(new JParameter(new JClass("Counter"), "counter"));
264 insAtPref.getModifiers().makeProtected();
265 sc = insAtPref.getSourceCode();
266 sc.add("int contentIndex = 0;");
267 sc.add("int elementCounter = 0;");
268 sc.add("Iterator it = parent.getContent().iterator();");
269 sc.add("Text lastText = null;");
270 sc.add("int offset = 0;");
271 sc.add("while ( it.hasNext() && elementCounter <= counter.getCurrentIndex() )");
272 sc.add("{");
273 sc.indent();
274 sc.add("Object next = it.next();");
275 sc.add("offset = offset + 1;");
276 sc.add("if ( next instanceof Element )");
277 sc.add("{");
278 sc.indent();
279 sc.add("elementCounter = elementCounter + 1;");
280 sc.add("contentIndex = contentIndex + offset;");
281 sc.add("offset = 0;");
282 sc.unindent();
283 sc.add("}");
284 sc.add("if ( next instanceof Text && it.hasNext() )");
285 sc.add("{");
286 sc.addIndented("lastText = (Text) next;");
287 sc.add("}");
288 sc.unindent();
289 sc.add("}");
290 sc.add("if ( lastText != null && lastText.getTextTrim().length() == 0 )");
291 sc.add("{");
292 sc.addIndented("lastText = (Text) lastText.clone();");
293 sc.add("}");
294 sc.add("else");
295 sc.add("{");
296 sc.indent();
297 sc.add("String starter = lineSeparator;");
298 sc.add("for ( int i = 0; i < counter.getDepth(); i++ )");
299 sc.add("{");
300 sc.addIndented("starter = starter + \" \"; //TODO make settable?");
301 sc.add("}");
302 sc.add("lastText = factory.text( starter );");
303 sc.unindent();
304 sc.add("}");
305 sc.add("if ( parent.getContentSize() == 0 )");
306 sc.add("{");
307 sc.indent();
308 sc.add("Text finalText = (Text) lastText.clone();");
309 sc.add(
310 "finalText.setText( finalText.getText().substring( 0, finalText.getText().length() - \" \".length() ) );");
311 sc.add("parent.addContent( contentIndex, finalText );");
312 sc.unindent();
313 sc.add("}");
314 sc.add("parent.addContent( contentIndex, child );");
315 sc.add("parent.addContent( contentIndex, lastText );");
316
317 JMethod findRSLists = new JMethod("findAndReplaceSimpleLists", new JClass("Element"), null);
318 findRSLists.addParameter(new JParameter(new JClass("Counter"), "counter"));
319 findRSLists.addParameter(new JParameter(new JClass("Element"), "parent"));
320 findRSLists.addParameter(new JParameter(new JClass("java.util.Collection"), "list"));
321 findRSLists.addParameter(new JParameter(new JClass("String"), "parentName"));
322 findRSLists.addParameter(new JParameter(new JClass("String"), "childName"));
323 findRSLists.getModifiers().makeProtected();
324 sc = findRSLists.getSourceCode();
325 sc.add("boolean shouldExist = ( list != null ) && ( list.size() > 0 );");
326 sc.add("Element element = updateElement( counter, parent, parentName );");
327 sc.add("if ( shouldExist )");
328 sc.add("{");
329 sc.indent();
330 sc.add("Iterator it = list.iterator();");
331 sc.add("Counter innerCount = new Counter( counter.getDepth() + 1 );");
332 sc.add("while ( it.hasNext() )");
333 sc.add("{");
334 sc.indent();
335 sc.add("String value = (String) it.next();");
336 sc.add("Element el = factory.element( childName, element.getNamespace() );");
337 sc.add("insertAtPreferredLocation( element, el, innerCount );");
338 sc.add("el.setText( value );");
339 sc.add("innerCount.increaseCount();");
340 sc.unindent();
341 sc.add("}");
342 sc.add("}");
343 sc.add("return element;");
344
345 return new JMethod[] {findRSElement, updateElement, insAtPref, findRSLists};
346 }
347
348 private JMethod[] generateDomMethods() {
349 JMethod findRSDom = new JMethod("findAndReplaceXpp3DOM", new JClass("Element"), null);
350 findRSDom.addParameter(new JParameter(new JClass("Counter"), "counter"));
351 findRSDom.addParameter(new JParameter(new JClass("Element"), "parent"));
352 findRSDom.addParameter(new JParameter(new JClass("String"), "name"));
353 findRSDom.addParameter(new JParameter(new JClass("Xpp3Dom"), "dom"));
354 findRSDom.getModifiers().makeProtected();
355 JSourceCode sc = findRSDom.getSourceCode();
356 sc.add("boolean shouldExist = ( dom != null ) && ( dom.getChildCount() > 0 || dom.getValue() != null );");
357 sc.add("Element element = updateElement( counter, parent, name );");
358 sc.add("if ( shouldExist )");
359 sc.add("{");
360 sc.addIndented("replaceXpp3DOM( element, dom, new Counter( counter.getDepth() + 1 ) );");
361 sc.add("}");
362 sc.add("return element;");
363
364 JMethod findRSDom2 = new JMethod("replaceXpp3DOM");
365 findRSDom2.addParameter(new JParameter(new JClass("Element"), "parent"));
366 findRSDom2.addParameter(new JParameter(new JClass("Xpp3Dom"), "parentDom"));
367 findRSDom2.addParameter(new JParameter(new JClass("Counter"), "counter"));
368 findRSDom2.getModifiers().makeProtected();
369 sc = findRSDom2.getSourceCode();
370
371 sc.add("for( String attributeName : parentDom.getAttributeNames() )");
372 sc.add("{");
373 sc.indent();
374 sc.add("String[] attrDetails = attributeName.split( \":\", 2 );");
375 sc.add("if ( attrDetails.length == 2 )");
376 sc.add("{");
377 sc.addIndented(
378 "parent.setAttribute( attrDetails[1], parentDom.getAttribute( attributeName ), parent.getNamespace( attrDetails[0] ) );");
379 sc.add("}");
380 sc.add("else ");
381 sc.add("{");
382 sc.addIndented("parent.setAttribute( attributeName, parentDom.getAttribute( attributeName ) );");
383 sc.add("}");
384 sc.unindent();
385 sc.add("}");
386 sc.add("if ( parentDom.getChildCount() > 0 )");
387 sc.add("{");
388 sc.indent();
389 sc.add("Xpp3Dom[] childs = parentDom.getChildren();");
390 sc.add("Collection domChilds = new ArrayList();");
391 sc.add("for ( int i = 0; i < childs.length; i++ )");
392 sc.add("{");
393 sc.addIndented("domChilds.add( childs[i] );");
394 sc.add("}");
395 sc.add("ListIterator it = parent.getChildren().listIterator();");
396 sc.add("while ( it.hasNext() )");
397 sc.add("{");
398 sc.indent();
399 sc.add("Element elem = (Element) it.next();");
400 sc.add("Iterator it2 = domChilds.iterator();");
401 sc.add("Xpp3Dom corrDom = null;");
402 sc.add("while ( it2.hasNext() )");
403 sc.add("{");
404 sc.indent();
405 sc.add("Xpp3Dom dm = (Xpp3Dom) it2.next();");
406 sc.add("if ( dm.getName().equals( elem.getName() ) )");
407 sc.add("{");
408 sc.indent();
409 sc.add("corrDom = dm;");
410 sc.add("break;");
411 sc.unindent();
412 sc.add("}");
413 sc.unindent();
414 sc.add("}");
415 sc.add("if ( corrDom != null )");
416 sc.add("{");
417 sc.indent();
418 sc.add("domChilds.remove( corrDom );");
419 sc.add("replaceXpp3DOM( elem, corrDom, new Counter( counter.getDepth() + 1 ) );");
420 sc.add("counter.increaseCount();");
421 sc.unindent();
422 sc.add("}");
423 sc.add("else");
424 sc.add("{");
425 sc.addIndented("it.remove();");
426 sc.add("}");
427 sc.unindent();
428 sc.add("}");
429 sc.add("Iterator it2 = domChilds.iterator();");
430 sc.add("while ( it2.hasNext() )");
431 sc.add("{");
432 sc.indent();
433 sc.add("Xpp3Dom dm = (Xpp3Dom) it2.next();");
434 sc.add("Element elem = factory.element( dm.getName(), parent.getNamespace() );");
435 sc.add("insertAtPreferredLocation( parent, elem, counter );");
436 sc.add("counter.increaseCount();");
437 sc.add("replaceXpp3DOM( elem, dm, new Counter( counter.getDepth() + 1 ) );");
438 sc.unindent();
439 sc.add("}");
440 sc.unindent();
441 sc.add("}");
442 sc.add(" else if ( parentDom.getValue() != null )");
443 sc.add("{");
444 sc.addIndented("parent.setText( parentDom.getValue() );");
445 sc.add("}");
446
447 return new JMethod[] {findRSDom, findRSDom2};
448 }
449
450 private void writeAllClasses(Model objectModel, JClass jClass, ModelClass rootClass) throws ModelloException {
451 List<ModelClass> alwaysExistingElements = new ArrayList<ModelClass>();
452 alwaysExistingElements.add(rootClass);
453
454 for (ModelClass clazz : getClasses(objectModel)) {
455 updateClass(clazz, jClass, alwaysExistingElements);
456 }
457 }
458
459 private void updateClass(ModelClass clazz, JClass jClass, List<ModelClass> alwaysExisting) throws ModelloException {
460 String className = clazz.getName();
461
462 String capClassName = capitalise(className);
463
464 String uncapClassName = uncapitalise(className);
465
466 ModelClassMetadata classMetadata = (ModelClassMetadata) clazz.getMetadata(ModelClassMetadata.ID);
467
468 JMethod marshall = new JMethod("update" + capClassName);
469 marshall.addParameter(new JParameter(new JClass(className), uncapClassName));
470 marshall.addParameter(new JParameter(new JClass("String"), "xmlTag"));
471 marshall.addParameter(new JParameter(new JClass("Counter"), "counter"));
472 if (classMetadata.isRootElement()) {
473 marshall.addParameter(new JParameter(new JClass("Document"), "document"));
474 } else {
475 marshall.addParameter(new JParameter(new JClass("Element"), "element"));
476 }
477 marshall.getModifiers().makeProtected();
478
479 JSourceCode sc = marshall.getSourceCode();
480 sc.add("if ( " + uncapClassName + " != null )");
481 sc.add("{");
482 sc.indent();
483
484 if (classMetadata.isRootElement()) {
485 XmlModelMetadata xmlModelMetadata =
486 (XmlModelMetadata) clazz.getModel().getMetadata(XmlModelMetadata.ID);
487 String namespace = xmlModelMetadata.getNamespace(getGeneratedVersion());
488
489 if (namespace != null) {
490 sc.add("Element root = factory.element( xmlTag, \"" + namespace + "\" );");
491 if (xmlModelMetadata.getSchemaLocation() != null) {
492 String url = xmlModelMetadata.getSchemaLocation(getGeneratedVersion());
493 sc.add(
494 "Namespace xsins = Namespace.getNamespace( \"xsi\", \"http://www.w3.org/2001/XMLSchema-instance\" );");
495 sc.add("root.setAttribute( \"schemaLocation\", \"" + namespace + " " + url + "\", xsins );");
496 }
497 } else {
498 sc.add("Element root = factory.element( xmlTag );");
499 }
500 sc.add("document.setRootElement( root );");
501 } else {
502 sc.add("Element root = updateElement( counter, element, xmlTag );");
503 }
504
505 sc.add("Counter innerCount = new Counter( counter.getDepth() + 1 );");
506
507 ModelField contentField = null;
508
509 String contentValue = null;
510
511 List<ModelField> modelFields = getFieldsForXml(clazz, getGeneratedVersion());
512
513 for (ModelField field : modelFields) {
514 XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadata) field.getMetadata(XmlFieldMetadata.ID);
515 JavaFieldMetadata javaFieldMetadata = (JavaFieldMetadata) field.getMetadata(JavaFieldMetadata.ID);
516
517 String fieldTagName = resolveTagName(field, xmlFieldMetadata);
518
519 String type = field.getType();
520 String value = uncapClassName + '.' + getPrefix(javaFieldMetadata) + capitalise(field.getName()) + "()";
521
522 if (xmlFieldMetadata.isContent()) {
523 contentField = field;
524 contentValue = value;
525 continue;
526 }
527
528 if (xmlFieldMetadata.isAttribute()) {
529 sc.add(getValueChecker(type, value, field));
530 sc.add("{");
531 sc.addIndented("root.setAttribute( \"" + fieldTagName + "\", "
532 + getValue(field.getType(), value, xmlFieldMetadata) + " );");
533 sc.add("}");
534 continue;
535 }
536 if (field instanceof ModelAssociation) {
537 ModelAssociation association = (ModelAssociation) field;
538
539 ModelClass toClass = association.getToClass();
540 if (association.isOneMultiplicity()) {
541 sc.add(getValueChecker(type, value, field));
542 sc.add("{");
543 sc.addIndented("update" + capitalise(field.getType()) + "( " + value + ", \"" + fieldTagName
544 + "\", innerCount, root );");
545 sc.add("}");
546 } else {
547
548
549 XmlAssociationMetadata xmlAssociationMetadata =
550 (XmlAssociationMetadata) association.getAssociationMetadata(XmlAssociationMetadata.ID);
551
552 String valuesTagName = resolveTagName(fieldTagName, xmlAssociationMetadata);
553
554
555
556
557 if (ModelDefault.LIST.equals(type) || ModelDefault.SET.equals(type)) {
558
559 String toType = association.getTo();
560 if (toClass != null) {
561 if (xmlAssociationMetadata.isWrappedItems()) {
562 sc.add("iterate" + capitalise(toType) + "( innerCount, root, " + value + ",\""
563 + fieldTagName + "\",\"" + valuesTagName + "\" );");
564 createIterateMethod(field.getName(), toClass, singular(fieldTagName), jClass);
565 } else {
566
567 sc.add("iterate2" + capitalise(toType) + "( innerCount, root, " + value + ", \""
568 + valuesTagName + "\" );");
569 createIterateMethod2(field.getName(), toClass, singular(fieldTagName), jClass);
570 }
571 } else {
572
573 sc.add("findAndReplaceSimpleLists( innerCount, root, " + value + ", \"" + fieldTagName
574 + "\", \"" + singular(fieldTagName) + "\" );");
575 }
576 } else {
577
578 sc.add(getValueChecker(type, value, field));
579 sc.add("{");
580 sc.indent();
581 sc.add("Element listElement = updateElement( innerCount, root, \"" + fieldTagName + "\" );");
582 sc.add("Iterator it = " + value + ".keySet().iterator();");
583 sc.add("Counter propertiesCounter = new Counter( innerCount.getDepth() + 1 );");
584 sc.add("while ( it.hasNext() )");
585 sc.add("{");
586 sc.indent();
587 sc.add("String key = (String) it.next();");
588 if (xmlAssociationMetadata.isMapExplode()) {
589 sc.add("Element propTag = updateElement( propertiesCounter, listElement, \""
590 + singular(fieldTagName) + "\" );");
591 sc.add("Counter propertyCounter = new Counter( propertiesCounter.getDepth() + 1 );");
592 sc.add("findAndReplaceSimpleElement( propertyCounter, propTag, \"key\", key, null );");
593 sc.add("findAndReplaceSimpleElement( propertyCounter, propTag, \"value\", (String) " + value
594 + ".get( key ), null );");
595 } else {
596 sc.add("findAndReplaceSimpleElement( propertiesCounter, listElement, key, (String) " + value
597 + ".get( key ), null );");
598 }
599 sc.unindent();
600 sc.add("}");
601 sc.unindent();
602 sc.add("}");
603 }
604 }
605 } else {
606 if ("DOM".equals(field.getType())) {
607 sc.add("findAndReplaceXpp3DOM( innerCount, root, \"" + fieldTagName + "\", (Xpp3Dom) " + value
608 + " );");
609
610 requiresDomSupport = true;
611 } else {
612 sc.add(getValueChecker(type, value, field));
613 sc.add("{");
614 sc.addIndented("updateElement( innerCount, root, \"" + fieldTagName + "\" ).setText( "
615 + getValue(field.getType(), value, xmlFieldMetadata) + " );");
616 sc.add("}");
617 }
618 }
619 }
620
621 if (contentField != null) {
622 XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadata) contentField.getMetadata(XmlFieldMetadata.ID);
623 sc.add("root.setText( " + getValue(contentField.getType(), contentValue, xmlFieldMetadata) + " );");
624 }
625
626 sc.unindent();
627 sc.add("}");
628
629 jClass.addMethod(marshall);
630 }
631
632 private void createIterateMethod(String field, ModelClass toClass, String childFieldTagName, JClass jClass) {
633 if (jClass.getMethod("iterate" + capitalise(toClass.getName()), 0) != null) {
634 return;
635 }
636 JMethod toReturn = new JMethod("iterate" + capitalise(toClass.getName()));
637 toReturn.addParameter(new JParameter(new JClass("Counter"), "counter"));
638 toReturn.addParameter(new JParameter(new JClass("Element"), "parent"));
639 toReturn.addParameter(new JParameter(new JClass("java.util.Collection"), "list"));
640 toReturn.addParameter(new JParameter(new JClass("java.lang.String"), "parentTag"));
641 toReturn.addParameter(new JParameter(new JClass("java.lang.String"), "childTag"));
642 toReturn.getModifiers().makeProtected();
643 JSourceCode sc = toReturn.getSourceCode();
644 sc.add("boolean shouldExist = ( list != null ) && ( list.size() > 0 );");
645 sc.add("Element element = updateElement( counter, parent, parentTag );");
646 sc.add("if ( shouldExist )");
647 sc.add("{");
648 sc.indent();
649 sc.add("Iterator it = list.iterator();");
650 sc.add("Counter innerCount = new Counter( counter.getDepth() + 1 );");
651 sc.add("while ( it.hasNext() )");
652 sc.add("{");
653 sc.indent();
654 sc.add(toClass.getName() + " value = (" + toClass.getName() + ") it.next();");
655 sc.add("update" + toClass.getName() + "( value, childTag, innerCount, element );");
656 sc.add("innerCount.increaseCount();");
657 sc.unindent();
658 sc.add("}");
659 sc.unindent();
660 sc.add("}");
661
662 jClass.addMethod(toReturn);
663 }
664
665 private void createIterateMethod2(String field, ModelClass toClass, String childFieldTagName, JClass jClass) {
666 if (jClass.getMethod("iterate2" + capitalise(toClass.getName()), 0) != null) {
667 return;
668 }
669 JMethod toReturn = new JMethod("iterate2" + capitalise(toClass.getName()));
670 toReturn.addParameter(new JParameter(new JClass("Counter"), "counter"));
671 toReturn.addParameter(new JParameter(new JClass("Element"), "parent"));
672 toReturn.addParameter(new JParameter(new JClass("java.util.Collection"), "list"));
673 toReturn.addParameter(new JParameter(new JClass("java.lang.String"), "childTag"));
674 toReturn.getModifiers().makeProtected();
675 JSourceCode sc = toReturn.getSourceCode();
676 sc.add("Iterator it = list.iterator();");
677 sc.add("while ( it.hasNext() )");
678 sc.add("{");
679 sc.indent();
680 sc.add(toClass.getName() + " value = (" + toClass.getName() + ") it.next();");
681 sc.add("update" + toClass.getName() + "( value, childTag, counter, parent );");
682 sc.unindent();
683 sc.add("}");
684
685 jClass.addMethod(toReturn);
686 }
687 }