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