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 rootElement = 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("rootElement.setAttribute( \"schemaLocation\", \"" + namespace + " " + url + "\", xsins );");
496 }
497 } else {
498 sc.add("Element rootElement = factory.element( xmlTag );");
499 }
500 sc.add("document.setRootElement( rootElement );");
501 } else {
502 sc.add("Element rootElement = 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("rootElement.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
542 boolean inModel = isClassInModel(
543 association.getTo(), field.getModelClass().getModel());
544
545 if (inModel) {
546
547 sc.add(getValueChecker(type, value, field));
548 sc.add("{");
549 sc.addIndented("update" + capitalise(field.getType()) + "( " + value + ", \"" + fieldTagName
550 + "\", innerCount, rootElement );");
551 sc.add("}");
552 } else {
553
554 sc.add(getValueChecker(type, value, field));
555 sc.add("{");
556 sc.addIndented("updateElement( innerCount, root, \"" + fieldTagName + "\" ).setText( "
557 + getValue(association.getTo(), value, xmlFieldMetadata) + " );");
558 sc.add("}");
559 }
560 } else {
561
562
563 XmlAssociationMetadata xmlAssociationMetadata =
564 (XmlAssociationMetadata) association.getAssociationMetadata(XmlAssociationMetadata.ID);
565
566 String valuesTagName = resolveTagName(fieldTagName, xmlAssociationMetadata);
567
568
569
570
571 if (ModelDefault.LIST.equals(type) || ModelDefault.SET.equals(type)) {
572
573 String toType = association.getTo();
574 if (toClass != null) {
575 if (xmlAssociationMetadata.isWrappedItems()) {
576 sc.add("iterate" + capitalise(toType) + "( innerCount, rootElement, " + value + ",\""
577 + fieldTagName + "\",\"" + valuesTagName + "\" );");
578 createIterateMethod(field.getName(), toClass, singular(fieldTagName), jClass);
579 } else {
580
581 sc.add("iterate2" + capitalise(toType) + "( innerCount, rootElement, " + value + ", \""
582 + valuesTagName + "\" );");
583 createIterateMethod2(field.getName(), toClass, singular(fieldTagName), jClass);
584 }
585 } else {
586
587 sc.add("findAndReplaceSimpleLists( innerCount, rootElement, " + value + ", \""
588 + fieldTagName + "\", \"" + singular(fieldTagName) + "\" );");
589 }
590 } else {
591
592 sc.add(getValueChecker(type, value, field));
593 sc.add("{");
594 sc.indent();
595 sc.add("Element listElement = updateElement( innerCount, rootElement, \"" + fieldTagName
596 + "\" );");
597 sc.add("Iterator it = " + value + ".keySet().iterator();");
598 sc.add("Counter propertiesCounter = new Counter( innerCount.getDepth() + 1 );");
599 sc.add("while ( it.hasNext() )");
600 sc.add("{");
601 sc.indent();
602 sc.add("String key = (String) it.next();");
603 if (xmlAssociationMetadata.isMapExplode()) {
604 sc.add("Element propTag = updateElement( propertiesCounter, listElement, \""
605 + singular(fieldTagName) + "\" );");
606 sc.add("Counter propertyCounter = new Counter( propertiesCounter.getDepth() + 1 );");
607 sc.add("findAndReplaceSimpleElement( propertyCounter, propTag, \"key\", key, null );");
608 sc.add("findAndReplaceSimpleElement( propertyCounter, propTag, \"value\", (String) " + value
609 + ".get( key ), null );");
610 } else {
611 sc.add("findAndReplaceSimpleElement( propertiesCounter, listElement, key, (String) " + value
612 + ".get( key ), null );");
613 }
614 sc.unindent();
615 sc.add("}");
616 sc.unindent();
617 sc.add("}");
618 }
619 }
620 } else {
621 if ("DOM".equals(field.getType())) {
622 sc.add("findAndReplaceXpp3DOM( innerCount, rootElement, \"" + fieldTagName + "\", (Xpp3Dom) "
623 + value + " );");
624
625 requiresDomSupport = true;
626 } else {
627 sc.add(getValueChecker(type, value, field));
628 sc.add("{");
629 sc.addIndented("updateElement( innerCount, rootElement, \"" + fieldTagName + "\" ).setText( "
630 + getValue(field.getType(), value, xmlFieldMetadata) + " );");
631 sc.add("}");
632 }
633 }
634 }
635
636 if (contentField != null) {
637 XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadata) contentField.getMetadata(XmlFieldMetadata.ID);
638 sc.add("rootElement.setText( " + getValue(contentField.getType(), contentValue, xmlFieldMetadata) + " );");
639 }
640
641 sc.unindent();
642 sc.add("}");
643
644 jClass.addMethod(marshall);
645 }
646
647 private void createIterateMethod(String field, ModelClass toClass, String childFieldTagName, JClass jClass) {
648 if (jClass.getMethod("iterate" + capitalise(toClass.getName()), 0) != null) {
649 return;
650 }
651 JMethod toReturn = new JMethod("iterate" + capitalise(toClass.getName()));
652 toReturn.addParameter(new JParameter(new JClass("Counter"), "counter"));
653 toReturn.addParameter(new JParameter(new JClass("Element"), "parent"));
654 toReturn.addParameter(new JParameter(new JClass("java.util.Collection"), "list"));
655 toReturn.addParameter(new JParameter(new JClass("java.lang.String"), "parentTag"));
656 toReturn.addParameter(new JParameter(new JClass("java.lang.String"), "childTag"));
657 toReturn.getModifiers().makeProtected();
658 JSourceCode sc = toReturn.getSourceCode();
659 sc.add("boolean shouldExist = ( list != null ) && ( list.size() > 0 );");
660 sc.add("Element element = updateElement( counter, parent, parentTag );");
661 sc.add("if ( shouldExist )");
662 sc.add("{");
663 sc.indent();
664 sc.add("Iterator it = list.iterator();");
665 sc.add("Counter innerCount = new Counter( counter.getDepth() + 1 );");
666 sc.add("while ( it.hasNext() )");
667 sc.add("{");
668 sc.indent();
669 sc.add(toClass.getName() + " value = (" + toClass.getName() + ") it.next();");
670 sc.add("update" + toClass.getName() + "( value, childTag, innerCount, element );");
671 sc.add("innerCount.increaseCount();");
672 sc.unindent();
673 sc.add("}");
674 sc.unindent();
675 sc.add("}");
676
677 jClass.addMethod(toReturn);
678 }
679
680 private void createIterateMethod2(String field, ModelClass toClass, String childFieldTagName, JClass jClass) {
681 if (jClass.getMethod("iterate2" + capitalise(toClass.getName()), 0) != null) {
682 return;
683 }
684 JMethod toReturn = new JMethod("iterate2" + capitalise(toClass.getName()));
685 toReturn.addParameter(new JParameter(new JClass("Counter"), "counter"));
686 toReturn.addParameter(new JParameter(new JClass("Element"), "parent"));
687 toReturn.addParameter(new JParameter(new JClass("java.util.Collection"), "list"));
688 toReturn.addParameter(new JParameter(new JClass("java.lang.String"), "childTag"));
689 toReturn.getModifiers().makeProtected();
690 JSourceCode sc = toReturn.getSourceCode();
691 sc.add("Iterator it = list.iterator();");
692 sc.add("while ( it.hasNext() )");
693 sc.add("{");
694 sc.indent();
695 sc.add(toClass.getName() + " value = (" + toClass.getName() + ") it.next();");
696 sc.add("update" + toClass.getName() + "( value, childTag, counter, parent );");
697 sc.unindent();
698 sc.add("}");
699
700 jClass.addMethod(toReturn);
701 }
702 }