org.codehaus.modello.plugin.jdom.JDOMWriterGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modello-plugin-jdom Show documentation
Show all versions of modello-plugin-jdom Show documentation
Modello JDOM Plugin generates XML writers based on JDOM API.
/* ==========================================================================
* Copyright 2005 Mevenide Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================================================================
*/
package org.codehaus.modello.plugin.jdom;
import org.codehaus.modello.ModelloException;
import org.codehaus.modello.model.Model;
import org.codehaus.modello.model.ModelAssociation;
import org.codehaus.modello.model.ModelClass;
import org.codehaus.modello.model.ModelDefault;
import org.codehaus.modello.model.ModelField;
import org.codehaus.modello.plugin.java.javasource.JClass;
import org.codehaus.modello.plugin.java.javasource.JConstructor;
import org.codehaus.modello.plugin.java.javasource.JField;
import org.codehaus.modello.plugin.java.javasource.JMethod;
import org.codehaus.modello.plugin.java.javasource.JParameter;
import org.codehaus.modello.plugin.java.javasource.JSourceCode;
import org.codehaus.modello.plugin.java.javasource.JSourceWriter;
import org.codehaus.modello.plugin.java.javasource.JType;
import org.codehaus.modello.plugin.java.metadata.JavaClassMetadata;
import org.codehaus.modello.plugin.java.metadata.JavaFieldMetadata;
import org.codehaus.modello.plugins.xml.metadata.XmlAssociationMetadata;
import org.codehaus.modello.plugins.xml.metadata.XmlFieldMetadata;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* @author [email protected]
*/
public class JDOMWriterGenerator
extends AbstractJDOMGenerator
{
public void generate( Model model, Properties parameters )
throws ModelloException
{
initialize( model, parameters );
try
{
generateJDOMWriter();
}
catch ( IOException ex )
{
throw new ModelloException( "Exception while generating JDOM Writer.", ex );
}
}
private void generateJDOMWriter()
throws ModelloException, IOException
{
Model objectModel = getModel();
String packageName= objectModel.getDefaultPackageName( isPackageWithVersion(), getGeneratedVersion() )
+ ".io.jdom";
String marshallerName = getFileName( "JDOMWriter" );
JSourceWriter sourceWriter = newJSourceWriter( packageName, marshallerName );
JClass jClass = new JClass( packageName + '.' + marshallerName );
initHeader( jClass );
suppressAllWarnings( objectModel, jClass );
// -------------------------------------------------------------
// imports now
// -------------------------------------------------------------
jClass.addImport( "java.io.OutputStream" );
jClass.addImport( "java.io.OutputStreamWriter" );
jClass.addImport( "java.io.Writer" );
jClass.addImport( "java.text.DateFormat" );
jClass.addImport( "java.util.ArrayList" );
jClass.addImport( "java.util.Collection" );
jClass.addImport( "java.util.Iterator" );
jClass.addImport( "java.util.List" );
jClass.addImport( "java.util.ListIterator" );
jClass.addImport( "java.util.Locale" );
jClass.addImport( "java.util.Map" );
jClass.addImport( "java.util.Properties" );
jClass.addImport( "org.jdom.Content" );
jClass.addImport( "org.jdom.DefaultJDOMFactory" );
jClass.addImport( "org.jdom.Document" );
jClass.addImport( "org.jdom.Element" );
jClass.addImport( "org.jdom.Text" );
jClass.addImport( "org.jdom.output.Format" );
jClass.addImport( "org.jdom.output.XMLOutputter" );
jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" );
addModelImports( jClass, null );
jClass.addField( new JField( new JClass( "DefaultJDOMFactory" ), "factory" ) );
jClass.addField( new JField( new JClass( "String" ), "lineSeparator" ) );
createCounter( jClass );
// constructor --
JConstructor constructor = jClass.createConstructor();
JSourceCode constCode = constructor.getSourceCode();
constCode.add( "factory = new DefaultJDOMFactory();" );
constCode.add( "lineSeparator = \"\\n\";" );
String root = objectModel.getRoot( getGeneratedVersion() );
ModelClass rootClass = objectModel.getClass( root, getGeneratedVersion() );
String rootElement = resolveTagName( rootClass );
// the public global write method..
jClass.addMethod( generateWriteModel( root, rootElement ) );
jClass.addMethod( generateWriteModel2( root, rootElement ) );
jClass.addMethod( generateWriteModel3( root, rootElement ) );
// the private utility classes;
jClass.addMethods( generateUtilityMethods() );
writeAllClasses( objectModel, jClass, rootClass );
jClass.print( sourceWriter );
sourceWriter.close();
}
private void createCounter( final JClass jClass )
throws IllegalArgumentException
{
// inner counter class
JClass counter = jClass.createInnerClass( "Counter" );
counter.getModifiers().setStatic( true );
JField fld = new JField( new JType( "int" ), "currentIndex" );
fld.setInitString( "0" );
counter.addField( fld );
fld = new JField( new JType( "int" ), "level" );
counter.addField( fld );
JConstructor constr =
counter.createConstructor( new JParameter[] { new JParameter( new JType( "int" ), "depthLevel" ) } );
constr.getSourceCode().append( "level = depthLevel;" );
JMethod inc = new JMethod( "increaseCount" );
inc.getSourceCode().add( "currentIndex = currentIndex + 1;" );
counter.addMethod( inc );
JMethod getter = new JMethod( "getCurrentIndex", new JType( "int" ), null );
getter.getSourceCode().add( "return currentIndex;" );
counter.addMethod( getter );
getter = new JMethod( "getDepth", new JType( "int" ), null );
getter.getSourceCode().add( "return level;" );
counter.addMethod( getter );
}
private JMethod generateWriteModel( String root, String rootElement )
{
JMethod marshall = new JMethod( "write" );
marshall.addParameter( new JParameter( new JClass( root ), rootElement ) );
marshall.addParameter( new JParameter( new JClass( "Document" ), "document" ) );
marshall.addParameter( new JParameter( new JClass( "OutputStream" ), "stream" ) );
marshall.addException( new JClass( "java.io.IOException" ) );
marshall.getJDocComment().appendComment( "\n@deprecated" );
JSourceCode sc = marshall.getSourceCode();
sc.add( "update" + root + "( " + rootElement + ", \"" + rootElement
+ "\", new Counter( 0 ), document.getRootElement() );" );
sc.add( "XMLOutputter outputter = new XMLOutputter();" );
sc.add( "outputter.setFormat( Format.getPrettyFormat()" );
sc.add( " .setIndent( \" \" )" );
sc.add( " .setLineSeparator( System.getProperty( \"line.separator\" ) ) );" );
sc.add( "outputter.output( document, stream );" );
return marshall;
}
private JMethod generateWriteModel2( String root, String rootElement )
{
JMethod marshall = new JMethod( "write" );
marshall.addParameter( new JParameter( new JClass( root ), rootElement ) );
marshall.addParameter( new JParameter( new JClass( "Document" ), "document" ) );
marshall.addParameter( new JParameter( new JClass( "OutputStreamWriter" ), "writer" ) );
marshall.addException( new JClass( "java.io.IOException" ) );
JSourceCode sc = marshall.getSourceCode();
sc.add( "Format format = Format.getRawFormat()" );
sc.add( " .setEncoding( writer.getEncoding() )" );
sc.add( " .setLineSeparator( System.getProperty( \"line.separator\" ) );" );
sc.add( "write( " + rootElement + ", document, writer, format );" );
return marshall;
}
private JMethod generateWriteModel3( String root, String rootElement )
{
JMethod marshall = new JMethod( "write" );
marshall.addParameter( new JParameter( new JClass( root ), rootElement ) );
marshall.addParameter( new JParameter( new JClass( "Document" ), "document" ) );
marshall.addParameter( new JParameter( new JClass( "Writer" ), "writer" ) );
marshall.addParameter( new JParameter( new JClass( "Format" ), "jdomFormat" ) );
marshall.addException( new JClass( "java.io.IOException" ) );
JSourceCode sc = marshall.getSourceCode();
sc.add( "update" + root + "( " + rootElement + ", \"" + rootElement
+ "\", new Counter( 0 ), document.getRootElement() );" );
sc.add( "XMLOutputter outputter = new XMLOutputter();" );
sc.add( "outputter.setFormat( jdomFormat );" );
sc.add( "outputter.output( document, writer );" );
return marshall;
}
private JMethod[] generateUtilityMethods()
{
JMethod findRSElement = new JMethod( "findAndReplaceSimpleElement", new JClass( "Element" ), null );
findRSElement.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
findRSElement.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
findRSElement.addParameter( new JParameter( new JClass( "String" ), "name" ) );
findRSElement.addParameter( new JParameter( new JClass( "String" ), "text" ) );
findRSElement.addParameter( new JParameter( new JClass( "String" ), "defaultValue" ) );
findRSElement.getModifiers().makeProtected();
JSourceCode sc = findRSElement.getSourceCode();
sc.add( "if ( ( defaultValue != null ) && ( text != null ) && defaultValue.equals( text ) )" );
sc.add( "{" );
sc.indent();
sc.add( "Element element = parent.getChild( name, parent.getNamespace() );" );
sc.add( "// if exist and is default value or if doesn't exist.. just keep the way it is.." );
sc.add( "if ( ( element != null && defaultValue.equals( element.getText() ) ) || element == null )" );
sc.add( "{" );
sc.addIndented( "return element;" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "boolean shouldExist = ( text != null ) && ( text.trim().length() > 0 );" );
sc.add( "Element element = updateElement( counter, parent, name, shouldExist );" );
sc.add( "if ( shouldExist )" );
sc.add( "{" );
sc.addIndented( "element.setText( text );" );
sc.add( "}" );
sc.add( "return element;" );
JMethod updateElement = new JMethod( "updateElement", new JClass( "Element" ), null );
updateElement.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
updateElement.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
updateElement.addParameter( new JParameter( new JClass( "String" ), "name" ) );
updateElement.addParameter( new JParameter( new JType( "boolean" ), "shouldExist" ) );
updateElement.getModifiers().makeProtected();
sc = updateElement.getSourceCode();
sc.add( "Element element = parent.getChild( name, parent.getNamespace() );" );
sc.add( "if ( element != null && shouldExist )" );
sc.add( "{" );
sc.addIndented( "counter.increaseCount();" );
sc.add( "}" );
sc.add( "if ( element == null && shouldExist )" );
sc.add( "{" );
sc.indent();
sc.add( "element = factory.element( name, parent.getNamespace() );" );
sc.add( "insertAtPreferredLocation( parent, element, counter );" );
sc.add( "counter.increaseCount();" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( !shouldExist && element != null )" );
sc.add( "{" );
sc.indent();
sc.add( "int index = parent.indexOf( element );" );
sc.add( "if ( index > 0 )" );
sc.add( "{" );
sc.indent();
sc.add( "Content previous = parent.getContent( index - 1 );" );
sc.add( "if ( previous instanceof Text )" );
sc.add( "{" );
sc.indent();
sc.add( "Text txt = (Text) previous;" );
sc.add( "if ( txt.getTextTrim().length() == 0 )" );
sc.add( "{" );
sc.addIndented( "parent.removeContent( txt );" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "parent.removeContent( element );" );
sc.unindent();
sc.add( "}" );
sc.add( "return element;" );
JMethod insAtPref = new JMethod( "insertAtPreferredLocation" );
insAtPref.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
insAtPref.addParameter( new JParameter( new JClass( "Element" ), "child" ) );
insAtPref.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
insAtPref.getModifiers().makeProtected();
sc = insAtPref.getSourceCode();
sc.add( "int contentIndex = 0;" );
sc.add( "int elementCounter = 0;" );
sc.add( "Iterator it = parent.getContent().iterator();" );
sc.add( "Text lastText = null;" );
sc.add( "int offset = 0;" );
sc.add( "while ( it.hasNext() && elementCounter <= counter.getCurrentIndex() )" );
sc.add( "{" );
sc.indent();
sc.add( "Object next = it.next();" );
sc.add( "offset = offset + 1;" );
sc.add( "if ( next instanceof Element )" );
sc.add( "{" );
sc.indent();
sc.add( "elementCounter = elementCounter + 1;" );
sc.add( "contentIndex = contentIndex + offset;" );
sc.add( "offset = 0;" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( next instanceof Text && it.hasNext() )" );
sc.add( "{" );
sc.addIndented( "lastText = (Text) next;" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
// sc.add("if ( lastText == null )" );
// sc.add( "{" );
// sc.indent();
// sc.add( "int index = parent.getParentElement().indexOf( parent );" );
// sc.add( "if ( index > 0 ) ");
// sc.add( "{" );
// sc.indent();
// sc.add( "Content cont = parent.getParentElement().getContent( index - 1 );" );
// sc.add( "if ( cont instanceof Text )" );
// sc.add( "{" );
// sc.addIndented( "lastText = (Text) cont;" );
// sc.add( "}" );
// sc.unindent();
// sc.add( "}" );
// sc.unindent();
// sc.add( "}" );
sc.add( "if ( lastText != null && lastText.getTextTrim().length() == 0 )" );
sc.add( "{" );
sc.addIndented( "lastText = (Text) lastText.clone();" );
sc.add( "}" );
sc.add( "else" );
sc.add( "{" );
sc.indent();
sc.add( "String starter = lineSeparator;" );
sc.add( "for ( int i = 0; i < counter.getDepth(); i++ )" );
sc.add( "{" );
sc.addIndented( "starter = starter + \" \"; //TODO make settable?" );
sc.add( "}" );
sc.add( "lastText = factory.text( starter );" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( parent.getContentSize() == 0 )" );
sc.add( "{" );
sc.indent();
sc.add( "Text finalText = (Text) lastText.clone();" );
sc.add(
"finalText.setText( finalText.getText().substring( 0, finalText.getText().length() - \" \".length() ) );"
);
sc.add( "parent.addContent( contentIndex, finalText );" );
sc.unindent();
sc.add( "}" );
sc.add( "parent.addContent( contentIndex, child );" );
sc.add( "parent.addContent( contentIndex, lastText );" );
JMethod findRSProps = new JMethod( "findAndReplaceProperties", new JClass( "Element" ), null );
findRSProps.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
findRSProps.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
findRSProps.addParameter( new JParameter( new JClass( "String" ), "name" ) );
findRSProps.addParameter( new JParameter( new JClass( "Map" ), "props" ) );
findRSProps.getModifiers().makeProtected();
sc = findRSProps.getSourceCode();
sc.add( "boolean shouldExist = ( props != null ) && ! props.isEmpty();" );
sc.add( "Element element = updateElement( counter, parent, name, shouldExist );" );
sc.add( "if ( shouldExist )" );
sc.add( "{" );
sc.indent();
sc.add( "Iterator it = props.keySet().iterator();" );
sc.add( "Counter innerCounter = new Counter( counter.getDepth() + 1 );" );
sc.add( "while ( it.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "String key = (String) it.next();" );
sc.add( "findAndReplaceSimpleElement( innerCounter, element, key, (String) props.get( key ), null );" );
sc.unindent();
sc.add( "}" );
sc.add( "ArrayList lst = new ArrayList( props.keySet() );" );
sc.add( "it = element.getChildren().iterator();" );
sc.add( "while ( it.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "Element elem = (Element) it.next();" );
sc.add( "String key = elem.getName();" );
sc.add( "if ( !lst.contains( key ) )" );
sc.add( "{" );
sc.addIndented( "it.remove();" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "return element;" );
JMethod findRSLists = new JMethod( "findAndReplaceSimpleLists", new JClass( "Element" ), null );
findRSLists.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
findRSLists.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
findRSLists.addParameter( new JParameter( new JClass( "java.util.Collection" ), "list" ) );
findRSLists.addParameter( new JParameter( new JClass( "String" ), "parentName" ) );
findRSLists.addParameter( new JParameter( new JClass( "String" ), "childName" ) );
findRSLists.getModifiers().makeProtected();
sc = findRSLists.getSourceCode();
sc.add( "boolean shouldExist = ( list != null ) && ( list.size() > 0 );" );
sc.add( "Element element = updateElement( counter, parent, parentName, shouldExist );" );
sc.add( "if ( shouldExist )" );
sc.add( "{" );
sc.indent();
sc.add( "Iterator it = list.iterator();" );
sc.add( "Iterator elIt = element.getChildren( childName, element.getNamespace() ).iterator();" );
sc.add( "if ( ! elIt.hasNext() )" );
sc.add( "{" );
sc.addIndented( " elIt = null;" );
sc.add( "}" );
sc.add( "Counter innerCount = new Counter( counter.getDepth() + 1 );" );
sc.add( "while ( it.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "String value = (String) it.next();" );
sc.add( "Element el;" );
sc.add( "if ( elIt != null && elIt.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "el = (Element) elIt.next();" );
sc.add( "if ( ! elIt.hasNext() )" );
sc.add( "{" );
sc.addIndented( "elIt = null;" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "else" );
sc.add( "{" );
sc.indent();
sc.add( "el = factory.element( childName, element.getNamespace() );" );
sc.add( "insertAtPreferredLocation( element, el, innerCount );" );
sc.unindent();
sc.add( "}" );
sc.add( "el.setText( value );" );
sc.add( "innerCount.increaseCount();" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( elIt != null )" );
sc.add( "{" );
sc.indent();
sc.add( "while ( elIt.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "elIt.next();" );
sc.add( "elIt.remove();" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "return element;" );
JMethod findRSDom = new JMethod( "findAndReplaceXpp3DOM", new JClass( "Element" ), null );
findRSDom.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
findRSDom.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
findRSDom.addParameter( new JParameter( new JClass( "String" ), "name" ) );
findRSDom.addParameter( new JParameter( new JClass( "Xpp3Dom" ), "dom" ) );
findRSDom.getModifiers().makeProtected();
sc = findRSDom.getSourceCode();
sc.add( "boolean shouldExist = ( dom != null ) && ( dom.getChildCount() > 0 || dom.getValue() != null );" );
sc.add( "Element element = updateElement( counter, parent, name, shouldExist );" );
sc.add( "if ( shouldExist )" );
sc.add( "{" );
sc.addIndented( "replaceXpp3DOM( element, dom, new Counter( counter.getDepth() + 1 ) );" );
sc.add( "}" );
sc.add( "return element;" );
JMethod findRSDom2 = new JMethod( "replaceXpp3DOM" );
findRSDom2.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
findRSDom2.addParameter( new JParameter( new JClass( "Xpp3Dom" ), "parentDom" ) );
findRSDom2.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
findRSDom2.getModifiers().makeProtected();
sc = findRSDom2.getSourceCode();
sc.add( "if ( parentDom.getChildCount() > 0 )" );
sc.add( "{" );
sc.indent();
sc.add( "Xpp3Dom[] childs = parentDom.getChildren();" );
sc.add( "Collection domChilds = new ArrayList();" );
sc.add( "for ( int i = 0; i < childs.length; i++ )" );
sc.add( "{" );
sc.addIndented( "domChilds.add( childs[i] );" );
sc.add( "}" );
sc.add( "ListIterator it = parent.getChildren().listIterator();" );
sc.add( "while ( it.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "Element elem = (Element) it.next();" );
sc.add( "Iterator it2 = domChilds.iterator();" );
sc.add( "Xpp3Dom corrDom = null;" );
sc.add( "while ( it2.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "Xpp3Dom dm = (Xpp3Dom) it2.next();" );
sc.add( "if ( dm.getName().equals( elem.getName() ) )" );
sc.add( "{" );
sc.indent();
sc.add( "corrDom = dm;" );
sc.add( "break;" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( corrDom != null )" );
sc.add( "{" );
sc.indent();
sc.add( "domChilds.remove( corrDom );" );
sc.add( "replaceXpp3DOM( elem, corrDom, new Counter( counter.getDepth() + 1 ) );" );
sc.add( "counter.increaseCount();" );
sc.unindent();
sc.add( "}" );
sc.add( "else" );
sc.add( "{" );
sc.addIndented( "it.remove();" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "Iterator it2 = domChilds.iterator();" );
sc.add( "while ( it2.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "Xpp3Dom dm = (Xpp3Dom) it2.next();" );
sc.add( "Element elem = factory.element( dm.getName(), parent.getNamespace() );" );
sc.add( "insertAtPreferredLocation( parent, elem, counter );" );
sc.add( "counter.increaseCount();" );
sc.add( "replaceXpp3DOM( elem, dm, new Counter( counter.getDepth() + 1 ) );" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( " else if ( parentDom.getValue() != null )" );
sc.add( "{" );
sc.addIndented( "parent.setText( parentDom.getValue() );" );
sc.add( "}" );
return new JMethod[]{findRSElement, updateElement, insAtPref, findRSProps, findRSLists, findRSDom, findRSDom2};
}
private void writeAllClasses( Model objectModel, JClass jClass, ModelClass rootClass )
throws ModelloException
{
ArrayList alwaysExistingElements = new ArrayList();
alwaysExistingElements.add( rootClass );
for ( Iterator i = objectModel.getClasses( getGeneratedVersion() ).iterator(); i.hasNext(); )
{
ModelClass clazz = (ModelClass) i.next();
JavaClassMetadata javaClassMetadata = (JavaClassMetadata) clazz.getMetadata( JavaClassMetadata.ID );
if ( !javaClassMetadata.isEnabled() )
{
// Skip import of those classes that are not enabled for the java plugin.
continue;
}
updateClass( clazz, jClass, alwaysExistingElements );
}
}
private void updateClass( ModelClass clazz, JClass jClass, ArrayList alwaysExisting )
throws ModelloException
{
String className = clazz.getName();
String uncapClassName = uncapitalise( className );
String clazzTagName = null;
if ( clazz.hasMetadata( XmlFieldMetadata.ID ) )
{
XmlFieldMetadata clazzMetadata = (XmlFieldMetadata) clazz.getMetadata( XmlFieldMetadata.ID );
clazzTagName = clazzMetadata.getTagName();
}
JMethod marshall = new JMethod( "update" + className );
marshall.addParameter( new JParameter( new JClass( className ), "value" ) );
marshall.addParameter( new JParameter( new JClass( "String" ), "xmlTag" ) );
marshall.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
marshall.addParameter( new JParameter( new JClass( "Element" ), "element" ) );
marshall.getModifiers().makeProtected();
if ( clazzTagName == null )
{
clazzTagName = uncapClassName;
}
JSourceCode sc = marshall.getSourceCode();
boolean shouldExist = alwaysExisting.contains( clazz );
if ( shouldExist )
{
sc.add( "Element root = element;" );
}
else
{
sc.add( "boolean shouldExist = ( value != null );" );
sc.add( "Element root = updateElement( counter, element, xmlTag, shouldExist );" );
sc.add( "if ( shouldExist )" );
sc.add( "{" );
sc.indent();
}
sc.add( "Counter innerCount = new Counter( counter.getDepth() + 1 );" );
List modelFields = clazz.getAllFields( getGeneratedVersion(), true );
modelFields = getNonTransientFields( modelFields );
for ( Iterator i = modelFields.iterator(); i.hasNext(); )
{
ModelField field = (ModelField) i.next();
XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadata) field.getMetadata( XmlFieldMetadata.ID );
JavaFieldMetadata javaFieldMetadata = (JavaFieldMetadata) field.getMetadata( JavaFieldMetadata.ID );
String fieldTagName = resolveTagName( field, xmlFieldMetadata );
String type = field.getType();
String value = "value." + getPrefix( javaFieldMetadata ) + capitalise( field.getName() ) + "()";
if ( xmlFieldMetadata.isAttribute() )
{
continue;
}
if ( field instanceof ModelAssociation )
{
ModelAssociation association = (ModelAssociation) field;
ModelClass toClass = association.getToClass();
if ( association.isOneMultiplicity() )
{
sc.add( "update" + capitalise( field.getType() ) + "( " + value + ", \"" + fieldTagName
+ "\", innerCount, root );" );
}
else
{
//MANY_MULTIPLICITY
XmlAssociationMetadata xmlAssociationMetadata =
(XmlAssociationMetadata) association.getAssociationMetadata( XmlAssociationMetadata.ID );
//String valuesTagName = resolveTagName( fieldTagName, xmlAssociationMetadata );
//
// type = association.getType();
// String toType = association.getTo();
//
if ( ModelDefault.LIST.equals( type ) || ModelDefault.SET.equals( type ) )
{
// type = association.getType();
String toType = association.getTo();
if ( toClass != null )
{
if ( xmlAssociationMetadata.isWrappedItems() )
{
sc.add( "iterate" + capitalise( toType ) + "( innerCount, root, " + value + ",\""
+ field.getName() + "\",\"" + singular( fieldTagName ) + "\" );" );
createIterateMethod( field.getName(), toClass, singular( fieldTagName ), jClass );
}
else
{
//assume flat..
sc.add( "iterate2" + capitalise( toType ) + "( innerCount, root, " + value + ", \""
+ singular( fieldTagName ) + "\" );" );
createIterateMethod2( field.getName(), toClass, singular( fieldTagName ), jClass );
}
alwaysExisting.add( toClass );
}
else
{
//list of strings?
sc.add( "findAndReplaceSimpleLists( innerCount, root, " + value + ", \"" + fieldTagName
+ "\", \"" + singular( fieldTagName ) + "\" );" );
}
}
else
{
//Map or Properties
sc.add(
"findAndReplaceProperties( innerCount, root, \"" + fieldTagName + "\", " + value + " );" );
}
}
}
else
{
if ( "DOM".equals( field.getType() ) )
{
sc.add(
"findAndReplaceXpp3DOM( innerCount, root, \"" + fieldTagName + "\", (Xpp3Dom) " + value + " );" );
}
else
{
sc.add( "findAndReplaceSimpleElement( innerCount, root, \"" + fieldTagName + "\", "
+ getJdomValueChecker( type, value, field ) + getValue( type, value, xmlFieldMetadata ) + ", "
+ ( field.getDefaultValue() != null ? ( "\"" + field.getDefaultValue() + "\"" ) : "null" )
+ " );" );
}
}
}
if ( !shouldExist )
{
sc.unindent();
sc.add( "}" );
}
jClass.addMethod( marshall );
}
private String getJdomValueChecker( String type, String value, ModelField field )
throws ModelloException
{
if ( "boolean".equals( type ) || "double".equals( type ) || "float".equals( type ) || "int".equals( type )
|| "long".equals( type ) || "short".equals( type ) || "byte".equals( type ) || "char".equals( type ) )
{
return value + " == " + getJavaDefaultValue( field ) + " ? null : ";
}
else if ( ModelDefault.LIST.equals( type ) || ModelDefault.SET.equals( type )
|| ModelDefault.MAP.equals( type ) || ModelDefault.PROPERTIES.equals( type ) )
{
return value + " == null || " + value + ".size() == 0 ? null : ";
// } else if ( "String".equals( type ) && field.getDefaultValue() != null ) {
// return "" + value + " == null || " + value + ".equals( \"" + field.getDefaultValue() + "\" ) ? null : ";
}
else if ( "Date".equals( type ) && field.getDefaultValue() != null )
{
return "" + value + " == null || " + value + ".equals( " + getJavaDefaultValue( field ) + " ) ? null : ";
}
else
{
return value + " == null ? null : ";
}
}
private void createIterateMethod( String field, ModelClass toClass, String childFieldTagName, JClass jClass )
{
if ( jClass.getMethod( "iterate" + capitalise( toClass.getName() ), 0 ) != null )
{
// System.out.println("method iterate" + capitalise(field) + " already exists");
return;
}
JMethod toReturn = new JMethod( "iterate" + capitalise( toClass.getName() ) );
toReturn.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
toReturn.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
toReturn.addParameter( new JParameter( new JClass( "java.util.Collection" ), "list" ) );
toReturn.addParameter( new JParameter( new JClass( "java.lang.String" ), "parentTag" ) );
toReturn.addParameter( new JParameter( new JClass( "java.lang.String" ), "childTag" ) );
toReturn.getModifiers().makeProtected();
JSourceCode sc = toReturn.getSourceCode();
sc.add( "boolean shouldExist = ( list != null ) && ( list.size() > 0 );" );
sc.add( "Element element = updateElement( counter, parent, parentTag, shouldExist );" );
sc.add( "if ( shouldExist )" );
sc.add( "{" );
sc.indent();
sc.add( "Iterator it = list.iterator();" );
sc.add( "Iterator elIt = element.getChildren( childTag, element.getNamespace() ).iterator();" );
sc.add( "if ( !elIt.hasNext() )" );
sc.add( "{" );
sc.addIndented( "elIt = null;" );
sc.add( "}" );
sc.add( "Counter innerCount = new Counter( counter.getDepth() + 1 );" );
sc.add( "while ( it.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( toClass.getName() + " value = (" + toClass.getName() + ") it.next();" );
sc.add( "Element el;" );
sc.add( "if ( elIt != null && elIt.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "el = (Element) elIt.next();" );
sc.add( "if ( ! elIt.hasNext() )" );
sc.add( "{" );
sc.addIndented( " elIt = null;" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "else" );
sc.add( "{" );
sc.indent();
sc.add( "el = factory.element( childTag, element.getNamespace() );" );
sc.add( "insertAtPreferredLocation( element, el, innerCount );" );
sc.unindent();
sc.add( "}" );
sc.add( "update" + toClass.getName() + "( value, childTag, innerCount, el );" );
sc.add( "innerCount.increaseCount();" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( elIt != null )" );
sc.add( "{" );
sc.indent();
sc.add( "while ( elIt.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "elIt.next();" );
sc.add( "elIt.remove();" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
jClass.addMethod( toReturn );
}
private void createIterateMethod2( String field, ModelClass toClass, String childFieldTagName, JClass jClass )
{
if ( jClass.getMethod( "iterate2" + capitalise( toClass.getName() ), 0 ) != null )
{
// System.out.println("method iterate" + capitalise(field) + " already exists");
return;
}
JMethod toReturn = new JMethod( "iterate2" + capitalise( toClass.getName() ) );
toReturn.addParameter( new JParameter( new JClass( "Counter" ), "counter" ) );
toReturn.addParameter( new JParameter( new JClass( "Element" ), "parent" ) );
toReturn.addParameter( new JParameter( new JClass( "java.util.Collection" ), "list" ) );
toReturn.addParameter( new JParameter( new JClass( "java.lang.String" ), "childTag" ) );
toReturn.getModifiers().makeProtected();
JSourceCode sc = toReturn.getSourceCode();
sc.add( "Iterator it = list.iterator();" );
sc.add( "Iterator elIt = parent.getChildren( childTag, parent.getNamespace() ).iterator();" );
sc.add( "if ( !elIt.hasNext() )" );
sc.add( "{" );
sc.addIndented( "elIt = null;" );
sc.add( "}" );
sc.add( "Counter innerCount = new Counter( counter.getDepth() + 1 );" );
sc.add( "while ( it.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( toClass.getName() + " value = (" + toClass.getName() + ") it.next();" );
sc.add( "Element el;" );
sc.add( "if ( elIt != null && elIt.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "el = (Element) elIt.next();" );
sc.add( "if ( ! elIt.hasNext() )" );
sc.add( "{" );
sc.addIndented( "elIt = null;" );
sc.add( "}" );
sc.unindent();
sc.add( "}" );
sc.add( "else" );
sc.add( "{" );
sc.indent();
sc.add( "el = factory.element( childTag, parent.getNamespace() );" );
sc.add( "insertAtPreferredLocation( parent, el, innerCount );" );
sc.unindent();
sc.add( "}" );
sc.add( "update" + toClass.getName() + "( value, childTag, innerCount, el );" );
sc.add( "innerCount.increaseCount();" );
sc.unindent();
sc.add( "}" );
sc.add( "if ( elIt != null )" );
sc.add( "{" );
sc.indent();
sc.add( "while ( elIt.hasNext() )" );
sc.add( "{" );
sc.indent();
sc.add( "elIt.next();" );
sc.add( "elIt.remove();" );
sc.unindent();
sc.add( "}" );
sc.unindent();
sc.add( "}" );
jClass.addMethod( toReturn );
}
}