diff --git a/modello-core/pom.xml b/modello-core/pom.xml index 366d006dc..f7dbf005f 100644 --- a/modello-core/pom.xml +++ b/modello-core/pom.xml @@ -3,7 +3,7 @@ modello org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-core/src/main/java/org/codehaus/modello/ModelloParameterConstants.java b/modello-core/src/main/java/org/codehaus/modello/ModelloParameterConstants.java index 82dfb0137..0dbf2c934 100644 --- a/modello-core/src/main/java/org/codehaus/modello/ModelloParameterConstants.java +++ b/modello-core/src/main/java/org/codehaus/modello/ModelloParameterConstants.java @@ -65,6 +65,11 @@ public class ModelloParameterConstants */ public static final String DOM_AS_XPP3 = "modello.dom.xpp3"; + /** + * @since 1.10 + */ + public static final String EXTENDED_CLASSNAME_SUFFIX = "modello.xpp3.extended.suffix"; + private ModelloParameterConstants() { } diff --git a/modello-maven-plugin/pom.xml b/modello-maven-plugin/pom.xml index 7907b3d17..98a96abf1 100644 --- a/modello-maven-plugin/pom.xml +++ b/modello-maven-plugin/pom.xml @@ -3,7 +3,7 @@ modello org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedWriterMojo.java b/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedWriterMojo.java new file mode 100644 index 000000000..39f983411 --- /dev/null +++ b/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedWriterMojo.java @@ -0,0 +1,64 @@ +package org.codehaus.modello.maven; + +/* + * Copyright (c) 2004, Codehaus.org + * + * 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.Properties; + +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.codehaus.modello.ModelloParameterConstants; + +/** + * Creates an XPP3 extended writer from the model. An extended writer renders the content with comments about the + * line/column from which the data was read if the model supports this. + * + * @author Hervé Boutemy + * @since 1.10 + */ +@Mojo( name = "xpp3-extended-writer", defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true ) +public class ModelloXpp3ExtendedWriterMojo + extends ModelloXpp3WriterMojo +{ + /** + * The class name suffix for the generated writer. + */ + @Parameter( defaultValue = "Ex" ) + private String extendedClassnameSuffix; + + @Override + protected String getGeneratorType() + { + return "xpp3-extended-writer"; + } + + protected void customizeParameters( Properties parameters ) + { + super.customizeParameters( parameters ); + + if ( extendedClassnameSuffix != null ) + { + parameters.put( ModelloParameterConstants.EXTENDED_CLASSNAME_SUFFIX, extendedClassnameSuffix ); + } + } +} diff --git a/modello-maven-plugin/src/site/apt/index.apt b/modello-maven-plugin/src/site/apt/index.apt index 534451b75..f7004f6e5 100644 --- a/modello-maven-plugin/src/site/apt/index.apt +++ b/modello-maven-plugin/src/site/apt/index.apt @@ -25,7 +25,10 @@ Modello Maven Plugin * {{{./xpp3-reader-mojo.html}modello:xpp3-reader}} Generates an XML Pull Parser reader from the Modello model. * {{{./xpp3-extended-reader-mojo.html}modello:xpp3-extended-reader}} Generates an XML Pull Parser reader from the - Modello model that records line/column number metadata in the parsed model. + Modello model that records line/column number metadata and eventual source in the parsed model. + + * {{{./xpp3-extended-writer-mojo.html}modello:xpp3-extended-writer}} Generates an XML Pull Parser writer from the + Modello model that writes line/column number and source info as comments on each line. * {{{./dom4j-writer-mojo.html}modello:dom4j-writer}} Generates a DOM4J writer from the Modello model. diff --git a/modello-plugins/modello-plugin-converters/pom.xml b/modello-plugins/modello-plugin-converters/pom.xml index 1a04d580c..33a2684a3 100644 --- a/modello-plugins/modello-plugin-converters/pom.xml +++ b/modello-plugins/modello-plugin-converters/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-dom4j/pom.xml b/modello-plugins/modello-plugin-dom4j/pom.xml index b7cfcf3a1..8dca28bd6 100644 --- a/modello-plugins/modello-plugin-dom4j/pom.xml +++ b/modello-plugins/modello-plugin-dom4j/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-jackson/pom.xml b/modello-plugins/modello-plugin-jackson/pom.xml index 67a9fe6b7..12ad27bfd 100644 --- a/modello-plugins/modello-plugin-jackson/pom.xml +++ b/modello-plugins/modello-plugin-jackson/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-java/pom.xml b/modello-plugins/modello-plugin-java/pom.xml index 86398185f..dc784fd4f 100644 --- a/modello-plugins/modello-plugin-java/pom.xml +++ b/modello-plugins/modello-plugin-java/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/AbstractJavaModelloGenerator.java b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/AbstractJavaModelloGenerator.java index 9bf4f6532..5ab6389ac 100644 --- a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/AbstractJavaModelloGenerator.java +++ b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/AbstractJavaModelloGenerator.java @@ -158,7 +158,7 @@ protected void addModelImports( JClass jClass, BaseElement baseElem ) } } - private void addModelImport( JClass jClass, ModelType modelType, String basePackageName ) + protected void addModelImport( JClass jClass, ModelType modelType, String basePackageName ) { String packageName = modelType.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); diff --git a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/JavaModelloGenerator.java b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/JavaModelloGenerator.java index 7cadd74a2..1bd8c8e38 100644 --- a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/JavaModelloGenerator.java +++ b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/JavaModelloGenerator.java @@ -920,7 +920,7 @@ private void generateLocationBean( JClass jClass, ModelClass locationClass, Mode } JType fieldType = new JMapType( "java.util.Map", new JType(locationClass.getName()), useJava5 ); - JType fieldImpl = new JMapType("java.util.LinkedHashMap", new JType(locationClass.getName()), useJava5); + JType fieldImpl = new JMapType( "java.util.LinkedHashMap", new JType( locationClass.getName() ), useJava5 ); // public Map getLocations() JMethod jMethod = new JMethod( "get" + capitalise( locationsField ), fieldType, null ); @@ -1044,6 +1044,15 @@ private void generateLocationBean( JClass jClass, ModelClass locationClass, Mode sc.add( "" ); sc.add( "return result;" ); jClass.addMethod( jMethod ); + + JClass stringFormatterClass = jClass.createInnerClass( "StringFormatter" ); + stringFormatterClass.getModifiers().setStatic( true ); + stringFormatterClass.getModifiers().setAbstract( true ); + + jMethod = new JMethod( "toString", new JType( "String" ), null ); + jMethod.getModifiers().setAbstract( true ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), "location" ) ); + stringFormatterClass.addMethod( jMethod ); } /** diff --git a/modello-plugins/modello-plugin-jdom/pom.xml b/modello-plugins/modello-plugin-jdom/pom.xml index dc49fd8b9..02784c450 100644 --- a/modello-plugins/modello-plugin-jdom/pom.xml +++ b/modello-plugins/modello-plugin-jdom/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-jsonschema/pom.xml b/modello-plugins/modello-plugin-jsonschema/pom.xml index f4f50c82b..04b57e167 100644 --- a/modello-plugins/modello-plugin-jsonschema/pom.xml +++ b/modello-plugins/modello-plugin-jsonschema/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-sax/pom.xml b/modello-plugins/modello-plugin-sax/pom.xml index 7ba03cc5d..ab313ee83 100644 --- a/modello-plugins/modello-plugin-sax/pom.xml +++ b/modello-plugins/modello-plugin-sax/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-snakeyaml/pom.xml b/modello-plugins/modello-plugin-snakeyaml/pom.xml index b1adf82a2..d4317c14c 100644 --- a/modello-plugins/modello-plugin-snakeyaml/pom.xml +++ b/modello-plugins/modello-plugin-snakeyaml/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-stax/pom.xml b/modello-plugins/modello-plugin-stax/pom.xml index 430060038..7f1022d55 100644 --- a/modello-plugins/modello-plugin-stax/pom.xml +++ b/modello-plugins/modello-plugin-stax/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-xdoc/pom.xml b/modello-plugins/modello-plugin-xdoc/pom.xml index 168fc0e2b..e8ada748f 100644 --- a/modello-plugins/modello-plugin-xdoc/pom.xml +++ b/modello-plugins/modello-plugin-xdoc/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-xml/pom.xml b/modello-plugins/modello-plugin-xml/pom.xml index 508475ef7..ca458c0b7 100644 --- a/modello-plugins/modello-plugin-xml/pom.xml +++ b/modello-plugins/modello-plugin-xml/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-xpp3/pom.xml b/modello-plugins/modello-plugin-xpp3/pom.xml index 0f5092d76..7347399f0 100644 --- a/modello-plugins/modello-plugin-xpp3/pom.xml +++ b/modello-plugins/modello-plugin-xpp3/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/AbstractXpp3Generator.java b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/AbstractXpp3Generator.java index 715a39350..f5112aab3 100644 --- a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/AbstractXpp3Generator.java +++ b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/AbstractXpp3Generator.java @@ -22,6 +22,11 @@ * SOFTWARE. */ +import java.util.Properties; + +import org.codehaus.modello.ModelloException; +import org.codehaus.modello.model.Model; +import org.codehaus.modello.model.ModelClass; import org.codehaus.modello.plugins.xml.AbstractXmlJavaGenerator; /** @@ -30,4 +35,36 @@ public abstract class AbstractXpp3Generator extends AbstractXmlJavaGenerator { + protected boolean requiresDomSupport; + + protected ModelClass locationTracker; + + protected ModelClass sourceTracker; + + protected boolean isLocationTracking() + { + return false; + } + + @Override + protected void initialize( Model model, Properties parameters ) + throws ModelloException + { + super.initialize( model, parameters ); + + requiresDomSupport = false; + locationTracker = sourceTracker = null; + + if ( isLocationTracking() ) + { + locationTracker = model.getLocationTracker( getGeneratedVersion() ); + if ( locationTracker == null ) + { + throw new ModelloException( "No model class has been marked as location tracker" + + " via the attribute locationTracker=\"locations\", cannot generate extended reader." ); + } + + sourceTracker = model.getSourceTracker( getGeneratedVersion() ); + } + } } diff --git a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedWriterGenerator.java b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedWriterGenerator.java new file mode 100644 index 000000000..4dd3fc477 --- /dev/null +++ b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedWriterGenerator.java @@ -0,0 +1,149 @@ +package org.codehaus.modello.plugin.xpp3; + +/* + * Copyright (c) 2004, Codehaus.org + * + * 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 org.codehaus.modello.plugin.java.javasource.JClass; +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.JType; + +/** + * The generator for XPP3-based writers that support input location tracking. + * + * @author Hervé Boutemy + * @since 1.10 + */ +public class Xpp3ExtendedWriterGenerator + extends Xpp3WriterGenerator +{ + @Override + protected boolean isLocationTracking() + { + return true; + } + + @Override + protected void prepareLocationTracking( JClass jClass ) + { + String packageName = locationTracker.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); + + jClass.addImport( packageName + '.' + locationTracker.getName() + "Tracker" ); + addModelImport( jClass, locationTracker, null ); + + createLocationTrackingMethod( jClass ); + + if ( requiresDomSupport && domAsXpp3 ) + { + createXpp3DomToSerializerMethod( jClass ); + } + } + + private void createLocationTrackingMethod( JClass jClass ) + { + JMethod method = new JMethod( "writeLocationTracking" ); + method.getModifiers().makePrivate(); + + method.addParameter( new JParameter( new JType( locationTracker.getName() + "Tracker" ), "locationTracker" ) ); + method.addParameter( new JParameter( new JClass( "Object" ), "key" ) ); + method.addParameter( new JParameter( new JClass( "XmlSerializer" ), "serializer" ) ); + + method.addException( new JClass( "java.io.IOException" ) ); + + JSourceCode sc = method.getSourceCode(); + + sc.add( locationTracker.getName() + " location = ( locationTracker == null ) ? null : locationTracker.getLocation( key );" ); + sc.add( "if ( location != null )" ); + sc.add( "{" ); + sc.addIndented( "serializer.comment( toString( location ) );" ); + sc.add( "}" ); + + jClass.addMethod( method ); + + JField field = new JField( new JType( locationTracker.getName() + ".StringFormatter" ), "stringFormatter" ); + field.getModifiers().makeProtected(); + jClass.addField( field ); + + method = new JMethod( "setStringFormatter", null, null ); + method.addParameter( new JParameter( new JType( locationTracker.getName() + ".StringFormatter" ), "stringFormatter" ) ); + sc = method.getSourceCode(); + sc.add( "this.stringFormatter = stringFormatter;" ); + jClass.addMethod( method ); + + method = new JMethod( "toString", new JType( "String" ), null ); + method.getModifiers().makeProtected(); + + method.addParameter( new JParameter( new JType( locationTracker.getName() ), "location" ) ); + + sc = method.getSourceCode(); + sc.add( "if ( stringFormatter != null )" ); + sc.add( "{" ); + sc.addIndented( "return stringFormatter.toString( location );" ); + sc.add( "}" ); + sc.add( "return ' ' + " + ( ( sourceTracker == null ) ? "" : "location.getSource().toString() + ':' + " ) + + "location.getLineNumber() + ' ';" ); + + jClass.addMethod( method ); + } + + private void createXpp3DomToSerializerMethod( JClass jClass ) + { + JMethod method = new JMethod( "writeXpp3DomToSerializer" ); + method.getModifiers().makeProtected(); + + method.addParameter( new JParameter( new JClass( "Xpp3Dom" ), "dom" ) ); + method.addParameter( new JParameter( new JClass( "XmlSerializer" ), "serializer" ) ); + + method.addException( new JClass( "java.io.IOException" ) ); + + JSourceCode sc = method.getSourceCode(); + + sc.add( "serializer.startTag( NAMESPACE, dom.getName() );" ); + sc.add( "" ); + sc.add( "String[] attributeNames = dom.getAttributeNames();" ); + sc.add( "for ( String attributeName : attributeNames )" ); + sc.add( "{" ); + sc.addIndented( "serializer.attribute( NAMESPACE, attributeName, dom.getAttribute( attributeName ) );" ); + sc.add( "}" ); + sc.add( "for ( Xpp3Dom aChild : dom.getChildren() )" ); + sc.add( "{" ); + sc.addIndented( "writeXpp3DomToSerializer( aChild, serializer );" ); + sc.add( "}" ); + sc.add( "" ); + sc.add( "String value = dom.getValue();" ); + sc.add( "if ( value != null )" ); + sc.add( "{" ); + sc.addIndented( "serializer.text( value );" ); + sc.add( "}" ); + sc.add( "" ); + sc.add( "serializer.endTag( NAMESPACE, dom.getName() );" ); + sc.add( "" ); + sc.add( "if ( dom.getInputLocation() != null && dom.getChildCount() == 0 )" ); + sc.add( "{" ); + sc.addIndented( "serializer.comment( toString( (InputLocation) dom.getInputLocation() ) );" ); + sc.add( "}" ); + + jClass.addMethod( method ); + } +} diff --git a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ReaderGenerator.java b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ReaderGenerator.java index 6c2a78248..fd7bb34f6 100644 --- a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ReaderGenerator.java +++ b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ReaderGenerator.java @@ -61,51 +61,36 @@ public class Xpp3ReaderGenerator private static final String LOCATION_VAR = "_location"; - private ModelClass locationTracker; - private String locationField; - private ModelClass sourceTracker; - private String trackingArgs; - private boolean requiresDomSupport; - - protected boolean isLocationTracking() - { - return false; - } - - public void generate( Model model, Properties parameters ) + @Override + protected void initialize( Model model, Properties parameters ) throws ModelloException { - initialize( model, parameters ); + super.initialize( model, parameters ); - locationTracker = sourceTracker = null; trackingArgs = locationField = ""; - requiresDomSupport = false; if ( isLocationTracking() ) { - locationTracker = model.getLocationTracker( getGeneratedVersion() ); - if ( locationTracker == null ) - { - throw new ModelloException( "No model class has been marked as location tracker" - + " via the attribute locationTracker=\"locations\"" - + ", cannot generate extended reader." ); - } - locationField = ( (ModelClassMetadata) locationTracker.getMetadata( ModelClassMetadata.ID ) ).getLocationTracker(); - sourceTracker = model.getSourceTracker( getGeneratedVersion() ); - if ( sourceTracker != null ) { trackingArgs += ", " + SOURCE_PARAM; } } + } + + public void generate( Model model, Properties parameters ) + throws ModelloException + { + initialize( model, parameters ); + try { generateXpp3Reader(); @@ -453,6 +438,11 @@ private void generateXpp3Reader() if ( requiresDomSupport ) { writeBuildDomMethod( jClass ); + + if ( isLocationTracking() ) + { + writeBuildDomLocationTrackingMethod( jClass ); + } } // ---------------------------------------------------------------------- @@ -1080,9 +1070,14 @@ else if ( "Date".equals( type ) ) } else if ( "DOM".equals( type ) ) { - sc.add( objectName + "." + setterName + "( " + keyCapture + ( domAsXpp3 - ? "org.codehaus.plexus.util.xml.Xpp3DomBuilder.build" - : "buildDom" ) + "( parser, " + xmlFieldMetadata.isTrim() + " ) );" ); + String locationBuilderParam = ""; + if ( isLocationTracking() && domAsXpp3 ) + { + locationBuilderParam = ", new Xpp3DomBuilderInputLocationBuilder( " + LOCATION_VAR + " )"; + } + sc.add( objectName + "." + setterName + "( " + keyCapture + + ( domAsXpp3 ? "org.codehaus.plexus.util.xml.Xpp3DomBuilder.build" : "buildDom" ) + + "( parser, " + xmlFieldMetadata.isTrim() + locationBuilderParam + " ) );" ); requiresDomSupport = true; } @@ -1104,6 +1099,7 @@ private void writeBuildDomMethod( JClass jClass ) // no need, Xpp3DomBuilder provided by plexus-utils return; } + jClass.addField( new JField( new JClass( "org.w3c.dom.Document" ), "_doc_" ) ); JMethod method = new JMethod( "initDoc", null, null ); method.getModifiers().makePrivate(); @@ -1228,6 +1224,34 @@ private void writeBuildDomMethod( JClass jClass ) jClass.addMethod( method ); } + private void writeBuildDomLocationTrackingMethod( JClass jClass ) + { + if ( !domAsXpp3 ) + { + // no need, input location tracking available only for Xpp3 + return; + } + + JClass builderClass = jClass.createInnerClass( "Xpp3DomBuilderInputLocationBuilder" ); + builderClass.getModifiers().makePrivate(); + builderClass.getModifiers().setStatic( true ); + builderClass.addInterface( "org.codehaus.plexus.util.xml.Xpp3DomBuilder.InputLocationBuilder" ); + + JField field = new JField( new JType( locationTracker.getName() ), "rootLocation" ); + field.getModifiers().setFinal( true ); + builderClass.addField( field ); + + JConstructor constructor = new JConstructor( builderClass ); + constructor.addParameter( new JParameter( new JType( locationTracker.getName() ), "rootLocation" ) ); + constructor.getSourceCode().add( "this.rootLocation = rootLocation;" ); + builderClass.addConstructor( constructor ); + + JMethod method = new JMethod( "toInputLocation", new JType( "Object" ), null ); + method.addParameter( new JParameter( new JType( "XmlPullParser" ), "parser" ) ); + method.getSourceCode().add( "return " + buildNewLocation( "rootLocation.getSource()" ) + ";" ); + builderClass.addMethod( method ); + } + private void writeHelpers( JClass jClass ) { jClass.addMethod(getTrimmedValueMethod()); @@ -1624,11 +1648,14 @@ private void writeNewLocation( String trackerVariable, JSourceCode sc ) return; } - String constr = "new " + locationTracker.getName() + "( parser.getLineNumber(), parser.getColumnNumber()"; - constr += ( sourceTracker != null ) ? ", " + SOURCE_PARAM : ""; - constr += " )"; + sc.add( ( ( trackerVariable != null ) ? trackerVariable : LOCATION_VAR ) + " = " + + buildNewLocation( SOURCE_PARAM ) + ";" ); + } - sc.add( ( ( trackerVariable != null ) ? trackerVariable : LOCATION_VAR ) + " = " + constr + ";" ); + private String buildNewLocation( String source ) + { + return "new " + locationTracker.getName() + "( parser.getLineNumber(), parser.getColumnNumber()" + + ( ( sourceTracker != null ) ? ", " + source : "" ) + " )"; } private void writeSetLocation( String key, String objectName, String trackerVariable, JSourceCode sc ) diff --git a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3WriterGenerator.java b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3WriterGenerator.java index 0db38970e..534caa606 100644 --- a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3WriterGenerator.java +++ b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3WriterGenerator.java @@ -23,6 +23,7 @@ */ import org.codehaus.modello.ModelloException; +import org.codehaus.modello.ModelloParameterConstants; import org.codehaus.modello.model.Model; import org.codehaus.modello.model.ModelAssociation; import org.codehaus.modello.model.ModelClass; @@ -52,15 +53,39 @@ public class Xpp3WriterGenerator extends AbstractXpp3Generator { - private boolean requiresDomSupport; + private String extendedClassnameSuffix; + + protected void prepareLocationTracking( JClass jClass ) + { + // NO OP + } + + protected void writeLocationTracking( JSourceCode sc, String name, String key ) + { + if ( isLocationTracking() ) + { + sc.add( "writeLocationTracking( " + name + ", " + key + ", serializer );" ); + } + } + + @Override + protected void initialize( Model model, Properties parameters ) + throws ModelloException + { + super.initialize( model, parameters ); + + extendedClassnameSuffix = "Ex"; + if ( isLocationTracking() ) + { + extendedClassnameSuffix = parameters.getProperty( ModelloParameterConstants.EXTENDED_CLASSNAME_SUFFIX ); + } + } public void generate( Model model, Properties parameters ) throws ModelloException { initialize( model, parameters ); - requiresDomSupport = false; - try { generateXpp3Writer(); @@ -79,7 +104,7 @@ private void generateXpp3Writer() String packageName = objectModel.getDefaultPackageName( isPackageWithVersion(), getGeneratedVersion() ) + ".io.xpp3"; - String marshallerName = getFileName( "Xpp3Writer" ); + String marshallerName = getFileName( "Xpp3Writer" + ( isLocationTracking() ? extendedClassnameSuffix : "" ) ); JSourceWriter sourceWriter = newJSourceWriter( packageName, marshallerName ); @@ -184,6 +209,11 @@ private void generateXpp3Writer() writeAllClasses( objectModel, jClass ); + if ( isLocationTracking() ) + { + prepareLocationTracking( jClass ); + } + if ( requiresDomSupport ) { createWriteDomMethod( jClass ); @@ -353,6 +383,8 @@ private void writeClass( ModelClass modelClass, JClass jClass ) if ( ModelDefault.LIST.equals( type ) || ModelDefault.SET.equals( type ) ) { + boolean isList = ModelDefault.LIST.equals( type ); + sc.add( getValueChecker( type, value, association ) ); sc.add( "{" ); @@ -363,6 +395,15 @@ private void writeClass( ModelClass modelClass, JClass jClass ) sc.add( "serializer.startTag( NAMESPACE, " + "\"" + fieldTagName + "\" );" ); } + if ( isLocationTracking() && !isClassInModel( association.getTo(), modelClass.getModel() ) ) + { + sc.add( locationTracker.getName() + " location = " + uncapClassName + ".getLocation( \"" + fieldTagName + "\" );" ); + if ( isList ) + { + sc.add( "int n = 0;" ); + } + } + sc.add( "for ( Iterator iter = " + value + ".iterator(); iter.hasNext(); )" ); sc.add( "{" ); @@ -376,12 +417,14 @@ private void writeClass( ModelClass modelClass, JClass jClass ) } else { - sc.add( toType + " " + singular( uncapitalise( field.getName() ) ) + " = (" + toType - + ") iter.next();" ); + String variable = singular( uncapitalise( field.getName() ) ); - sc.add( "serializer.startTag( NAMESPACE, " + "\"" + valuesTagName + "\" ).text( " - + singular( uncapitalise( field.getName() ) ) + " ).endTag( NAMESPACE, " + "\"" - + valuesTagName + "\" );" ); + sc.add( toType + " " + variable + " = (" + toType + ") iter.next();" ); + + sc.add( "serializer.startTag( NAMESPACE, \"" + valuesTagName + "\" ).text( " + variable + + " ).endTag( NAMESPACE, \"" + valuesTagName + "\" );" ); + + writeLocationTracking( sc, "location", isList ? "Integer.valueOf( n++ )" : variable ); } sc.unindent(); @@ -389,7 +432,7 @@ private void writeClass( ModelClass modelClass, JClass jClass ) if ( wrappedItems ) { - sc.add( "serializer.endTag( NAMESPACE, " + "\"" + fieldTagName + "\" );" ); + sc.add( "serializer.endTag( NAMESPACE, \"" + fieldTagName + "\" );" ); } sc.unindent(); @@ -406,7 +449,12 @@ private void writeClass( ModelClass modelClass, JClass jClass ) if ( wrappedItems ) { - sc.add( "serializer.startTag( NAMESPACE, " + "\"" + fieldTagName + "\" );" ); + sc.add( "serializer.startTag( NAMESPACE, \"" + fieldTagName + "\" );" ); + } + + if ( isLocationTracking() ) + { + sc.add( locationTracker.getName() + " location = " + uncapClassName + ".getLocation( \"" + fieldTagName + "\" );" ); } sc.add( "for ( Iterator iter = " + value + ".keySet().iterator(); iter.hasNext(); )" ); @@ -430,15 +478,17 @@ private void writeClass( ModelClass modelClass, JClass jClass ) else { sc.add( - "serializer.startTag( NAMESPACE, \"\" + key + \"\" ).text( value ).endTag( NAMESPACE, \"\" + key + \"\" );" ); + "serializer.startTag( NAMESPACE, key ).text( value ).endTag( NAMESPACE, key );" ); } + writeLocationTracking( sc, "location", "key" ); + sc.unindent(); sc.add( "}" ); if ( wrappedItems ) { - sc.add( "serializer.endTag( NAMESPACE, " + "\"" + fieldTagName + "\" );" ); + sc.add( "serializer.endTag( NAMESPACE, \"" + fieldTagName + "\" );" ); } sc.unindent(); @@ -456,8 +506,15 @@ private void writeClass( ModelClass modelClass, JClass jClass ) if ( domAsXpp3 ) { jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); - - sc.addIndented( "((Xpp3Dom) " + value + ").writeToSerializer( NAMESPACE, serializer );" ); + + if ( isLocationTracking() ) + { + sc.addIndented( "writeXpp3DomToSerializer( (Xpp3Dom) " + value + ", serializer );" ); + } + else + { + sc.addIndented( "((Xpp3Dom) " + value + ").writeToSerializer( NAMESPACE, serializer );" ); + } } else { @@ -471,6 +528,9 @@ private void writeClass( ModelClass modelClass, JClass jClass ) sc.addIndented( "serializer.startTag( NAMESPACE, " + "\"" + fieldTagName + "\" ).text( " + getValue( field.getType(), value, xmlFieldMetadata ) + " ).endTag( NAMESPACE, " + "\"" + fieldTagName + "\" );" ); + sc.indent(); + writeLocationTracking( sc, uncapClassName, '"' + fieldTagName + '"' ); + sc.unindent(); } sc.add( "}" ); } diff --git a/modello-plugins/modello-plugin-xpp3/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-xpp3/src/main/resources/META-INF/plexus/components.xml index 1d0d75854..24ad84b57 100644 --- a/modello-plugins/modello-plugin-xpp3/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-xpp3/src/main/resources/META-INF/plexus/components.xml @@ -18,5 +18,11 @@ org.codehaus.modello.plugin.xpp3.Xpp3WriterGenerator per-lookup + + org.codehaus.modello.plugin.ModelloGenerator + xpp3-extended-writer + org.codehaus.modello.plugin.xpp3.Xpp3ExtendedWriterGenerator + per-lookup + diff --git a/modello-plugins/modello-plugin-xpp3/src/site/xdoc/index.xml b/modello-plugins/modello-plugin-xpp3/src/site/xdoc/index.xml index bef5f7243..dea9fa623 100644 --- a/modello-plugins/modello-plugin-xpp3/src/site/xdoc/index.xml +++ b/modello-plugins/modello-plugin-xpp3/src/site/xdoc/index.xml @@ -61,6 +61,13 @@

If source tracking is enabled in addition to location tracking, the public methods have an extra parameter which is the source tracker instance.

+ + +

xpp3-extended-writer generator creates + my.model.package.io.xpp3.ModelNameXpp3WriterEx class with same public methods + as xpp3-writer, but it adds location tracking information on each written field as comments. +

+
diff --git a/modello-plugins/modello-plugin-xsd/pom.xml b/modello-plugins/modello-plugin-xsd/pom.xml index 76f35e547..ada209169 100644 --- a/modello-plugins/modello-plugin-xsd/pom.xml +++ b/modello-plugins/modello-plugin-xsd/pom.xml @@ -3,7 +3,7 @@ modello-plugins org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-plugins/pom.xml b/modello-plugins/pom.xml index 87ec8673e..dd5f0d196 100644 --- a/modello-plugins/pom.xml +++ b/modello-plugins/pom.xml @@ -3,7 +3,7 @@ modello org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/modello-test/pom.xml b/modello-test/pom.xml index f29ddc5ff..5200e5971 100644 --- a/modello-test/pom.xml +++ b/modello-test/pom.xml @@ -3,7 +3,7 @@ modello org.codehaus.modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 9051808f4..f59f18805 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.codehaus.modello modello - 1.9.2-SNAPSHOT + 1.10.0-SNAPSHOT pom Modello @@ -355,7 +355,7 @@ org.codehaus.plexus plexus-utils - 3.0.24 + 3.2.0 org.codehaus.plexus