Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   package org.codehaus.modello.plugin.dom4j;
   
   /*
    * Copyright (c) 2006, Codehaus.
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy of
    * this software and associated documentation files (the "Software"), to deal in
    * the Software without restriction, including without limitation the rights to
    * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   * of the Software, and to permit persons to whom the Software is furnished to do
   * so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   * SOFTWARE.
   */
  
  
  import java.util.List;
Generator that reads a model using dom4j. TODO: chunks are lifted from xpp3, including the tests. Can we abstract it in some way?

Author(s):
Brett Porter
  
  public class Dom4jReaderGenerator
      extends AbstractXmlJavaGenerator
  {
  
      private boolean requiresDomSupport;
  
      public void generateModel modelProperties parameters )
          throws ModelloException
      {
          initializemodelparameters );
  
           = false;
  
          try
          {
              generateDom4jReader();
          }
          catch ( IOException ex )
          {
              throw new ModelloException"Exception while generating Dom4j Reader."ex );
          }
      }
  
      private void generateDom4jReader()
          throws ModelloExceptionIOException
      {
          Model objectModel = getModel();
  
          String packageName = objectModel.getDefaultPackageNameisPackageWithVersion(), getGeneratedVersion() )
              + ".io.dom4j";
  
          String unmarshallerName = getFileName"Dom4jReader" );
  
          JSourceWriter sourceWriter = newJSourceWriterpackageNameunmarshallerName );
  
          JClass jClass = new JClasspackageName + '.' + unmarshallerName );
          initHeaderjClass );
          suppressAllWarningsobjectModeljClass );
  
          jClass.addImport"java.io.InputStream" );
          jClass.addImport"java.io.IOException" );
          jClass.addImport"java.io.Reader" );
          jClass.addImport"java.net.URL" );
          jClass.addImport"java.util.Date" );
          jClass.addImport"java.util.Locale" );
          jClass.addImport"java.text.DateFormat" );
          jClass.addImport"java.text.ParsePosition" );
          jClass.addImport"java.util.Iterator" );
         jClass.addImport"org.dom4j.Attribute" );
         jClass.addImport"org.dom4j.Document" );
         jClass.addImport"org.dom4j.DocumentException" );
         jClass.addImport"org.dom4j.Element" );
         jClass.addImport"org.dom4j.Node" );
         jClass.addImport"org.dom4j.io.SAXReader" );
 
         addModelImportsjClassnull );
 
         ModelClass root = objectModel.getClassobjectModel.getRootgetGeneratedVersion() ), getGeneratedVersion() );
         JClass rootType = new JClassroot.getName() );
 
         // ----------------------------------------------------------------------
         // Write the read(XMLStreamReader,boolean) method which will do the unmarshalling.
         // ----------------------------------------------------------------------
 
         JMethod unmarshall = new JMethod"read"rootTypenull );
         unmarshall.getModifiers().makePrivate();
 
         unmarshall.addParameternew JParameternew JClass"Document" ), "document" ) );
         unmarshall.addParameternew JParameter."strict" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         JSourceCode sc = unmarshall.getSourceCode();
 
         String className = root.getName();
         String variableName = uncapitaliseclassName );
 
         sc.add"String encoding = document.getXMLEncoding();" );
 
         sc.addclassName + ' ' + variableName + " = parse" + root.getName() + "( \"" + resolveTagNameroot )
                 + "\", document.getRootElement(), strict );" );
 
         sc.addvariableName + ".setModelEncoding( encoding );" );
 
         sc.add"return " + variableName + ";" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
         // Write the read(Reader[,boolean]) methods which will do the unmarshalling.
         // ----------------------------------------------------------------------
 
         unmarshall = new JMethod"read"rootTypenull );
 
         unmarshall.addParameternew JParameternew JClass"Reader" ), "reader" ) );
         unmarshall.addParameternew JParameter."strict" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         sc = unmarshall.getSourceCode();
 
         sc.add"SAXReader parser = new SAXReader();" );
 
         sc.add"Document document = parser.read( reader );" );
 
         sc.add"return read( document, strict );" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
 
         unmarshall = new JMethod"read"rootTypenull );
 
         unmarshall.addParameternew JParameternew JClass"Reader" ), "reader" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         sc = unmarshall.getSourceCode();
 
         sc.add"return read( reader, true );" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
         // Write the read(InputStream[,boolean]) methods which will do the unmarshalling.
         // ----------------------------------------------------------------------
 
         unmarshall = new JMethod"read"rootTypenull );
 
         unmarshall.addParameternew JParameternew JClass"InputStream" ), "stream" ) );
         unmarshall.addParameternew JParameter."strict" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         sc = unmarshall.getSourceCode();
 
         sc.add"SAXReader parser = new SAXReader();" );
 
         sc.add"Document document = parser.read( stream );" );
 
         sc.add"return read( document, strict );" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
 
         unmarshall = new JMethod"read"rootTypenull );
 
         unmarshall.addParameternew JParameternew JClass"InputStream" ), "stream" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         sc = unmarshall.getSourceCode();
 
         sc.add"return read( stream, true );" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
         // Write the read(URL[,boolean]) methods which will do the unmarshalling.
         // ----------------------------------------------------------------------
 
         unmarshall = new JMethod"read"rootTypenull );
 
         unmarshall.addParameternew JParameternew JClass"URL" ), "url" ) );
         unmarshall.addParameternew JParameter."strict" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         sc = unmarshall.getSourceCode();
 
         sc.add"SAXReader parser = new SAXReader();" );
 
         sc.add"Document document = parser.read( url );" );
 
         sc.add"return read( document, strict );" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
 
         unmarshall = new JMethod"read"rootTypenull );
 
         unmarshall.addParameternew JParameternew JClass"URL" ), "url" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         sc = unmarshall.getSourceCode();
 
         sc.add"return read( url, true );" );
 
         jClass.addMethodunmarshall );
 
         // ----------------------------------------------------------------------
         // Write the class parsers
         // ----------------------------------------------------------------------
 
         writeAllClassesParserobjectModeljClass );
 
         // ----------------------------------------------------------------------
         // Write helpers
         // ----------------------------------------------------------------------
 
         writeHelpersjClass );
 
         if (  )
         {
             jClass.addImport"org.codehaus.plexus.util.xml.Xpp3Dom" );
             writeDomHelpersjClass );
         }
 
         // ----------------------------------------------------------------------
         //
         // ----------------------------------------------------------------------
 
         jClass.printsourceWriter );
 
         sourceWriter.close();
     }
 
     private void writeAllClassesParserModel objectModelJClass jClass )
     {
         ModelClass root = objectModel.getClassobjectModel.getRootgetGeneratedVersion() ), getGeneratedVersion() );
 
         for ( ModelClass clazz : getClassesobjectModel ) )
         {
             writeClassParserclazzjClassroot.getName().equalsclazz.getName() ) );
         }
     }
 
     private void writeClassParserModelClass modelClassJClass jClassboolean rootElement )
     {
         String className = modelClass.getName();
 
         String capClassName = capitaliseclassName );
 
         String uncapClassName = uncapitaliseclassName );
 
         JMethod unmarshall = new JMethod"parse" + capClassNamenew JClassclassName ), null );
         unmarshall.getModifiers().makePrivate();
 
         unmarshall.addParameternew JParameternew JClass"String" ), "tagName" ) );
         unmarshall.addParameternew JParameternew JClass"Element" ), "element" ) );
         unmarshall.addParameternew JParameter."strict" ) );
 
         unmarshall.addExceptionnew JClass"IOException" ) );
         unmarshall.addExceptionnew JClass"DocumentException" ) );
 
         JSourceCode sc = unmarshall.getSourceCode();
 
         sc.addclassName + " " + uncapClassName + " = new " + className + "();" );
 
         ModelField contentField = null;
 
         List<ModelFieldmodelFields = getFieldsForXmlmodelClassgetGeneratedVersion() );
 
         // read all XML attributes first
         for ( ModelField field : modelFields )
         {
             XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadatafield.getMetadata. );
 
             if ( xmlFieldMetadata.isAttribute() )
             {
                 String tagName = xmlFieldMetadata.getTagName();
                 if ( tagName == null )
                 {
                     tagName = field.getName();
                 }
 
                 sc.add"if ( element.attributeValue( \"" + tagName + "\" ) != null  )" );
                 sc.add(  "{" );
                 sc.indent();
 
                 writePrimitiveFieldfieldfield.getType(), uncapClassName"set" + capitalisefield.getName() ), sc,
                                      jClass"element""childElement" );
 
                 sc.unindent();
                 sc.add"}" );
             }
             // TODO check if we have already one with this type and throws Exception
             if ( xmlFieldMetadata.isContent() )
             {
                 contentField = field;
             }
         }
 
         if ( rootElement )
         {
             sc.add"if ( strict )" );
             sc.add"{" );
             sc.indent();
 
             sc.add"if ( !element.getName().equals( tagName ) )" );
             sc.add"{" );
             sc.addIndented(
                 "throw new DocumentException( \"Error parsing model: root element tag is '\" + element.getName() + \"' instead of '\" + tagName + \"'\" );" );
             sc.add"}" );
 
             sc.unindent();
             sc.add"}" );
         }
 
         if ( contentField != null )
         {
             writePrimitiveFieldcontentFieldcontentField.getType(), uncapClassName,
                                  "set" + capitalisecontentField.getName() ), scjClassnull"element" );
         }
         else
         {
             sc.add"java.util.Set parsed = new java.util.HashSet();" );
 
             sc.add"for ( Iterator i = element.nodeIterator(); i.hasNext(); )" );
             sc.add"{" );
             sc.indent();
 
             sc.add"Node node = (Node) i.next();" );
 
             sc.add"if ( node.getNodeType() == Node.ELEMENT_NODE )" );
             // TODO: attach other NodeTypes to model in some way
             sc.add"{" );
             sc.indent();
 
             sc.add"Element childElement = (Element) node;" );
 
             boolean addElse = false;
 
             for ( ModelField field : modelFields )
             {
                 XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadatafield.getMetadata. );
 
                 if ( !xmlFieldMetadata.isAttribute() )
                 {
                     processFieldfieldxmlFieldMetadataaddElsescuncapClassNamejClass );
 
                     addElse = true;
                 }
             }
 
             if ( addElse )
             {
                 sc.add"else" );
 
                 sc.add"{" );
                 sc.indent();
             }
 
             sc.add"checkUnknownElement( childElement, strict );" );
 
             if ( addElse )
             {
                 sc.unindent();
                 sc.add"}" );
             }
 
             sc.unindent();
             sc.add"}" );
 
             sc.unindent();
             sc.add"}" );
         }
 
         sc.add"return " + uncapClassName + ";" );
 
         jClass.addMethodunmarshall );
     }

    
Generate code to process a field represented as an XML element.

Parameters:
field the field to process
xmlFieldMetadata its XML metadata
addElse add an else statement before generating a new if
sc the method source code to add to
objectName the object name in the source
jClass the generated class source file
 
     private void processFieldModelField fieldXmlFieldMetadata xmlFieldMetadataboolean addElseJSourceCode sc,
                                String objectNameJClass jClass )
     {
         String fieldTagName = resolveTagNamefieldxmlFieldMetadata );
 
         String capFieldName = capitalisefield.getName() );
 
         String singularName = singularfield.getName() );
 
         String alias;
         if ( StringUtils.isEmptyfield.getAlias() ) )
         {
             alias = "null";
         }
         else
         {
             alias = "\"" + field.getAlias() + "\"";
         }
 
         String tagComparison = ( addElse ? "else " : "" )
             + "if ( checkFieldWithDuplicate( childElement, \"" + fieldTagName + "\", " + alias + ", parsed ) )";
 
         if ( field instanceof ModelAssociation )
         {
             ModelAssociation association = (ModelAssociationfield;
 
             String associationName = association.getName();
 
             if ( association.isOneMultiplicity() )
             {
                 sc.addtagComparison );
 
                 sc.add"{" );
                 sc.addIndentedobjectName + ".set" + capFieldName + "( parse" + association.getTo() + "( \""
                                 + fieldTagName + "\", childElement, strict ) );" );
                 sc.add"}" );
             }
             else
             {
                 //MANY_MULTIPLICITY
 
                 XmlAssociationMetadata xmlAssociationMetadata =
                     (XmlAssociationMetadataassociation.getAssociationMetadata. );
 
                 String valuesTagName = resolveTagNamefieldTagNamexmlAssociationMetadata );
 
                 String type = association.getType();
 
                 if ( ..equalstype ) || ..equalstype ) )
                 {
                     boolean wrappedItems = xmlAssociationMetadata.isWrappedItems();
 
                     if ( wrappedItems )
                     {
                         sc.addtagComparison );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.addtype + " " + associationName + " = " + association.getDefaultValue() + ";" );
 
                         sc.addobjectName + ".set" + capFieldName + "( " + associationName + " );" );
 
                         sc.add"for ( Iterator j = childElement.nodeIterator(); j.hasNext(); )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Node n = (Node) j.next();" );
 
                         sc.add"if ( n.getNodeType() == Node.ELEMENT_NODE )" );
                         // TODO: track the whitespace in the model (other NodeTypes)
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Element listElement = (Element) n;" );
 
                         sc.add"if ( \"" + valuesTagName + "\".equals( listElement.getName() ) )" );
 
                         sc.add"{" );
                         sc.indent();
                     }
                     else
                     {
                         sc.add( ( addElse ? "else " : "" )
                             + "if ( \"" + valuesTagName + "\".equals( childElement.getName() ) )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Element listElement = childElement;" );
 
                         sc.addtype + " " + associationName + " = " + objectName + ".get" + capFieldName + "();" );
 
                         sc.add"if ( " + associationName + " == null )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.addassociationName + " = " + association.getDefaultValue() + ";" );
 
                         sc.addobjectName + ".set" + capFieldName + "( " + associationName + " );" );
 
                         sc.unindent();
                         sc.add"}" );
                     }
 
                     if ( isClassInModelassociation.getTo(), field.getModelClass().getModel() ) )
                     {
                         sc.addassociationName + ".add( parse" + association.getTo() + "( \"" + valuesTagName
                             + "\", listElement, strict ) );" );
                     }
                     else
                     {
                         writePrimitiveFieldassociationassociation.getTo(), associationName"add"scjClass,
                                              "childElement""listElement" );
                     }
 
                     if ( wrappedItems )
                     {
                         sc.unindent();
                         sc.add"}" );
 
                         sc.add"else" );
 
                         sc.add"{" );
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
                     }
                     else
                     {
                         sc.unindent();
                         sc.add"}" );
                     }
                 }
                 else
                 {
                     //Map or Properties
 
                     sc.addtagComparison );
 
                     sc.add"{" );
                     sc.indent();
 
                     if ( xmlAssociationMetadata.isMapExplode() )
                     {
                         sc.add"for ( Iterator j = childElement.nodeIterator(); j.hasNext(); )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Node n = (Node) j.next();" );
 
                         sc.add"if ( n.getNodeType() == Node.ELEMENT_NODE )" );
                         // TODO: track the whitespace in the model (other NodeTypes)
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Element listElement = (Element) n;" );
 
                         sc.add"if ( \"" + valuesTagName + "\".equals( listElement.getName() ) )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"String key = null;" );
 
                         sc.add"String value = null;" );
 
                         sc.add"//" + xmlAssociationMetadata.getMapStyle() + " mode." );
 
                         sc.add"for ( Iterator k = listElement.nodeIterator(); k.hasNext(); )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Node nd = (Node) k.next();" );
 
                         sc.add"if ( nd.getNodeType() == Node.ELEMENT_NODE )" );
                         // TODO: track the whitespace in the model (other NodeTypes)
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Element propertyElement = (Element) nd;" );
 
                         sc.add"if ( \"key\".equals( propertyElement.getName() ) )" );
 
                         sc.add"{" );
                         sc.addIndented"key = propertyElement.getText();" );
                         sc.add"}" );
 
                         sc.add"else if ( \"value\".equals( propertyElement.getName() ) )" );
 
                         sc.add"{" );
                         sc.addIndented"value = propertyElement.getText()"
                                         + ( xmlFieldMetadata.isTrim() ? ".trim()" : "" ) + ";" );
                         sc.add"}" );
 
                         sc.add"else" );
 
                         sc.add"{" );
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.addobjectName + ".add" + capitalisesingularName ) + "( key, value );" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
                     }
                     else
                     {
                         //INLINE Mode
 
                         sc.add"for ( Iterator j = childElement.nodeIterator(); j.hasNext(); )" );
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Node n = (Node) j.next();" );
 
                         sc.add"if ( n.getNodeType() == Node.ELEMENT_NODE )" );
                         // TODO: track the whitespace in the model (other NodeTypes)
 
                         sc.add"{" );
                         sc.indent();
 
                         sc.add"Element listElement = (Element) n;" );
 
                         sc.add"String key = listElement.getName();" );
 
                         sc.add"String value = listElement.getText()"
                                 + ( xmlFieldMetadata.isTrim() ? ".trim()" : "" ) + ";" );
 
                         sc.addobjectName + ".add" + capitalisesingularName ) + "( key, value );" );
 
                         sc.unindent();
                         sc.add"}" );
 
                         sc.unindent();
                         sc.add"}" );
                     }
 
                     sc.unindent();
                     sc.add"}" );
                 }
             }
         }
         else
         {
             sc.addtagComparison );
 
             sc.add"{" );
             sc.indent();
 
             //ModelField
             writePrimitiveFieldfieldfield.getType(), objectName"set" + capitalisefield.getName() ), sc,
                                  jClass"element""childElement" );
 
             sc.unindent();
             sc.add"}" );
         }
     }
 
     private void writePrimitiveFieldModelField fieldString typeString objectNameString setterName,
                                       JSourceCode scJClass jClassString parentElementNameString childElementName )
     {
         XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadatafield.getMetadata. );
 
         String tagName = resolveTagNamefieldxmlFieldMetadata );
 
         String parserGetter;
         if ( xmlFieldMetadata.isAttribute() )
         {
             parserGetter = parentElementName + ".attributeValue( \"" + tagName + "\" )";
         }
         else
         {
             parserGetter = childElementName + ".getText()";
         }
 
 // TODO: this and a default
 //        if ( fieldMetaData.isRequired() )
 //        {
 //            parserGetter = "getRequiredAttributeValue( " + parserGetter + ", \"" + tagName + "\", parser, strict, encoding )";
 //        }
 //
 
         if ( xmlFieldMetadata.isTrim() )
         {
             parserGetter = "getTrimmedValue( " + parserGetter + " )";
         }
 
         if ( "boolean".equalstype ) )
         {
             sc.add(
                 objectName + "." + setterName + "( getBooleanValue( " + parserGetter + ", \"" + tagName + "\" ) );" );
         }
         else if ( "char".equalstype ) )
         {
             sc.add(
                 objectName + "." + setterName + "( getCharacterValue( " + parserGetter + ", \"" + tagName + "\" ) );" );
         }
         else if ( "double".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( getDoubleValue( " + parserGetter + ", \"" + tagName
                 + "\", strict ) );" );
         }
         else if ( "float".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( getFloatValue( " + parserGetter + ", \"" + tagName
                 + "\", strict ) );" );
         }
         else if ( "int".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( getIntegerValue( " + parserGetter + ", \"" + tagName
                 + "\", strict ) );" );
         }
         else if ( "long".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( getLongValue( " + parserGetter + ", \"" + tagName
                 + "\", strict ) );" );
         }
         else if ( "short".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( getShortValue( " + parserGetter + ", \"" + tagName
                 + "\", strict ) );" );
         }
         else if ( "byte".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( getByteValue( " + parserGetter + ", \"" + tagName
                 + "\", strict ) );" );
         }
         else if ( "String".equalstype ) || "Boolean".equalstype ) )
         {
             // TODO: other Primitive types
             sc.addobjectName + "." + setterName + "( " + parserGetter + " );" );
         }
         else if ( "Date".equalstype ) )
         {
             sc.add"String dateFormat = "
                 + ( xmlFieldMetadata.getFormat() != null ? "\"" + xmlFieldMetadata.getFormat() + "\"" : "null" ) + ";" );
             sc.addobjectName + "." + setterName + "( getDateValue( " + parserGetter + ", \"" + tagName
                 + "\", dateFormat ) );" );
         }
         else if ( "DOM".equalstype ) )
         {
             sc.addobjectName + "." + setterName + "( writeElementToXpp3Dom( " + childElementName + " ) );" );
 
              = true;
         }
         else
         {
             throw new IllegalArgumentException"Unknown type: " + type );
         }
     }
 
     private void writeHelpersJClass jClass )
     {
         JMethod method = new JMethod"getTrimmedValue"new JClass"String" ), null );
         method.getModifiers().makePrivate();
 
         method.addParameternew JParameternew JClass"String" ), "s" ) );
 
         JSourceCode sc = method.getSourceCode();
 
         sc.add"if ( s != null )" );
 
         sc.add"{" );
         sc.addIndented"s = s.trim();" );
         sc.add"}" );
 
         sc.add"return s;" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
 /* TODO
         method = new JMethod( new JClass( "String" ), "getRequiredAttributeValue" );
         method.addException( new JClass( "XmlPullParserException" ) );
         method.getModifiers().makePrivate();
 
         method.addParameter( new JParameter( new JClass( "String" ), "s" ) );
         method.addParameter( new JParameter( new JClass( "String" ), "attribute" ) );
         method.addParameter( new JParameter( new JClass( "XmlPullParser" ), "parser" ) );
         method.addParameter( new JParameter( JClass.Boolean, "strict" ) );
 
         sc = method.getSourceCode();
 
         sc.add( "if ( s == null )" );
 
         sc.add( "{" );
         sc.indent();
 
         sc.add( "if ( strict )" );
 
         sc.add( "{" );
         sc.addIndented(
             "throw new XmlPullParserException( \"Missing required value for attribute '\" + attribute + \"'\", parser, null );" );
         sc.add( "}" );
 
         sc.unindent();
         sc.add( "}" );
 
         sc.add( "return s;" );
 
         jClass.addMethod( method );
 */
         // --------------------------------------------------------------------
 
         method = new JMethod"getBooleanValue".null );
         method.getModifiers().makePrivate();
 
         method.addParameternew JParameternew JClass"String" ), "s" ) );
         method.addParameternew JParameternew JClass"String" ), "attribute" ) );
 
         sc = method.getSourceCode();
 
         sc.add"if ( s != null )" );
 
         sc.add"{" );
         sc.addIndented"return Boolean.valueOf( s ).booleanValue();" );
         sc.add"}" );
 
         sc.add"return false;" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = new JMethod"getCharacterValue".null );
         method.getModifiers().makePrivate();
 
         method.addParameternew JParameternew JClass"String" ), "s" ) );
         method.addParameternew JParameternew JClass"String" ), "attribute" ) );
 
         sc = method.getSourceCode();
 
         sc.add"if ( s != null )" );
 
         sc.add"{" );
         sc.addIndented"return s.charAt( 0 );" );
         sc.add"}" );
 
         sc.add"return 0;" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = convertNumericalType"getIntegerValue"."Integer.valueOf( s ).intValue()""an integer" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = convertNumericalType"getShortValue"."Short.valueOf( s ).shortValue()",
                                        "a short integer" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = convertNumericalType"getByteValue"."Byte.valueOf( s ).byteValue()""a byte" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = convertNumericalType"getLongValue"."Long.valueOf( s ).longValue()""a long integer" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = convertNumericalType"getFloatValue"."Float.valueOf( s ).floatValue()",
                                        "a floating point number" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = convertNumericalType"getDoubleValue"."Double.valueOf( s ).doubleValue()",
                                        "a floating point number" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = new JMethod"getDateValue"new JClass"java.util.Date" ), null );
         method.getModifiers().makePrivate();
 
         method.addParameternew JParameternew JClass"String" ), "s" ) );
         method.addParameternew JParameternew JClass"String" ), "attribute" ) );
         method.addParameternew JParameternew JClass"String" ), "dateFormat" ) );
         method.addExceptionnew JClass"DocumentException" ) );
 
         writeDateParsingHelpermethod.getSourceCode(), "new DocumentException( e.getMessage(), e )" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = new JMethod"checkFieldWithDuplicate".null );
         method.getModifiers().makePrivate();
 
         method.addParameternew JParameternew JClass"Element" ), "element" ) );
         method.addParameternew JParameternew JClass"String" ), "tagName" ) );
         method.addParameternew JParameternew JClass"String" ), "alias" ) );
         method.addParameternew JParameternew JClass"java.util.Set" ), "parsed" ) );
         method.addExceptionnew JClass"DocumentException" ) );
 
         sc = method.getSourceCode();
 
         sc.add"if ( !( element.getName().equals( tagName ) || element.getName().equals( alias ) ) )" );
 
         sc.add"{" );
         sc.addIndented"return false;" );
         sc.add"}" );
 
         sc.add"if ( !parsed.add( tagName ) )" );
 
         sc.add"{" );
         sc.addIndented"throw new DocumentException( \"Duplicated tag: '\" + tagName + \"'\" );" );
         sc.add"}" );
 
         sc.add"return true;" );
 
         jClass.addMethodmethod );
 
         // --------------------------------------------------------------------
 
         method = new JMethod"checkUnknownElement"nullnull );
         method.getModifiers().makePrivate();
 
         method.addParameternew JParameternew JClass"Element" ), "element" ) );
         method.addParameternew JParameter."strict" ) );
         method.addExceptionnew JClass"DocumentException" ) );
 
         sc = method.getSourceCode();
 
         sc.add"if ( strict )" );
 
        sc.add"{" );
        sc.addIndented"throw new DocumentException( \"Unrecognised tag: '\" + element.getName() + \"'\" );" );
        sc.add"}" );
        jClass.addMethodmethod );
    }
    private void writeDomHelpersJClass jClass )
    {
        JMethod method = new JMethod"writeElementToXpp3Dom"new JClass"Xpp3Dom" ), null );
        method.getModifiers().makePrivate();
        method.addParameternew JParameternew JClass"Element" ), "element" ) );
        JSourceCode sc = method.getSourceCode();
        sc.add"Xpp3Dom xpp3Dom = new Xpp3Dom( element.getName() );" );
        sc.add"if ( element.elements().isEmpty() && element.getText() != null )" );
        sc.add"{" );
        sc.addIndented"xpp3Dom.setValue( element.getText() );" );
        sc.add"}" );
        sc.add"for ( Iterator i = element.attributeIterator(); i.hasNext(); )" );
        sc.add"{" );
        sc.indent();
        sc.add"Attribute attribute = (Attribute) i.next();" );
        sc.add"xpp3Dom.setAttribute( attribute.getName(), attribute.getValue() );" );
        sc.unindent();
        sc.add"}" );
        // TODO: would be nice to track whitespace in here
        sc.add"for ( Iterator i = element.elementIterator(); i.hasNext(); )" );
        sc.add"{" );
        sc.indent();
        sc.add"Element child = (Element) i.next();" );
        sc.add"xpp3Dom.addChild( writeElementToXpp3Dom( child ) );" );
        sc.unindent();
        sc.add"}" );
        sc.add"return xpp3Dom;" );
        jClass.addMethodmethod );
    }
    private JMethod convertNumericalTypeString methodNameJType returnTypeString expressionString typeDesc )
    {
        JMethod method = new JMethodmethodNamereturnTypenull );
        method.addExceptionnew JClass"DocumentException" ) );
        method.getModifiers().makePrivate();
        method.addParameternew JParameternew JClass"String" ), "s" ) );
        method.addParameternew JParameternew JClass"String" ), "attribute" ) );
        method.addParameternew JParameter."strict" ) );
        JSourceCode sc = method.getSourceCode();
        sc.add"if ( s != null )" );
        sc.add"{" );