From 2c551be69467b1c491b6751f75344fd6cfd7411d Mon Sep 17 00:00:00 2001 From: bentmann Date: Fri, 16 Apr 2010 22:47:30 +0000 Subject: [PATCH 01/10] [MODELLO-240] Provide support to track line/column number of source elements o Created feature branch --- .../org/codehaus/modello/model/Model.java | 58 +++ .../plugin/model/ModelClassMetadata.java | 25 + .../plugin/model/ModelMetadataPlugin.java | 8 + .../java/AbstractJavaModelloGenerator.java | 60 ++- .../plugin/java/JavaModelloGenerator.java | 445 +++++++++++++++--- .../plugin/java/javasource/JClass.java | 5 + .../plugin/java/javasource/JModifiers.java | 10 + .../plugin/xpp3/Xpp3ReaderGenerator.java | 288 +++++++++--- .../resources/META-INF/plexus/components.xml | 5 + pom.xml | 2 +- src/main/mdo/modello.mdo | 34 +- 11 files changed, 786 insertions(+), 154 deletions(-) diff --git a/modello-core/src/main/java/org/codehaus/modello/model/Model.java b/modello-core/src/main/java/org/codehaus/modello/model/Model.java index 7d6f1a54a..db10d2fcb 100644 --- a/modello-core/src/main/java/org/codehaus/modello/model/Model.java +++ b/modello-core/src/main/java/org/codehaus/modello/model/Model.java @@ -25,6 +25,7 @@ import org.codehaus.modello.ModelloRuntimeException; import org.codehaus.modello.metadata.ModelMetadata; import org.codehaus.modello.plugin.model.ModelClassMetadata; +import org.codehaus.plexus.util.StringUtils; import java.util.ArrayList; import java.util.HashMap; @@ -404,4 +405,61 @@ public void initialize() public void validateElement() { } + + public ModelClass getLocationTracker( Version version ) + { + List modelClasses = getClasses( version ); + + ModelClass locationTracker = null; + + for ( ModelClass modelClass : modelClasses ) + { + ModelClassMetadata metadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); + + if ( metadata != null && StringUtils.isNotEmpty( metadata.getLocationTracker() ) ) + { + if ( locationTracker == null ) + { + locationTracker = modelClass; + } + else + { + throw new ModelloRuntimeException( "There are multiple location tracker classes (" + + locationTracker.getName() + " vs. " + modelClass.getName() + ") for this version " + version + + "." ); + } + } + } + + return locationTracker; + } + + public ModelClass getSourceTracker( Version version ) + { + List modelClasses = getClasses( version ); + + ModelClass sourceTracker = null; + + for ( ModelClass modelClass : modelClasses ) + { + ModelClassMetadata metadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); + + if ( metadata != null && StringUtils.isNotEmpty( metadata.getSourceTracker() ) ) + { + if ( sourceTracker == null ) + { + sourceTracker = modelClass; + } + else + { + throw new ModelloRuntimeException( "There are multiple source tracker classes (" + + sourceTracker.getName() + " vs. " + modelClass.getName() + ") for this version " + version + + "." ); + } + } + } + + return sourceTracker; + } + } diff --git a/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelClassMetadata.java b/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelClassMetadata.java index 3e4c2c4bb..b1532445c 100644 --- a/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelClassMetadata.java +++ b/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelClassMetadata.java @@ -35,6 +35,10 @@ public class ModelClassMetadata private boolean rootElement = false; + private String locationTracker; + + private String sourceTracker; + public boolean isRootElement() { return rootElement; @@ -44,4 +48,25 @@ public void setRootElement( boolean rootElement ) { this.rootElement = rootElement; } + + public String getLocationTracker() + { + return locationTracker; + } + + public void setLocationTracker( String locationTracker ) + { + this.locationTracker = locationTracker; + } + + public String getSourceTracker() + { + return sourceTracker; + } + + public void setSourceTracker( String sourceTracker ) + { + this.sourceTracker = sourceTracker; + } + } diff --git a/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelMetadataPlugin.java b/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelMetadataPlugin.java index 3385b0863..8ba22a179 100644 --- a/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelMetadataPlugin.java +++ b/modello-core/src/main/java/org/codehaus/modello/plugin/model/ModelMetadataPlugin.java @@ -47,6 +47,10 @@ public class ModelMetadataPlugin { public static final String ROOT_ELEMENT = "rootElement"; + public static final String LOCATION_TRACKER = "locationTracker"; + + public static final String SOURCE_TRACKER = "sourceTracker"; + // ---------------------------------------------------------------------- // Map to Metadata // ---------------------------------------------------------------------- @@ -62,6 +66,10 @@ public ClassMetadata getClassMetadata( ModelClass clazz, Map dat metadata.setRootElement( getBoolean( data, ROOT_ELEMENT, false ) ); + metadata.setLocationTracker( getString( data, LOCATION_TRACKER ) ); + + metadata.setSourceTracker( getString( data, SOURCE_TRACKER ) ); + return metadata; } 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 393577df4..913b44390 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 @@ -44,6 +44,7 @@ import org.codehaus.modello.model.ModelDefault; import org.codehaus.modello.model.ModelField; import org.codehaus.modello.model.ModelInterface; +import org.codehaus.modello.model.ModelType; import org.codehaus.modello.plugin.AbstractModelloGenerator; import org.codehaus.modello.plugin.java.javasource.JClass; import org.codehaus.modello.plugin.java.javasource.JComment; @@ -53,6 +54,7 @@ import org.codehaus.modello.plugin.java.metadata.JavaClassMetadata; import org.codehaus.modello.plugin.java.metadata.JavaFieldMetadata; import org.codehaus.modello.plugin.java.metadata.JavaModelMetadata; +import org.codehaus.modello.plugin.model.ModelClassMetadata; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.WriterFactory; @@ -136,44 +138,31 @@ protected void addModelImports( JClass jClass, BaseElement baseElem ) throws ModelloException { String basePackageName = null; - if ( baseElem != null ) + if ( baseElem instanceof ModelType ) { - if ( baseElem instanceof ModelInterface ) - { - basePackageName = - ( (ModelInterface) baseElem ).getPackageName( isPackageWithVersion(), getGeneratedVersion() ); - } - else if ( baseElem instanceof ModelClass ) - { - basePackageName = - ( (ModelClass) baseElem ).getPackageName( isPackageWithVersion(), getGeneratedVersion() ); - } + basePackageName = ( (ModelType) baseElem ).getPackageName( isPackageWithVersion(), getGeneratedVersion() ); } // import interfaces for ( ModelInterface modelInterface : getModel().getInterfaces( getGeneratedVersion() ) ) { - String packageName = modelInterface.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); - - if ( packageName.equals( basePackageName ) ) - { - continue; - } - - jClass.addImport( packageName + '.' + modelInterface.getName() ); + addModelImport( jClass, modelInterface, basePackageName ); } // import classes for ( ModelClass modelClass : getClasses( getModel() ) ) { - String packageName = modelClass.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); + addModelImport( jClass, modelClass, basePackageName ); + } + } - if ( packageName.equals( basePackageName ) ) - { - continue; - } + private void addModelImport( JClass jClass, ModelType modelType, String basePackageName ) + { + String packageName = modelType.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); - jClass.addImport( packageName + '.' + modelClass.getName() ); + if ( !packageName.equals( basePackageName ) ) + { + jClass.addImport( packageName + '.' + modelType.getName() ); } } @@ -276,9 +265,28 @@ protected List getClasses( Model model ) } protected boolean isRelevant( ModelClass modelClass ) + { + return isJavaEnabled( modelClass ) && !isTrackingSupport( modelClass ); + } + + protected boolean isJavaEnabled( ModelClass modelClass ) { JavaClassMetadata javaClassMetadata = (JavaClassMetadata) modelClass.getMetadata( JavaClassMetadata.ID ); - return javaClassMetadata != null && javaClassMetadata.isEnabled(); + return javaClassMetadata.isEnabled(); + } + + protected boolean isTrackingSupport( ModelClass modelClass ) + { + ModelClassMetadata modelClassMetadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); + if ( StringUtils.isNotEmpty( modelClassMetadata.getLocationTracker() ) ) + { + return true; + } + if ( StringUtils.isNotEmpty( modelClassMetadata.getSourceTracker() ) ) + { + return true; + } + return false; } } 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 05034de5a..e59de2781 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 @@ -47,6 +47,7 @@ import org.codehaus.modello.plugin.java.javasource.JField; import org.codehaus.modello.plugin.java.javasource.JInterface; import org.codehaus.modello.plugin.java.javasource.JMethod; +import org.codehaus.modello.plugin.java.javasource.JMethodSignature; import org.codehaus.modello.plugin.java.javasource.JParameter; import org.codehaus.modello.plugin.java.javasource.JSourceCode; import org.codehaus.modello.plugin.java.javasource.JSourceWriter; @@ -89,66 +90,20 @@ private void generateJava() { Model objectModel = getModel(); + ModelClass locationTrackerClass = objectModel.getLocationTracker( getGeneratedVersion() ); + ModelClass sourceTrackerClass = objectModel.getSourceTracker( getGeneratedVersion() ); + // ---------------------------------------------------------------------- // Generate the interfaces. // ---------------------------------------------------------------------- for ( ModelInterface modelInterface : objectModel.getInterfaces( getGeneratedVersion() ) ) { - String packageName = modelInterface.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); - - JSourceWriter sourceWriter = newJSourceWriter( packageName, modelInterface.getName() ); - - JInterface jInterface = new JInterface( packageName + '.' + modelInterface.getName() ); - - initHeader( jInterface ); - - suppressAllWarnings( objectModel, jInterface ); - - if ( modelInterface.getSuperInterface() != null ) - { - // check if we need an import: if it is a generated superInterface in another package - try - { - ModelInterface superInterface = - objectModel.getInterface( modelInterface.getSuperInterface(), getGeneratedVersion() ); - String superPackageName = - superInterface.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); - - if ( !packageName.equals( superPackageName ) ) - { - jInterface.addImport( superPackageName + '.' + superInterface.getName() ); - } - } - catch ( ModelloRuntimeException mre ) - { - // no problem if the interface does not exist in the model, it can be in the jdk - } - - jInterface.addInterface( modelInterface.getSuperInterface() ); - } - - if ( modelInterface.getCodeSegments( getGeneratedVersion() ) != null ) - { - for ( CodeSegment codeSegment : modelInterface.getCodeSegments( getGeneratedVersion() ) ) - { - jInterface.addSourceCode( codeSegment.getCode() ); - } - } - - if ( useJava5 && !modelInterface.getAnnotations().isEmpty() ) - { - for ( String annotation : modelInterface.getAnnotations() ) - { - jInterface.appendAnnotation( annotation ); - } - } - - jInterface.print( sourceWriter ); - - sourceWriter.close(); + generateInterface( modelInterface ); } + String locationTrackerInterface = generateLocationTracker( objectModel, locationTrackerClass ); + // ---------------------------------------------------------------------- // Generate the classes. // ---------------------------------------------------------------------- @@ -182,9 +137,11 @@ private void generateJava() jClass.getModifiers().setAbstract( javaClassMetadata.isAbstract() ); + boolean superClassInModel = false; if ( modelClass.getSuperClass() != null ) { jClass.setSuperClass( modelClass.getSuperClass() ); + superClassInModel = isClassInModel( modelClass.getSuperClass(), objectModel ); } for ( String implementedInterface : modelClass.getInterfaces() ) @@ -245,7 +202,8 @@ private void generateJava() jClass.addMethod( toString ); } - JMethod[] cloneMethods = generateClone( modelClass ); + boolean cloneLocations = !superClassInModel && modelClass != sourceTrackerClass; + JMethod[] cloneMethods = generateClone( modelClass, cloneLocations ? locationTrackerClass : null ); if ( cloneMethods.length > 0 ) { jClass.addInterface( Cloneable.class.getName() ); @@ -260,15 +218,33 @@ private void generateJava() } } - ModelClassMetadata metadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); + ModelClassMetadata modelClassMetadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); + + if ( modelClassMetadata != null ) + { + if ( modelClassMetadata.isRootElement() ) + { + ModelField modelEncoding = new ModelField( modelClass, "modelEncoding" ); + modelEncoding.setType( "String" ); + modelEncoding.setDefaultValue( "UTF-8" ); + modelEncoding.addMetadata( new JavaFieldMetadata() ); + createField( jClass, modelEncoding ); + } + } + + if ( modelClass == locationTrackerClass ) + { + jClass.addInterface( locationTrackerInterface ); + + generateLocationBean( jClass, modelClass, sourceTrackerClass ); - if ( ( metadata != null ) && metadata.isRootElement() ) + generateLocationTracking( jClass, modelClass, locationTrackerClass ); + } + else if ( locationTrackerClass != null && modelClass != sourceTrackerClass && !superClassInModel) { - ModelField modelEncoding = new ModelField( modelClass, "modelEncoding" ); - modelEncoding.setType( "String" ); - modelEncoding.setDefaultValue( "UTF-8" ); - modelEncoding.addMetadata( new JavaFieldMetadata() ); - createField( jClass, modelEncoding ); + jClass.addInterface( locationTrackerInterface ); + + generateLocationTracking( jClass, modelClass, locationTrackerClass ); } jClass.print( sourceWriter ); @@ -277,6 +253,64 @@ private void generateJava() } } + private void generateInterface( ModelInterface modelInterface ) + throws ModelloException, IOException + { + Model objectModel = modelInterface.getModel(); + + String packageName = modelInterface.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); + + JSourceWriter sourceWriter = newJSourceWriter( packageName, modelInterface.getName() ); + + JInterface jInterface = new JInterface( packageName + '.' + modelInterface.getName() ); + + initHeader( jInterface ); + + suppressAllWarnings( objectModel, jInterface ); + + if ( modelInterface.getSuperInterface() != null ) + { + // check if we need an import: if it is a generated superInterface in another package + try + { + ModelInterface superInterface = + objectModel.getInterface( modelInterface.getSuperInterface(), getGeneratedVersion() ); + String superPackageName = superInterface.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); + + if ( !packageName.equals( superPackageName ) ) + { + jInterface.addImport( superPackageName + '.' + superInterface.getName() ); + } + } + catch ( ModelloRuntimeException mre ) + { + // no problem if the interface does not exist in the model, it can be in the jdk + } + + jInterface.addInterface( modelInterface.getSuperInterface() ); + } + + if ( modelInterface.getCodeSegments( getGeneratedVersion() ) != null ) + { + for ( CodeSegment codeSegment : modelInterface.getCodeSegments( getGeneratedVersion() ) ) + { + jInterface.addSourceCode( codeSegment.getCode() ); + } + } + + if ( useJava5 && !modelInterface.getAnnotations().isEmpty() ) + { + for ( String annotation : modelInterface.getAnnotations() ) + { + jInterface.appendAnnotation( annotation ); + } + } + + jInterface.print( sourceWriter ); + + sourceWriter.close(); + } + private JMethod generateEquals( ModelClass modelClass ) { JMethod equals = new JMethod( "equals", JType.BOOLEAN, null ); @@ -421,7 +455,7 @@ private JMethod generateHashCode( ModelClass modelClass ) return hashCode; } - private JMethod[] generateClone( ModelClass modelClass ) + private JMethod[] generateClone( ModelClass modelClass, ModelClass locationClass ) throws ModelloException { String cloneModeClass = getCloneMode( modelClass ); @@ -555,6 +589,19 @@ else if ( isMap( modelField.getType() ) ) } } + if ( locationClass != null ) + { + String locationField = + ( (ModelClassMetadata) locationClass.getMetadata( ModelClassMetadata.ID ) ).getLocationTracker(); + sc.add( "if ( copy." + locationField + " != null )" ); + sc.add( "{" ); + sc.indent(); + sc.add( "copy." + locationField + " = new java.util.LinkedHashMap" + "( copy." + locationField + " );" ); + sc.unindent(); + sc.add( "}" ); + sc.add( "" ); + } + String cloneHook = getCloneHook( modelClass ); if ( StringUtils.isNotEmpty( cloneHook ) && !"false".equalsIgnoreCase( cloneHook ) ) @@ -652,6 +699,282 @@ private String getCloneHook( ModelClass modelClass ) return javaClassMetadata.getCloneHook(); } + private String generateLocationTracker( Model objectModel, ModelClass locationClass ) + throws ModelloException, IOException + { + if ( locationClass == null ) + { + return null; + } + + String locationField = + ( (ModelClassMetadata) locationClass.getMetadata( ModelClassMetadata.ID ) ).getLocationTracker(); + + String propertyName = capitalise( singular( locationField ) ); + + String interfaceName = propertyName + "Tracker"; + + String packageName = locationClass.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); + + JSourceWriter sourceWriter = newJSourceWriter( packageName, interfaceName ); + + JInterface jInterface = new JInterface( packageName + '.' + interfaceName ); + + initHeader( jInterface ); + + suppressAllWarnings( objectModel, jInterface ); + + JMethodSignature jMethod = new JMethodSignature( "get" + propertyName, new JType( locationClass.getName() ) ); + jMethod.addParameter( new JParameter( new JType( "Object" ), "field" ) ); + jInterface.addMethod( jMethod ); + + jMethod = new JMethodSignature( "set" + propertyName, null ); + jMethod.addParameter( new JParameter( new JType( "Object" ), "field" ) ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), singular( locationField ) ) ); + jInterface.addMethod( jMethod ); + + jInterface.print( sourceWriter ); + + sourceWriter.close(); + + return jInterface.getName(); + } + + private void generateLocationTracking( JClass jClass, ModelClass modelClass, ModelClass locationClass ) + throws ModelloException + { + if ( locationClass == null ) + { + return; + } + + String superClass = modelClass.getSuperClass(); + if ( StringUtils.isNotEmpty( superClass ) && isClassInModel( superClass, getModel() ) ) + { + return; + } + + ModelClassMetadata metadata = (ModelClassMetadata) locationClass.getMetadata( ModelClassMetadata.ID ); + String locationField = metadata.getLocationTracker(); + + String fieldType = "java.util.Map" + ( useJava5 ? "" : "" ); + String fieldImpl = "java.util.LinkedHashMap" + ( useJava5 ? "" : "" ); + + // private java.util.Map locations; + JField jField = new JField( new JType( fieldType ), locationField ); + jClass.addField( jField ); + + JMethod jMethod; + JSourceCode sc; + + // public Location getLocation( Object key ) + jMethod = + new JMethod( "get" + capitalise( singular( locationField ) ), new JType( locationClass.getName() ), null ); + jMethod.addParameter( new JParameter( new JType( "Object" ), "key" ) ); + sc = jMethod.getSourceCode(); + sc.add( "return ( " + locationField + " != null ) ? " + locationField + ".get( key ) : null;" ); + jMethod.setComment( "" ); + jClass.addMethod( jMethod ); + + // public void setLocation( Object key, Location location ) + jMethod = new JMethod( "set" + capitalise( singular( locationField ) ) ); + jMethod.addParameter( new JParameter( new JType( "Object" ), "key" ) ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), singular( locationField ) ) ); + sc = jMethod.getSourceCode(); + sc.add( "if ( " + singular( locationField ) + " != null )" ); + sc.add( "{" ); + sc.indent(); + sc.add( "if ( this." + locationField + " == null )" ); + sc.add( "{" ); + sc.addIndented( "this." + locationField + " = new " + fieldImpl + "();" ); + sc.add( "}" ); + sc.add( "this." + locationField + ".put( key, " + singular( locationField ) + " );" ); + sc.unindent(); + sc.add( "}" ); + jMethod.setComment( "" ); + jClass.addMethod( jMethod ); + } + + private void generateLocationBean( JClass jClass, ModelClass locationClass, ModelClass sourceClass ) + throws ModelloException + { + jClass.getModifiers().setFinal( true ); + + String locationsField = + ( (ModelClassMetadata) locationClass.getMetadata( ModelClassMetadata.ID ) ).getLocationTracker(); + + JavaFieldMetadata readOnlyField = new JavaFieldMetadata(); + readOnlyField.setSetter( false ); + + // int lineNumber; + ModelField lineNumber = new ModelField( locationClass, "lineNumber" ); + lineNumber.setType( "int" ); + lineNumber.setDefaultValue( "-1" ); + lineNumber.addMetadata( readOnlyField ); + createField( jClass, lineNumber ); + + // int columnNumber; + ModelField columnNumber = new ModelField( locationClass, "columnNumber" ); + columnNumber.setType( "int" ); + columnNumber.setDefaultValue( "-1" ); + columnNumber.addMetadata( readOnlyField ); + createField( jClass, columnNumber ); + + // Source source; + ModelField source = null; + if ( sourceClass != null ) + { + ModelClassMetadata metadata = (ModelClassMetadata) sourceClass.getMetadata( ModelClassMetadata.ID ); + String sourceField = metadata.getSourceTracker(); + + source = new ModelField( locationClass, sourceField ); + source.setType( sourceClass.getName() ); + source.addMetadata( readOnlyField ); + createField( jClass, source ); + } + + // Location( int lineNumber, int columnNumber ); + JConstructor jConstructor = jClass.createConstructor(); + JSourceCode sc = jConstructor.getSourceCode(); + + jConstructor.addParameter( new JParameter( JType.INT, lineNumber.getName() ) ); + sc.add( "this." + lineNumber.getName() + " = " + lineNumber.getName() + ";" ); + + jConstructor.addParameter( new JParameter( JType.INT, columnNumber.getName() ) ); + sc.add( "this." + columnNumber.getName() + " = " + columnNumber.getName() + ";" ); + + // Location( int lineNumber, int columnNumber, Source source ); + if ( sourceClass != null ) + { + jConstructor = jClass.createConstructor( jConstructor.getParameters() ); + sc.copyInto( jConstructor.getSourceCode() ); + sc = jConstructor.getSourceCode(); + + jConstructor.addParameter( new JParameter( new JType( sourceClass.getName() ), source.getName() ) ); + sc.add( "this." + source.getName() + " = " + source.getName() + ";" ); + } + + String fieldType = "java.util.Map" + ( useJava5 ? "" : "" ); + String fieldImpl = "java.util.LinkedHashMap" + ( useJava5 ? "" : "" ); + + // public Map getLocations() + JMethod jMethod = new JMethod( "get" + capitalise( locationsField ), new JType( fieldType ), null ); + sc = jMethod.getSourceCode(); + sc.add( "return " + locationsField + ";" ); + jMethod.setComment( "" ); + jClass.addMethod( jMethod ); + + // public void setLocations( Map locations ) + jMethod = new JMethod( "set" + capitalise( locationsField ) ); + jMethod.addParameter( new JParameter( new JType( fieldType ), locationsField ) ); + sc = jMethod.getSourceCode(); + sc.add( "this." + locationsField + " = " + locationsField + ";" ); + jMethod.setComment( "" ); + jClass.addMethod( jMethod ); + + // public static Location merge( Location target, Location source, boolean sourceDominant ) + jMethod = new JMethod( "merge", new JType( locationClass.getName() ), null ); + jMethod.getModifiers().setStatic( true ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), "target" ) ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), "source" ) ); + jMethod.addParameter( new JParameter( JType.BOOLEAN, "sourceDominant" ) ); + sc = jMethod.getSourceCode(); + sc.add( "if ( source == null )" ); + sc.add( "{" ); + sc.addIndented( "return target;" ); + sc.add( "}" ); + sc.add( "else if ( target == null )" ); + sc.add( "{" ); + sc.addIndented( "return source;" ); + sc.add( "}" ); + sc.add( "" ); + sc.add( locationClass.getName() + " result =" ); + sc.add( " new " + locationClass.getName() + "( target.getLineNumber(), target.getColumnNumber()" + + ( sourceClass != null ? ", target.get" + capitalise( source.getName() ) + "()" : "" ) + " );" ); + sc.add( "" ); + sc.add( fieldType + " locations;" ); + sc.add( fieldType + " sourceLocations = source.get" + capitalise( locationsField ) + "();" ); + sc.add( fieldType + " targetLocations = target.get" + capitalise( locationsField ) + "();" ); + sc.add( "if ( sourceLocations == null )" ); + sc.add( "{" ); + sc.addIndented( "locations = targetLocations;" ); + sc.add( "}" ); + sc.add( "else if ( targetLocations == null )" ); + sc.add( "{" ); + sc.addIndented( "locations = sourceLocations;" ); + sc.add( "}" ); + sc.add( "else" ); + sc.add( "{" ); + sc.addIndented( "locations = new " + fieldImpl + "();" ); + sc.addIndented( "locations.putAll( sourceDominant ? targetLocations : sourceLocations );" ); + sc.addIndented( "locations.putAll( sourceDominant ? sourceLocations : targetLocations );" ); + sc.add( "}" ); + sc.add( "result.set" + capitalise( locationsField ) + "( locations );" ); + sc.add( "" ); + sc.add( "return result;" ); + jClass.addMethod( jMethod ); + + // public static Location merge( Location target, Location source, Collection indices ) + jMethod = new JMethod( "merge", new JType( locationClass.getName() ), null ); + jMethod.getModifiers().setStatic( true ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), "target" ) ); + jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), "source" ) ); + jMethod.addParameter( new JParameter( new JCollectionType( "java.util.Collection", new JType( "Integer" ), + useJava5 ), "indices" ) ); + String intWrap = useJava5 ? "Integer.valueOf" : "new Integer"; + sc = jMethod.getSourceCode(); + sc.add( "if ( source == null )" ); + sc.add( "{" ); + sc.addIndented( "return target;" ); + sc.add( "}" ); + sc.add( "else if ( target == null )" ); + sc.add( "{" ); + sc.addIndented( "return source;" ); + sc.add( "}" ); + sc.add( "" ); + sc.add( locationClass.getName() + " result =" ); + sc.add( " new " + locationClass.getName() + "( target.getLineNumber(), target.getColumnNumber()" + + ( sourceClass != null ? ", target.get" + capitalise( source.getName() ) + "()" : "" ) + " );" ); + sc.add( "" ); + sc.add( fieldType + " locations;" ); + sc.add( fieldType + " sourceLocations = source.get" + capitalise( locationsField ) + "();" ); + sc.add( fieldType + " targetLocations = target.get" + capitalise( locationsField ) + "();" ); + sc.add( "if ( sourceLocations == null )" ); + sc.add( "{" ); + sc.addIndented( "locations = targetLocations;" ); + sc.add( "}" ); + sc.add( "else if ( targetLocations == null )" ); + sc.add( "{" ); + sc.addIndented( "locations = sourceLocations;" ); + sc.add( "}" ); + sc.add( "else" ); + sc.add( "{" ); + sc.indent(); + sc.add( "locations = new " + fieldImpl + "();" ); + sc.add( "for ( java.util.Iterator" + ( useJava5 ? "" : "" ) + " it = indices.iterator(); it.hasNext(); )" ); + sc.add( "{" ); + sc.indent(); + sc.add( locationClass.getName() + " location;" ); + sc.add( "Integer index = " + ( useJava5 ? "" : "(Integer) " ) + "it.next();" ); + sc.add( "if ( index.intValue() < 0 )" ); + sc.add( "{" ); + sc.addIndented( "location = sourceLocations.get( " + intWrap + "( ~index.intValue() ) );" ); + sc.add( "}" ); + sc.add( "else" ); + sc.add( "{" ); + sc.addIndented( "location = targetLocations.get( index );" ); + sc.add( "}" ); + sc.add( "locations.put( " + intWrap + "( locations.size() ), location );" ); + sc.unindent(); + sc.add( "}" ); + sc.unindent(); + sc.add( "}" ); + sc.add( "result.set" + capitalise( locationsField ) + "( locations );" ); + sc.add( "" ); + sc.add( "return result;" ); + jClass.addMethod( jMethod ); + } + /** * Utility method that adds a period to the end of a string, if the last non-whitespace character of the string is * not a punctuation mark or an end-tag. diff --git a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JClass.java b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JClass.java index 4ddb260ef..175a12316 100644 --- a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JClass.java +++ b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JClass.java @@ -615,6 +615,11 @@ else if ( modifiers.isPublic() ) buffer.append( "abstract " ); } + if ( modifiers.isFinal() ) + { + buffer.append( "final " ); + } + buffer.append( "class " ); buffer.append( getLocalName() ); jsw.writeln( buffer.toString() ); diff --git a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JModifiers.java b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JModifiers.java index bad13292f..140733d06 100644 --- a/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JModifiers.java +++ b/modello-plugins/modello-plugin-java/src/main/java/org/codehaus/modello/plugin/java/javasource/JModifiers.java @@ -202,6 +202,16 @@ public boolean isAbstract() return isAbstract; } //-- isAbstract + /** + * Returns true if the final qualifier is present. + *
This is only applicable to methods and classes. + * @return true if the final qualifier is present + **/ + public boolean isFinal() + { + return isFinal; + } //-- isFinal + /** * Returns true if the modifier represented is private. * @return true if the modifier represented is private. 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 e837bf602..81f2014f2 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 @@ -40,6 +40,7 @@ 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.model.ModelClassMetadata; import org.codehaus.modello.plugins.xml.metadata.XmlAssociationMetadata; import org.codehaus.modello.plugins.xml.metadata.XmlFieldMetadata; import org.codehaus.plexus.util.StringUtils; @@ -52,11 +53,52 @@ public class Xpp3ReaderGenerator extends AbstractXpp3Generator { + + private static final String SOURCE_PARAM = "source"; + + private static final String LOCATION_VAR = "_location"; + + private ModelClass locationTracker; + + private String locationField; + + private ModelClass sourceTracker; + + private String trackingArgs; + + protected boolean isLocationTracking() + { + return false; + } + public void generate( Model model, Properties parameters ) throws ModelloException { initialize( model, parameters ); + locationTracker = sourceTracker = null; + trackingArgs = locationField = ""; + + 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; + } + } + try { generateXpp3Reader(); @@ -75,7 +117,7 @@ private void generateXpp3Reader() String packageName = objectModel.getDefaultPackageName( isPackageWithVersion(), getGeneratedVersion() ) + ".io.xpp3"; - String unmarshallerName = getFileName( "Xpp3Reader" ); + String unmarshallerName = getFileName( "Xpp3Reader" + ( isLocationTracking() ? "Ex" : "" ) ); JSourceWriter sourceWriter = newJSourceWriter( packageName, unmarshallerName ); @@ -144,6 +186,7 @@ private void generateXpp3Reader() unmarshall.addParameter( new JParameter( new JClass( "XmlPullParser" ), "parser" ) ); unmarshall.addParameter( new JParameter( JClass.BOOLEAN, "strict" ) ); + addTrackingParameters( unmarshall ); unmarshall.addException( new JClass( "IOException" ) ); unmarshall.addException( new JClass( "XmlPullParserException" ) ); @@ -173,7 +216,8 @@ private void generateXpp3Reader() + "found '\" + parser.getName() + \"'\", parser, null );" ); sc.add( "}" ); - sc.add( className + ' ' + variableName + " = parse" + root.getName() + "( parser, strict );" ); + sc.add( className + ' ' + variableName + " = parse" + root.getName() + "( parser, strict" + trackingArgs + + " );" ); sc.add( variableName + ".setModelEncoding( parser.getInputEncoding() );" ); @@ -201,6 +245,7 @@ private void generateXpp3Reader() unmarshall.addParameter( new JParameter( new JClass( "Reader" ), "reader" ) ); unmarshall.addParameter( new JParameter( JClass.BOOLEAN, "strict" ) ); + addTrackingParameters( unmarshall ); unmarshall.addException( new JClass( "IOException" ) ); unmarshall.addException( new JClass( "XmlPullParserException" ) ); @@ -219,24 +264,27 @@ private void generateXpp3Reader() sc.add( "" ); - sc.add( "return read( parser, strict );" ); + sc.add( "return read( parser, strict" + trackingArgs + " );" ); jClass.addMethod( unmarshall ); // ---------------------------------------------------------------------- - unmarshall = new JMethod( "read", rootType, null ); - unmarshall.setComment( "@see ReaderFactory#newXmlReader" ); + if ( locationTracker == null ) + { + unmarshall = new JMethod( "read", rootType, null ); + unmarshall.setComment( "@see ReaderFactory#newXmlReader" ); - unmarshall.addParameter( new JParameter( new JClass( "Reader" ), "reader" ) ); + unmarshall.addParameter( new JParameter( new JClass( "Reader" ), "reader" ) ); - unmarshall.addException( new JClass( "IOException" ) ); - unmarshall.addException( new JClass( "XmlPullParserException" ) ); + unmarshall.addException( new JClass( "IOException" ) ); + unmarshall.addException( new JClass( "XmlPullParserException" ) ); - sc = unmarshall.getSourceCode(); - sc.add( "return read( reader, true );" ); + sc = unmarshall.getSourceCode(); + sc.add( "return read( reader, true );" ); - jClass.addMethod( unmarshall ); + jClass.addMethod( unmarshall ); + } // ---------------------------------------------------------------------- // Write the read(InputStream[,boolean]) methods which will do the unmarshalling. @@ -246,38 +294,34 @@ private void generateXpp3Reader() unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "in" ) ); unmarshall.addParameter( new JParameter( JClass.BOOLEAN, "strict" ) ); + addTrackingParameters( unmarshall ); unmarshall.addException( new JClass( "IOException" ) ); unmarshall.addException( new JClass( "XmlPullParserException" ) ); sc = unmarshall.getSourceCode(); - sc.add( "Reader reader = ReaderFactory.newXmlReader( in );" ); - - sc.add( "" ); - - sc.add( "return read( reader, strict );" ); + sc.add( "return read( ReaderFactory.newXmlReader( in ), strict" + trackingArgs + " );" ); jClass.addMethod( unmarshall ); // -------------------------------------------------------------------- - unmarshall = new JMethod( "read", rootType, null ); - - unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "in" ) ); - - unmarshall.addException( new JClass( "IOException" ) ); - unmarshall.addException( new JClass( "XmlPullParserException" ) ); + if ( locationTracker == null ) + { + unmarshall = new JMethod( "read", rootType, null ); - sc = unmarshall.getSourceCode(); + unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "in" ) ); - sc.add( "Reader reader = ReaderFactory.newXmlReader( in );" ); + unmarshall.addException( new JClass( "IOException" ) ); + unmarshall.addException( new JClass( "XmlPullParserException" ) ); - sc.add( "" ); + sc = unmarshall.getSourceCode(); - sc.add( "return read( reader );" ); + sc.add( "return read( ReaderFactory.newXmlReader( in ) );" ); - jClass.addMethod( unmarshall ); + jClass.addMethod( unmarshall ); + } // ---------------------------------------------------------------------- // Write the class parsers @@ -306,6 +350,11 @@ private void writeAllClassesParser( Model objectModel, JClass jClass ) for ( ModelClass clazz : getClasses( objectModel ) ) { + if ( isTrackingSupport( clazz ) ) + { + continue; + } + writeClassParser( clazz, jClass, root.getName().equals( clazz.getName() ) ); } } @@ -332,6 +381,7 @@ private void writeClassParser( ModelClass modelClass, JClass jClass, boolean roo unmarshall.addParameter( new JParameter( new JClass( "XmlPullParser" ), "parser" ) ); unmarshall.addParameter( new JParameter( JClass.BOOLEAN, "strict" ) ); + addTrackingParameters( unmarshall ); unmarshall.addException( new JClass( "IOException" ) ); unmarshall.addException( new JClass( "XmlPullParserException" ) ); @@ -341,6 +391,12 @@ private void writeClassParser( ModelClass modelClass, JClass jClass, boolean roo sc.add( "String tagName = parser.getName();" ); sc.add( className + " " + uncapClassName + " = new " + className + "();" ); + if ( locationTracker != null ) + { + sc.add( locationTracker.getName() + " " + LOCATION_VAR + ";" ); + writeNewSetLocation( "\"\"", uncapClassName, null, sc ); + } + ModelField contentField = null; List modelFields = getFieldsForXml( modelClass, getGeneratedVersion() ); @@ -351,8 +407,8 @@ private void writeClassParser( ModelClass modelClass, JClass jClass, boolean roo // then read content, either content field or elements if ( contentField != null ) { - writePrimitiveField( contentField, contentField.getType(), uncapClassName, - "set" + capitalise( contentField.getName() ), sc, jClass ); + writePrimitiveField( contentField, contentField.getType(), uncapClassName, uncapClassName, "\"\"", "set" + + capitalise( contentField.getName() ), sc, jClass ); } else { @@ -440,8 +496,8 @@ private ModelField writeClassAttributesParser( List modelFields, Str sc.add( "{" ); sc.indent(); - writePrimitiveField( field, field.getType(), objectName, "set" + capitalise( field.getName() ), sc, - jClass ); + writePrimitiveField( field, field.getType(), objectName, objectName, "\"" + field.getName() + "\"", + "set" + capitalise( field.getName() ), sc, jClass ); sc.unindent(); sc.add( "}" ); @@ -504,8 +560,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( "{" ); sc.indent(); - writePrimitiveField( field, field.getType(), objectName, "set" + capitalise( field.getName() ), sc, - jClass ); + writePrimitiveField( field, field.getType(), objectName, objectName, "\"" + field.getName() + "\"", "set" + + capitalise( field.getName() ), sc, jClass ); sc.unindent(); sc.add( "}" ); @@ -521,7 +577,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( tagComparison ); sc.add( "{" ); - sc.addIndented( objectName + ".set" + capFieldName + "( parse" + association.getTo() + "( parser, strict ) );" ); + sc.addIndented( objectName + ".set" + capFieldName + "( parse" + association.getTo() + + "( parser, strict" + trackingArgs + " ) );" ); sc.add( "}" ); } else @@ -539,6 +596,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, { boolean wrappedItems = xmlAssociationMetadata.isWrappedItems(); + boolean inModel = isClassInModel( association.getTo(), field.getModelClass().getModel() ); + if ( wrappedItems ) { sc.add( tagComparison ); @@ -550,6 +609,12 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( objectName + ".set" + capFieldName + "( " + associationName + " );" ); + if ( !inModel && locationTracker != null ) + { + sc.add( locationTracker.getName() + " " + LOCATION_VAR + "s;" ); + writeNewSetLocation( field, objectName, LOCATION_VAR + "s", sc ); + } + sc.add( "while ( parser.nextTag() == XmlPullParser.START_TAG )" ); sc.add( "{" ); @@ -581,15 +646,40 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.unindent(); sc.add( "}" ); + + if ( !inModel && locationTracker != null ) + { + sc.add( locationTracker.getName() + " " + LOCATION_VAR + "s = " + objectName + ".get" + + capitalise( singular( locationField ) ) + "( \"" + field.getName() + "\" );" ); + sc.add( "if ( " + LOCATION_VAR + "s == null )" ); + sc.add( "{" ); + sc.indent(); + writeNewSetLocation( field, objectName, LOCATION_VAR + "s", sc ); + sc.unindent(); + sc.add( "}" ); + } } - if ( isClassInModel( association.getTo(), field.getModelClass().getModel() ) ) + if ( inModel ) { - sc.add( associationName + ".add( parse" + association.getTo() + "( parser, strict ) );" ); + sc.add( associationName + ".add( parse" + association.getTo() + "( parser, strict" + + trackingArgs + " ) );" ); } else { - writePrimitiveField( association, association.getTo(), associationName, "add", sc, jClass ); + String key; + if ( ModelDefault.SET.equals( type ) ) + { + key = "?"; + } + else + { + key = + ( useJava5 ? "Integer.valueOf" : "new java.lang.Integer" ) + "( " + associationName + + ".size() )"; + } + writePrimitiveField( association, association.getTo(), associationName, LOCATION_VAR + "s", + key, "add", sc, jClass ); } if ( wrappedItems ) @@ -624,6 +714,12 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( "{" ); sc.indent(); + if ( locationTracker != null ) + { + sc.add( locationTracker.getName() + " " + LOCATION_VAR + "s;" ); + writeNewSetLocation( field, objectName, LOCATION_VAR + "s", sc ); + } + if ( xmlAssociationMetadata.isMapExplode() ) { sc.add( "while ( parser.nextTag() == XmlPullParser.START_TAG )" ); @@ -639,6 +735,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( "String key = null;" ); sc.add( "String value = null;" ); + + writeNewLocation( LOCATION_VAR, sc ); sc.add( "// " + xmlAssociationMetadata.getMapStyle() + " mode." ); @@ -656,8 +754,10 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( "else if ( \"value\".equals( parser.getName() ) )" ); sc.add( "{" ); - sc.addIndented( "value = parser.nextText()" + ( xmlFieldMetadata.isTrim() ? ".trim()" : "" ) - + ";" ); + sc.indent(); + writeNewLocation( LOCATION_VAR, sc ); + sc.add( "value = parser.nextText()" + ( xmlFieldMetadata.isTrim() ? ".trim()" : "" ) + ";" ); + sc.unindent(); sc.add( "}" ); sc.add( "else" ); @@ -670,6 +770,7 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( "}" ); sc.add( objectName + ".add" + capitalise( singularName ) + "( key, value );" ); + writeSetLocation( "key", LOCATION_VAR + "s", LOCATION_VAR, sc ); sc.unindent(); sc.add( "}" ); @@ -690,6 +791,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, sc.add( "String key = parser.getName();" ); + writeNewSetLocation( "key", LOCATION_VAR + "s", null, sc ); + sc.add( "String value = parser.nextText()" + ( xmlFieldMetadata.isTrim() ? ".trim()" : "" ) + ";" ); @@ -706,8 +809,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, } } - private void writePrimitiveField( ModelField field, String type, String objectName, String setterName, - JSourceCode sc, JClass jClass ) + private void writePrimitiveField( ModelField field, String type, String objectName, String locatorName, + String locationKey, String setterName, JSourceCode sc, JClass jClass ) { XmlFieldMetadata xmlFieldMetadata = (XmlFieldMetadata) field.getMetadata( XmlFieldMetadata.ID ); @@ -735,68 +838,86 @@ private void writePrimitiveField( ModelField field, String type, String objectNa parserGetter = "getTrimmedValue( " + parserGetter + " )"; } + String keyCapture = ""; + writeNewLocation( null, sc ); + if ( locationTracker != null && "?".equals( locationKey ) ) + { + sc.add( "Object _key;" ); + locationKey = "_key"; + keyCapture = "_key = "; + } + else + { + writeSetLocation( locationKey, locatorName, null, sc ); + } + if ( "boolean".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getBooleanValue( " + parserGetter + ", \"" + tagName + - "\", parser, \"" + field.getDefaultValue() + "\" ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getBooleanValue( " + parserGetter + ", \"" + + tagName + "\", parser, \"" + field.getDefaultValue() + "\" ) );" ); } else if ( "char".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getCharacterValue( " + parserGetter + ", \"" + tagName + - "\", parser ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getCharacterValue( " + parserGetter + ", \"" + + tagName + "\", parser ) );" ); } else if ( "double".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getDoubleValue( " + parserGetter + ", \"" + tagName + - "\", parser, strict ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getDoubleValue( " + parserGetter + ", \"" + + tagName + "\", parser, strict ) );" ); } else if ( "float".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getFloatValue( " + parserGetter + ", \"" + tagName + - "\", parser, strict ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getFloatValue( " + parserGetter + ", \"" + + tagName + "\", parser, strict ) );" ); } else if ( "int".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getIntegerValue( " + parserGetter + ", \"" + tagName + - "\", parser, strict ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getIntegerValue( " + parserGetter + ", \"" + + tagName + "\", parser, strict ) );" ); } else if ( "long".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getLongValue( " + parserGetter + ", \"" + tagName + - "\", parser, strict ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getLongValue( " + parserGetter + ", \"" + + tagName + "\", parser, strict ) );" ); } else if ( "short".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getShortValue( " + parserGetter + ", \"" + tagName + - "\", parser, strict ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getShortValue( " + parserGetter + ", \"" + + tagName + "\", parser, strict ) );" ); } else if ( "byte".equals( type ) ) { - sc.add( objectName + "." + setterName + "( getByteValue( " + parserGetter + ", \"" + tagName + - "\", parser, strict ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getByteValue( " + parserGetter + ", \"" + + tagName + "\", parser, strict ) );" ); } else if ( "String".equals( type ) || "Boolean".equals( type ) ) { // TODO: other Primitive types - sc.add( objectName + "." + setterName + "( " + parserGetter + " );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + parserGetter + " );" ); } else if ( "Date".equals( type ) ) { sc.add( "String dateFormat = " + ( xmlFieldMetadata.getFormat() != null ? "\"" + xmlFieldMetadata.getFormat() + "\"" : "null" ) + ";" ); - sc.add( objectName + "." + setterName + "( getDateValue( " + parserGetter + ", \"" + tagName + - "\", dateFormat, parser ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "getDateValue( " + parserGetter + ", \"" + + tagName + "\", dateFormat, parser ) );" ); } else if ( "DOM".equals( type ) ) { jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3DomBuilder" ); - sc.add( objectName + "." + setterName + "( Xpp3DomBuilder.build( parser ) );" ); + sc.add( objectName + "." + setterName + "( " + keyCapture + "Xpp3DomBuilder.build( parser ) );" ); } else { throw new IllegalArgumentException( "Unknown type: " + type ); } + + if ( keyCapture.length() > 0 ) + { + writeSetLocation( locationKey, locatorName, null, sc ); + } } private void writeParserInitialization( JSourceCode sc ) @@ -1436,4 +1557,49 @@ private JMethod initParser() return method; } + private void addTrackingParameters( JMethod method ) + { + if ( sourceTracker != null ) + { + method.addParameter( new JParameter( new JClass( sourceTracker.getName() ), SOURCE_PARAM ) ); + } + } + + private void writeNewSetLocation( ModelField field, String objectName, String trackerVariable, JSourceCode sc ) + { + writeNewSetLocation( "\"" + field.getName() + "\"", objectName, trackerVariable, sc ); + } + + private void writeNewSetLocation( String key, String objectName, String trackerVariable, JSourceCode sc ) + { + writeNewLocation( trackerVariable, sc ); + writeSetLocation( key, objectName, trackerVariable, sc ); + } + + private void writeNewLocation( String trackerVariable, JSourceCode sc ) + { + if ( locationTracker == null ) + { + return; + } + + String constr = "new " + locationTracker.getName() + "( parser.getLineNumber(), parser.getColumnNumber()"; + constr += ( sourceTracker != null ) ? ", " + SOURCE_PARAM : ""; + constr += " )"; + + sc.add( ( ( trackerVariable != null ) ? trackerVariable : LOCATION_VAR ) + " = " + constr + ";" ); + } + + private void writeSetLocation( String key, String objectName, String trackerVariable, JSourceCode sc ) + { + if ( locationTracker == null ) + { + return; + } + + String variable = ( trackerVariable != null ) ? trackerVariable : LOCATION_VAR; + + sc.add( objectName + ".set" + capitalise( singular( locationField ) ) + "( " + key + ", " + variable + " );" ); + } + } 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 04c1e08c4..c33701f1f 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 @@ -5,6 +5,11 @@ xpp3-reader org.codehaus.modello.plugin.xpp3.Xpp3ReaderGenerator + + org.codehaus.modello.plugin.ModelloGenerator + xpp3-extended-reader + org.codehaus.modello.plugin.xpp3.Xpp3ExtendedReaderGenerator + org.codehaus.modello.plugin.ModelloGenerator xpp3-writer diff --git a/pom.xml b/pom.xml index 14ec7ea20..c476837f8 100644 --- a/pom.xml +++ b/pom.xml @@ -492,7 +492,7 @@ src/main/mdo/modello.mdo - 1.3.0 + 1.4.0 diff --git a/src/main/mdo/modello.mdo b/src/main/mdo/modello.mdo index 72829d3d3..4dff69c13 100644 --- a/src/main/mdo/modello.mdo +++ b/src/main/mdo/modello.mdo @@ -389,6 +389,31 @@ see org.codehaus.modello.plugin.model.ModelMetadataPlugin + + locationTracker + 1.4.0+ + String + + + see org.codehaus.modello.plugin.model.ModelMetadataPlugin + + + sourceTracker + 1.4.0+ + String + locationTracker to store the source tracking information and indirectly + controls the names of the generated accessors. This attribute is only relevant in combination with + locationTracker and must not be used on the same class.]]> + + see org.codehaus.modello.plugin.model.ModelMetadataPlugin + tagName 1.0.0+ @@ -424,7 +449,7 @@ clone() method for this class. Allowed values are none, shallow and deep. The value is inherited from super classes - and defaults to none if no super class declares otherwise. Since Modello 1.1]]> + and defaults to none if no super class declares otherwise.]]> see org.codehaus.modello.plugin.java.metadata.JavaMetadataPlugin @@ -439,7 +464,7 @@ the default method name cloneHook. The hook method itself must have a single parameter whose type matches this class in order to receive the cloned object for further manipulation before completion of the clone operation. Besides, the hook method must not have a return value and must not throw a checked - exception. Since Modello 1.1]]> + exception.]]> see org.codehaus.modello.plugin.java.metadata.JavaMetadataPlugin @@ -586,7 +611,7 @@ false Since Modello 1.1]]> + state that is not meant to be persisted into XML.]]> see org.codehaus.modello.plugins.xml.metadata.XmlMetadataPlugin @@ -722,8 +747,7 @@ String shallow and - deep. If the value is not specified, the clone mode of the container class will be used. - Since Modello 1.1]]> + deep. If the value is not specified, the clone mode of the container class will be used.]]> see org.codehaus.modello.plugin.java.metadata.JavaMetadataPlugin From aa30b72a0eb97ce300cfffa2af599bc031d13b6b Mon Sep 17 00:00:00 2001 From: bentmann Date: Fri, 16 Apr 2010 22:48:53 +0000 Subject: [PATCH 02/10] o Added missing files --- .../maven/ModelloXpp3ExtendedReaderMojo.java | 45 +++++++ .../xpp3/Xpp3ExtendedReaderGenerator.java | 48 ++++++++ .../xml/xpp3/LocationsXpp3GeneratorTest.java | 62 ++++++++++ .../locations/Xpp3LocationsVerifier.java | 99 ++++++++++++++++ modello-test/src/main/resources/locations.mdo | 112 ++++++++++++++++++ modello-test/src/main/resources/locations.xml | 48 ++++++++ 6 files changed, 414 insertions(+) create mode 100644 modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java create mode 100644 modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedReaderGenerator.java create mode 100644 modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsXpp3GeneratorTest.java create mode 100644 modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java create mode 100644 modello-test/src/main/resources/locations.mdo create mode 100644 modello-test/src/main/resources/locations.xml diff --git a/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java b/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java new file mode 100644 index 000000000..3246cf412 --- /dev/null +++ b/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java @@ -0,0 +1,45 @@ +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. + */ + +/** + * Creates an XPP3 extended reader from the model. + * + * @goal xpp3-extended-reader + * + * @phase generate-sources + * + * @author Benjamin Bentmann + * @version $Id$ + */ +public class ModelloXpp3ExtendedReaderMojo + extends ModelloXpp3ReaderMojo +{ + + @Override + protected String getGeneratorType() + { + return "xpp3-extended-reader"; + } + +} diff --git a/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedReaderGenerator.java b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedReaderGenerator.java new file mode 100644 index 000000000..548db72c5 --- /dev/null +++ b/modello-plugins/modello-plugin-xpp3/src/main/java/org/codehaus/modello/plugin/xpp3/Xpp3ExtendedReaderGenerator.java @@ -0,0 +1,48 @@ +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.model.ModelClass; + +/** + * The generator for XPP3-based parsers that support input location tracking. + * + * @author Benjamin Bentmann + */ +public class Xpp3ExtendedReaderGenerator + extends Xpp3ReaderGenerator +{ + + @Override + protected boolean isRelevant( ModelClass modelClass ) + { + return isJavaEnabled( modelClass ); + } + + @Override + protected boolean isLocationTracking() + { + return true; + } + +} diff --git a/modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsXpp3GeneratorTest.java b/modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsXpp3GeneratorTest.java new file mode 100644 index 000000000..6f04fda4b --- /dev/null +++ b/modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsXpp3GeneratorTest.java @@ -0,0 +1,62 @@ +package org.codehaus.modello.generator.xml.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.AbstractModelloJavaGeneratorTest; +import org.codehaus.modello.core.ModelloCore; +import org.codehaus.modello.model.Model; + +import java.util.Properties; + +/** + * @author Benjamin Bentmann + * @version $Id$ + */ +public class LocationsXpp3GeneratorTest + extends AbstractModelloJavaGeneratorTest +{ + + public LocationsXpp3GeneratorTest() + { + super( "locations" ); + } + + public void testLocationsOnly() + throws Throwable + { + ModelloCore modello = (ModelloCore) lookup( ModelloCore.ROLE ); + + Model model = modello.loadModel( getXmlResourceReader( "/locations.mdo" ) ); + + Properties parameters = getModelloParameters( "1.0.0" ); + + modello.generate( model, "java", parameters ); + modello.generate( model, "xpp3-reader", parameters ); + modello.generate( model, "xpp3-extended-reader", parameters ); + + compileGeneratedSources(); + + verifyCompiledGeneratedSources( "org.codehaus.modello.generator.xml.xpp3.Xpp3LocationsVerifier" ); + } + +} diff --git a/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java b/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java new file mode 100644 index 000000000..6efae1333 --- /dev/null +++ b/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java @@ -0,0 +1,99 @@ +package org.codehaus.modello.generator.xml.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 junit.framework.Assert; +import org.codehaus.modello.test.locations.Item; +import org.codehaus.modello.test.locations.Location; +import org.codehaus.modello.test.locations.Model; +import org.codehaus.modello.test.locations.io.xpp3.LocationsTestXpp3ReaderEx; +import org.codehaus.modello.verifier.Verifier; + +/** + * @author Benjamin Bentmann + * @version $Id$ + */ +public class Xpp3LocationsVerifier + extends Verifier +{ + + public void verify() + throws Exception + { + LocationsTestXpp3ReaderEx reader = new LocationsTestXpp3ReaderEx(); + + Model model = reader.read( getClass().getResourceAsStream( "/locations.xml" ), true ); + + assertLocation( model.getLocation( "" ), -1, -1 ); + assertLocation( model.getLocation( "string" ), 4, 11 ); + + assertLocation( model.getLocation( "flatListStrings" ), -1, -1 ); + assertLocation( model.getLocation( "flatListStrings" ).getLocation( new Integer( 0 ) ), 6, 19 ); + assertLocation( model.getLocation( "flatListStrings" ).getLocation( new Integer( 1 ) ), 7, 19 ); + assertLocation( model.getLocation( "flatListStrings" ).getLocation( new Integer( 2 ) ), 8, 19 ); + + assertLocation( model.getLocation( "flatSetStrings" ), -1, -1 ); + assertLocation( model.getLocation( "flatSetStrings" ).getLocation( "a" ), 10, 18 ); + assertLocation( model.getLocation( "flatSetStrings" ).getLocation( "b" ), 11, 18 ); + assertLocation( model.getLocation( "flatSetStrings" ).getLocation( "c" ), 12, 18 ); + + assertLocation( model.getLocation( "wrappedListStrings" ), -1, -1 ); + assertLocation( model.getLocation( "wrappedListStrings" ).getLocation( new Integer( 0 ) ), 15, 24 ); + assertLocation( model.getLocation( "wrappedListStrings" ).getLocation( new Integer( 1 ) ), 16, 24 ); + assertLocation( model.getLocation( "wrappedListStrings" ).getLocation( new Integer( 2 ) ), 17, 24 ); + + assertLocation( model.getLocation( "wrappedSetStrings" ), -1, -1 ); + assertLocation( model.getLocation( "wrappedSetStrings" ).getLocation( "a" ), 21, 23 ); + assertLocation( model.getLocation( "wrappedSetStrings" ).getLocation( "b" ), 22, 23 ); + assertLocation( model.getLocation( "wrappedSetStrings" ).getLocation( "c" ), 23, 23 ); + + assertLocation( model.getLocation( "inlinedProperties" ), -1, -1 ); + assertLocation( model.getLocation( "inlinedProperties" ).getLocation( "a" ), 27, 8 ); + assertLocation( model.getLocation( "inlinedProperties" ).getLocation( "b" ), 28, 8 ); + + assertLocation( model.getLocation( "explodedProperties" ), -1, -1 ); + assertLocation( model.getLocation( "explodedProperties" ).getLocation( "a" ), 34, 14 ); + assertLocation( model.getLocation( "explodedProperties" ).getLocation( "b" ), 38, 14 ); + + Item item = model.getItems().get( 0 ); + assertNotNull( item ); + + assertLocation( item.getLocation( "" ), -1, -1 ); + assertLocation( item.getLocation( "string" ), 45, 15 ); + } + + private void assertLocation( Location location, int line, int column) + throws Exception + { + assertNotNull( location ); + if ( line >= 0 ) + { + assertEquals( line, location.getLineNumber() ); + } + if ( column >= 0 ) + { + assertEquals( column, location.getColumnNumber() ); + } + } + +} diff --git a/modello-test/src/main/resources/locations.mdo b/modello-test/src/main/resources/locations.mdo new file mode 100644 index 000000000..00ed6fb59 --- /dev/null +++ b/modello-test/src/main/resources/locations.mdo @@ -0,0 +1,112 @@ + + + + locations + LocationsTest + A model to test support for location tracking without additional source tracking. + + + + package + org.codehaus.modello.test.locations + + + + + + Location + 1.0.0+ + + + + + + Model + 1.0.0+ + + + string + 1.0.0+ + String + + + flatListStrings + 1.0.0+ + List + + String + * + + + + flatSetStrings + 1.0.0+ + Set + + String + * + + + + wrappedListStrings + 1.0.0+ + List + + String + * + + + + wrappedSetStrings + 1.0.0+ + Set + + String + * + + + + explodedProperties + 1.0.0+ + Properties + + String + * + + + + inlinedProperties + 1.0.0+ + Properties + + String + * + + + + items + 1.0.0+ + List + + Item + * + + + + + + Item + 1.0.0+ + + + string + 1.0.0+ + String + + + + + diff --git a/modello-test/src/main/resources/locations.xml b/modello-test/src/main/resources/locations.xml new file mode 100644 index 000000000..14f274ae8 --- /dev/null +++ b/modello-test/src/main/resources/locations.xml @@ -0,0 +1,48 @@ + + + + test + + a + b + c + + a + b + c + + + a + b + c + + + + a + b + c + + + + test + test + + + + + a + test + + + + test + b + + + + + + test + + + From ae5af27d0da249a48aaee64abefbb497c40edc85 Mon Sep 17 00:00:00 2001 From: bentmann Date: Fri, 16 Apr 2010 22:56:54 +0000 Subject: [PATCH 03/10] o Set svn:eol-style=native From b8433e2cf4409ba824c6543e234842e50eab4e17 Mon Sep 17 00:00:00 2001 From: bentmann Date: Sat, 17 Apr 2010 09:45:52 +0000 Subject: [PATCH 04/10] o Extended tests --- .../java/LocationsJavaGeneratorTest.java | 60 +++++++++ .../locations/JavaLocationsVerifier.java | 46 +++++++ .../LocationsSourceXpp3GeneratorTest.java | 62 +++++++++ .../Xpp3LocationsSourceVerifier.java | 106 +++++++++++++++ .../locations/Xpp3LocationsVerifier.java | 4 +- .../src/main/resources/locations+source.mdo | 123 ++++++++++++++++++ modello-test/src/main/resources/locations.mdo | 4 +- 7 files changed, 402 insertions(+), 3 deletions(-) create mode 100644 modello-plugins/modello-plugin-java/src/test/java/org/codehaus/modello/plugin/java/LocationsJavaGeneratorTest.java create mode 100644 modello-plugins/modello-plugin-java/src/test/verifiers/locations/JavaLocationsVerifier.java create mode 100644 modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsSourceXpp3GeneratorTest.java create mode 100644 modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations+src/Xpp3LocationsSourceVerifier.java create mode 100644 modello-test/src/main/resources/locations+source.mdo diff --git a/modello-plugins/modello-plugin-java/src/test/java/org/codehaus/modello/plugin/java/LocationsJavaGeneratorTest.java b/modello-plugins/modello-plugin-java/src/test/java/org/codehaus/modello/plugin/java/LocationsJavaGeneratorTest.java new file mode 100644 index 000000000..8034baf70 --- /dev/null +++ b/modello-plugins/modello-plugin-java/src/test/java/org/codehaus/modello/plugin/java/LocationsJavaGeneratorTest.java @@ -0,0 +1,60 @@ +package org.codehaus.modello.plugin.java; + +/* + * 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.AbstractModelloJavaGeneratorTest; +import org.codehaus.modello.core.ModelloCore; +import org.codehaus.modello.model.Model; + +import java.util.Properties; + +/** + * @author Benjamin Bentmann + * @version $Id$ + */ +public class LocationsJavaGeneratorTest + extends AbstractModelloJavaGeneratorTest +{ + + public LocationsJavaGeneratorTest() + { + super( "locations" ); + } + + public void testLocations() + throws Throwable + { + ModelloCore modello = (ModelloCore) lookup( ModelloCore.ROLE ); + + Model model = modello.loadModel( getXmlResourceReader( "/locations.mdo" ) ); + + Properties parameters = getModelloParameters( "1.0.0" ); + + modello.generate( model, "java", parameters ); + + compileGeneratedSources(); + + verifyCompiledGeneratedSources( "JavaLocationsVerifier" ); + } + +} diff --git a/modello-plugins/modello-plugin-java/src/test/verifiers/locations/JavaLocationsVerifier.java b/modello-plugins/modello-plugin-java/src/test/verifiers/locations/JavaLocationsVerifier.java new file mode 100644 index 000000000..bf59e4182 --- /dev/null +++ b/modello-plugins/modello-plugin-java/src/test/verifiers/locations/JavaLocationsVerifier.java @@ -0,0 +1,46 @@ +/* + * 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 junit.framework.Assert; +import org.codehaus.modello.test.locations.Item; +import org.codehaus.modello.test.locations.Location; +import org.codehaus.modello.test.locations.LocationTracker; +import org.codehaus.modello.test.locations.Model; +import org.codehaus.modello.verifier.Verifier; + +/** + * @author Benjamin Bentmann + * @version $Id$ + */ +public class JavaLocationsVerifier + extends Verifier +{ + + public void verify() + throws Exception + { + assertTrue( LocationTracker.class.isAssignableFrom( Model.class ) ); + assertTrue( LocationTracker.class.isAssignableFrom( Item.class ) ); + assertTrue( LocationTracker.class.isAssignableFrom( Location.class ) ); + } + +} diff --git a/modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsSourceXpp3GeneratorTest.java b/modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsSourceXpp3GeneratorTest.java new file mode 100644 index 000000000..e4e26d9a2 --- /dev/null +++ b/modello-plugins/modello-plugin-xpp3/src/test/java/org/codehaus/modello/generator/xml/xpp3/LocationsSourceXpp3GeneratorTest.java @@ -0,0 +1,62 @@ +package org.codehaus.modello.generator.xml.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.AbstractModelloJavaGeneratorTest; +import org.codehaus.modello.core.ModelloCore; +import org.codehaus.modello.model.Model; + +import java.util.Properties; + +/** + * @author Benjamin Bentmann + * @version $Id$ + */ +public class LocationsSourceXpp3GeneratorTest + extends AbstractModelloJavaGeneratorTest +{ + + public LocationsSourceXpp3GeneratorTest() + { + super( "locations+src" ); + } + + public void testLocationsWithSource() + throws Throwable + { + ModelloCore modello = (ModelloCore) lookup( ModelloCore.ROLE ); + + Model model = modello.loadModel( getXmlResourceReader( "/locations+source.mdo" ) ); + + Properties parameters = getModelloParameters( "1.0.0" ); + + modello.generate( model, "java", parameters ); + modello.generate( model, "xpp3-reader", parameters ); + modello.generate( model, "xpp3-extended-reader", parameters ); + + compileGeneratedSources(); + + verifyCompiledGeneratedSources( "org.codehaus.modello.generator.xml.xpp3.Xpp3LocationsSourceVerifier" ); + } + +} diff --git a/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations+src/Xpp3LocationsSourceVerifier.java b/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations+src/Xpp3LocationsSourceVerifier.java new file mode 100644 index 000000000..130333622 --- /dev/null +++ b/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations+src/Xpp3LocationsSourceVerifier.java @@ -0,0 +1,106 @@ +package org.codehaus.modello.generator.xml.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 junit.framework.Assert; +import org.codehaus.modello.test.locationssrc.Item; +import org.codehaus.modello.test.locationssrc.Location; +import org.codehaus.modello.test.locationssrc.Model; +import org.codehaus.modello.test.locationssrc.Source; +import org.codehaus.modello.test.locationssrc.io.xpp3.LocationsSourceTestXpp3ReaderEx; +import org.codehaus.modello.verifier.Verifier; + +/** + * @author Benjamin Bentmann + * @version $Id$ + */ +public class Xpp3LocationsSourceVerifier + extends Verifier +{ + + public void verify() + throws Exception + { + Source source = new Source(); + + LocationsSourceTestXpp3ReaderEx reader = new LocationsSourceTestXpp3ReaderEx(); + + Model model = reader.read( getClass().getResourceAsStream( "/locations.xml" ), true, source ); + + assertLocation( model.getLocation( "" ), -1, -1, source ); + assertLocation( model.getLocation( "string" ), 4, 11, source ); + + assertLocation( model.getLocation( "flatListStrings" ), -1, -1, source ); + assertLocation( model.getLocation( "flatListStrings" ).getLocation( new Integer( 0 ) ), 6, 19, source ); + assertLocation( model.getLocation( "flatListStrings" ).getLocation( new Integer( 1 ) ), 7, 19, source ); + assertLocation( model.getLocation( "flatListStrings" ).getLocation( new Integer( 2 ) ), 8, 19, source ); + + assertLocation( model.getLocation( "flatSetStrings" ), -1, -1, source ); + assertLocation( model.getLocation( "flatSetStrings" ).getLocation( "a" ), 10, 18, source ); + assertLocation( model.getLocation( "flatSetStrings" ).getLocation( "b" ), 11, 18, source ); + assertLocation( model.getLocation( "flatSetStrings" ).getLocation( "c" ), 12, 18, source ); + + assertLocation( model.getLocation( "wrappedListStrings" ), -1, -1, source ); + assertLocation( model.getLocation( "wrappedListStrings" ).getLocation( new Integer( 0 ) ), 15, 24, source ); + assertLocation( model.getLocation( "wrappedListStrings" ).getLocation( new Integer( 1 ) ), 16, 24, source ); + assertLocation( model.getLocation( "wrappedListStrings" ).getLocation( new Integer( 2 ) ), 17, 24, source ); + + assertLocation( model.getLocation( "wrappedSetStrings" ), -1, -1, source ); + assertLocation( model.getLocation( "wrappedSetStrings" ).getLocation( "a" ), 21, 23, source ); + assertLocation( model.getLocation( "wrappedSetStrings" ).getLocation( "b" ), 22, 23, source ); + assertLocation( model.getLocation( "wrappedSetStrings" ).getLocation( "c" ), 23, 23, source ); + + assertLocation( model.getLocation( "inlinedProperties" ), -1, -1, source ); + assertLocation( model.getLocation( "inlinedProperties" ).getLocation( "a" ), 27, 8, source ); + assertLocation( model.getLocation( "inlinedProperties" ).getLocation( "b" ), 28, 8, source ); + + assertLocation( model.getLocation( "explodedProperties" ), -1, -1, source ); + assertLocation( model.getLocation( "explodedProperties" ).getLocation( "a" ), 34, 14, source ); + assertLocation( model.getLocation( "explodedProperties" ).getLocation( "b" ), 38, 14, source ); + + Item item = model.getItems().get( 0 ); + assertNotNull( item ); + + assertLocation( item.getLocation( "" ), -1, -1, source ); + assertLocation( item.getLocation( "string" ), 45, 15, source ); + } + + private void assertLocation( Location location, int line, int column, Source src ) + throws Exception + { + assertNotNull( location ); + + assertSame( src, location.getSource() ); + + if ( line >= 0 ) + { + assertEquals( line, location.getLineNumber() ); + } + + if ( column >= 0 ) + { + assertEquals( column, location.getColumnNumber() ); + } + } + +} diff --git a/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java b/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java index 6efae1333..eebbbe312 100644 --- a/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java +++ b/modello-plugins/modello-plugin-xpp3/src/test/verifiers/locations/Xpp3LocationsVerifier.java @@ -82,14 +82,16 @@ public void verify() assertLocation( item.getLocation( "string" ), 45, 15 ); } - private void assertLocation( Location location, int line, int column) + private void assertLocation( Location location, int line, int column ) throws Exception { assertNotNull( location ); + if ( line >= 0 ) { assertEquals( line, location.getLineNumber() ); } + if ( column >= 0 ) { assertEquals( column, location.getColumnNumber() ); diff --git a/modello-test/src/main/resources/locations+source.mdo b/modello-test/src/main/resources/locations+source.mdo new file mode 100644 index 000000000..8c2214256 --- /dev/null +++ b/modello-test/src/main/resources/locations+source.mdo @@ -0,0 +1,123 @@ + + + + locations + LocationsSourceTest + A model to test support for location tracking with additional source tracking. + + + + package + org.codehaus.modello.test.locationssrc + + + + + + Location + 1.0.0+ + + + + + + Source + 1.0.0+ + + + path + 1.0.0+ + String + + + + + Model + 1.0.0+ + + + string + 1.0.0+ + String + + + flatListStrings + 1.0.0+ + List + + String + * + + + + flatSetStrings + 1.0.0+ + Set + + String + * + + + + wrappedListStrings + 1.0.0+ + List + + String + * + + + + wrappedSetStrings + 1.0.0+ + Set + + String + * + + + + explodedProperties + 1.0.0+ + Properties + + String + * + + + + inlinedProperties + 1.0.0+ + Properties + + String + * + + + + items + 1.0.0+ + List + + Item + * + + + + + + Item + 1.0.0+ + + + string + 1.0.0+ + String + + + + + diff --git a/modello-test/src/main/resources/locations.mdo b/modello-test/src/main/resources/locations.mdo index 00ed6fb59..6c1adba1f 100644 --- a/modello-test/src/main/resources/locations.mdo +++ b/modello-test/src/main/resources/locations.mdo @@ -23,7 +23,7 @@ - + Model 1.0.0+ @@ -97,7 +97,7 @@ - + Item 1.0.0+ From 67a50f748b0829e77d11f31a75f49222af754c78 Mon Sep 17 00:00:00 2001 From: bentmann Date: Sat, 17 Apr 2010 09:51:35 +0000 Subject: [PATCH 05/10] o Derived interface name from class name --- .../org/codehaus/modello/plugin/java/JavaModelloGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e59de2781..41c2ddcf5 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 @@ -712,7 +712,7 @@ private String generateLocationTracker( Model objectModel, ModelClass locationCl String propertyName = capitalise( singular( locationField ) ); - String interfaceName = propertyName + "Tracker"; + String interfaceName = locationClass.getName() + "Tracker"; String packageName = locationClass.getPackageName( isPackageWithVersion(), getGeneratedVersion() ); From 33757672db935c3a92eedff0d25c2b665def8bcf Mon Sep 17 00:00:00 2001 From: bentmann Date: Sat, 17 Apr 2010 12:10:14 +0000 Subject: [PATCH 06/10] o Merged r1445 from trunk --- modello-core/src/main/resources/META-INF/plexus/components.xml | 3 +++ .../src/main/resources/META-INF/plexus/components.xml | 1 + .../src/main/resources/META-INF/plexus/components.xml | 2 ++ .../src/main/resources/META-INF/plexus/components.xml | 2 ++ .../src/main/resources/META-INF/plexus/components.xml | 1 + .../src/main/resources/META-INF/plexus/components.xml | 2 ++ .../src/main/resources/META-INF/plexus/components.xml | 2 ++ .../src/main/resources/META-INF/plexus/components.xml | 3 +++ 8 files changed, 16 insertions(+) diff --git a/modello-core/src/main/resources/META-INF/plexus/components.xml b/modello-core/src/main/resources/META-INF/plexus/components.xml index 97e7d2e6a..78beb09cc 100644 --- a/modello-core/src/main/resources/META-INF/plexus/components.xml +++ b/modello-core/src/main/resources/META-INF/plexus/components.xml @@ -3,6 +3,7 @@ org.codehaus.modello.core.ModelloCore org.codehaus.modello.core.DefaultModelloCore + per-lookup org.codehaus.modello.core.MetadataPluginManager @@ -15,6 +16,7 @@ org.codehaus.modello.core.MetadataPluginManager org.codehaus.modello.core.DefaultMetadataPluginManager + per-lookup plugins @@ -25,6 +27,7 @@ org.codehaus.modello.core.GeneratorPluginManager org.codehaus.modello.core.DefaultGeneratorPluginManager + per-lookup plugins diff --git a/modello-plugins/modello-plugin-converters/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-converters/src/main/resources/META-INF/plexus/components.xml index dcddd0127..36d048912 100644 --- a/modello-plugins/modello-plugin-converters/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-converters/src/main/resources/META-INF/plexus/components.xml @@ -4,6 +4,7 @@ org.codehaus.modello.plugin.ModelloGenerator converters org.codehaus.modello.plugin.converters.ConverterGenerator + per-lookup diff --git a/modello-plugins/modello-plugin-dom4j/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-dom4j/src/main/resources/META-INF/plexus/components.xml index aace53e5b..4db1f2576 100644 --- a/modello-plugins/modello-plugin-dom4j/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-dom4j/src/main/resources/META-INF/plexus/components.xml @@ -4,11 +4,13 @@ org.codehaus.modello.plugin.ModelloGenerator dom4j-reader org.codehaus.modello.plugin.dom4j.Dom4jReaderGenerator + per-lookup org.codehaus.modello.plugin.ModelloGenerator dom4j-writer org.codehaus.modello.plugin.dom4j.Dom4jWriterGenerator + per-lookup diff --git a/modello-plugins/modello-plugin-java/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-java/src/main/resources/META-INF/plexus/components.xml index f14c4a552..e74e2a84e 100644 --- a/modello-plugins/modello-plugin-java/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-java/src/main/resources/META-INF/plexus/components.xml @@ -4,12 +4,14 @@ org.codehaus.modello.plugin.ModelloGenerator java org.codehaus.modello.plugin.java.JavaModelloGenerator + per-lookup org.codehaus.modello.metadata.MetadataPlugin java org.codehaus.modello.plugin.java.metadata.JavaMetadataPlugin + per-lookup diff --git a/modello-plugins/modello-plugin-jdom/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-jdom/src/main/resources/META-INF/plexus/components.xml index 816e2d0eb..d2182efe5 100644 --- a/modello-plugins/modello-plugin-jdom/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-jdom/src/main/resources/META-INF/plexus/components.xml @@ -4,6 +4,7 @@ org.codehaus.modello.plugin.ModelloGenerator jdom-writer org.codehaus.modello.plugin.jdom.JDOMWriterGenerator + per-lookup diff --git a/modello-plugins/modello-plugin-stax/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-stax/src/main/resources/META-INF/plexus/components.xml index 09c2c7171..8afe2f30d 100644 --- a/modello-plugins/modello-plugin-stax/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-stax/src/main/resources/META-INF/plexus/components.xml @@ -4,11 +4,13 @@ org.codehaus.modello.plugin.ModelloGenerator stax-reader org.codehaus.modello.plugin.stax.StaxReaderGenerator + per-lookup org.codehaus.modello.plugin.ModelloGenerator stax-writer org.codehaus.modello.plugin.stax.StaxWriterGenerator + per-lookup diff --git a/modello-plugins/modello-plugin-xdoc/src/main/resources/META-INF/plexus/components.xml b/modello-plugins/modello-plugin-xdoc/src/main/resources/META-INF/plexus/components.xml index c74c698ef..3af391ffa 100644 --- a/modello-plugins/modello-plugin-xdoc/src/main/resources/META-INF/plexus/components.xml +++ b/modello-plugins/modello-plugin-xdoc/src/main/resources/META-INF/plexus/components.xml @@ -4,12 +4,14 @@ org.codehaus.modello.plugin.ModelloGenerator xdoc org.codehaus.modello.plugin.xdoc.XdocGenerator + per-lookup org.codehaus.modello.metadata.MetadataPlugin xdoc org.codehaus.modello.plugin.xdoc.metadata.XdocMetadataPlugin + per-lookup 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 c33701f1f..1d0d75854 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 @@ -4,16 +4,19 @@ org.codehaus.modello.plugin.ModelloGenerator xpp3-reader org.codehaus.modello.plugin.xpp3.Xpp3ReaderGenerator + per-lookup org.codehaus.modello.plugin.ModelloGenerator xpp3-extended-reader org.codehaus.modello.plugin.xpp3.Xpp3ExtendedReaderGenerator + per-lookup org.codehaus.modello.plugin.ModelloGenerator xpp3-writer org.codehaus.modello.plugin.xpp3.Xpp3WriterGenerator + per-lookup From a255cbc511da664e7fbfbf44cf88b2763468584c Mon Sep 17 00:00:00 2001 From: bentmann Date: Sat, 17 Apr 2010 16:58:03 +0000 Subject: [PATCH 07/10] o Merged r1447 from trunk --- modello-plugins/modello-plugin-stax/pom.xml | 12 - .../plugin/stax/StaxSerializerGenerator.java | 363 ++++++++++++++++++ .../plugin/stax/StaxWriterGenerator.java | 6 +- .../resources/META-INF/plexus/components.xml | 13 + .../stax/AbstractStaxGeneratorTestCase.java | 1 - 5 files changed, 381 insertions(+), 14 deletions(-) create mode 100644 modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxSerializerGenerator.java diff --git a/modello-plugins/modello-plugin-stax/pom.xml b/modello-plugins/modello-plugin-stax/pom.xml index 191f5c87b..991a1b606 100644 --- a/modello-plugins/modello-plugin-stax/pom.xml +++ b/modello-plugins/modello-plugin-stax/pom.xml @@ -23,18 +23,6 @@ org.codehaus.modello modello-plugin-java - - net.java.dev.stax-utils - stax-utils - 20060502 - - - com.bea.xml - jsr173-ri - - - test - + + dom4j + dom4j + 1.6.1 + compile + + + + + test + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.4 + 1.4 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.2 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.4.3 + + + org.codehaus.modello + modello-maven-plugin + @project.version@ + + 1.0.0 + + src/main/mdo/thing.mdo + + + + + standard + + java + dom4j-reader + dom4j-writer + + + + + + + diff --git a/modello-maven-plugin/src/it/dom4j-no-plexus-utils/src/main/mdo/thing.mdo b/modello-maven-plugin/src/it/dom4j-no-plexus-utils/src/main/mdo/thing.mdo new file mode 100644 index 000000000..4ac21bf8d --- /dev/null +++ b/modello-maven-plugin/src/it/dom4j-no-plexus-utils/src/main/mdo/thing.mdo @@ -0,0 +1,134 @@ + + thing + Thing + + + package + test + + + + + SuperThing + 1.0.0 + + + Thing + SuperThing + 1.0.0 + + + + someBoolean + 1.0.0 + boolean + + + someChar + 1.0.0 + char + + + someByte + 1.0.0 + byte + + + someShort + 1.0.0 + short + + + someInt + 1.0.0 + int + + + someLong + 1.0.0 + long + + + someFloat + 1.0.0 + float + + + someDouble + 1.0.0 + double + + + someString + 1.0.0 + String + + + someDate + 1.0.0 + Date + + + + someProperties + 1.0.0 + Properties + + String + * + + + + someStringList + 1.0.0 + List + + String + * + + + + someStringSet + 1.0.0 + Set + + String + * + + + + + thingy + 1.0.0 + + Thingy + 1 + + + + thingyList + 1.0.0 + List + + Thingy + * + + + + thingySet + 1.0.0 + Set + + Thingy + * + + + + + + Thingy + SuperThing + 1.0.0 + + + diff --git a/modello-maven-plugin/src/it/dom4j-no-plexus-utils/verify.bsh b/modello-maven-plugin/src/it/dom4j-no-plexus-utils/verify.bsh new file mode 100644 index 000000000..4a91d33a4 --- /dev/null +++ b/modello-maven-plugin/src/it/dom4j-no-plexus-utils/verify.bsh @@ -0,0 +1,13 @@ +import java.io.*; + +File readerClass = new File( basedir, "target/classes/test/io/dom4j/ThingDom4jReader.class" ); +if ( !readerClass.isFile() ) +{ + throw new FileNotFoundException( "Missing " + readerClass ); +} + +File writerClass = new File( basedir, "target/classes/test/io/dom4j/ThingDom4jWriter.class" ); +if ( !writerClass.isFile() ) +{ + throw new FileNotFoundException( "Missing " + writerClass ); +} diff --git a/modello-maven-plugin/src/it/jdom-no-plexus-utils/pom.xml b/modello-maven-plugin/src/it/jdom-no-plexus-utils/pom.xml new file mode 100644 index 000000000..42ad828d3 --- /dev/null +++ b/modello-maven-plugin/src/it/jdom-no-plexus-utils/pom.xml @@ -0,0 +1,70 @@ + + + + 4.0.0 + + org.codehaus.modello.its + jdom-no-plexus-utils + 0.1-SNAPSHOT + + JDOM IT + + Test that the JDOM based readers/writers do not have a dependency on plexus-utils' Xpp3Dom if the model + does not use DOM fields. + + + + + + org.jdom + jdom + 1.1 + compile + + + + + test + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.4 + 1.4 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.2 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.4.3 + + + org.codehaus.modello + modello-maven-plugin + @project.version@ + + 1.0.0 + + src/main/mdo/thing.mdo + + + + + standard + + java + jdom-writer + + + + + + + diff --git a/modello-maven-plugin/src/it/jdom-no-plexus-utils/src/main/mdo/thing.mdo b/modello-maven-plugin/src/it/jdom-no-plexus-utils/src/main/mdo/thing.mdo new file mode 100644 index 000000000..4ac21bf8d --- /dev/null +++ b/modello-maven-plugin/src/it/jdom-no-plexus-utils/src/main/mdo/thing.mdo @@ -0,0 +1,134 @@ + + thing + Thing + + + package + test + + + + + SuperThing + 1.0.0 + + + Thing + SuperThing + 1.0.0 + + + + someBoolean + 1.0.0 + boolean + + + someChar + 1.0.0 + char + + + someByte + 1.0.0 + byte + + + someShort + 1.0.0 + short + + + someInt + 1.0.0 + int + + + someLong + 1.0.0 + long + + + someFloat + 1.0.0 + float + + + someDouble + 1.0.0 + double + + + someString + 1.0.0 + String + + + someDate + 1.0.0 + Date + + + + someProperties + 1.0.0 + Properties + + String + * + + + + someStringList + 1.0.0 + List + + String + * + + + + someStringSet + 1.0.0 + Set + + String + * + + + + + thingy + 1.0.0 + + Thingy + 1 + + + + thingyList + 1.0.0 + List + + Thingy + * + + + + thingySet + 1.0.0 + Set + + Thingy + * + + + + + + Thingy + SuperThing + 1.0.0 + + + diff --git a/modello-maven-plugin/src/it/jdom-no-plexus-utils/verify.bsh b/modello-maven-plugin/src/it/jdom-no-plexus-utils/verify.bsh new file mode 100644 index 000000000..bf09d038d --- /dev/null +++ b/modello-maven-plugin/src/it/jdom-no-plexus-utils/verify.bsh @@ -0,0 +1,7 @@ +import java.io.*; + +File writerClass = new File( basedir, "target/classes/test/io/jdom/ThingJDOMWriter.class" ); +if ( !writerClass.isFile() ) +{ + throw new FileNotFoundException( "Missing " + writerClass ); +} diff --git a/modello-maven-plugin/src/it/stax-no-plexus-utils/pom.xml b/modello-maven-plugin/src/it/stax-no-plexus-utils/pom.xml new file mode 100644 index 000000000..59b2e09c5 --- /dev/null +++ b/modello-maven-plugin/src/it/stax-no-plexus-utils/pom.xml @@ -0,0 +1,77 @@ + + + + 4.0.0 + + org.codehaus.modello.its + stax-no-plexus-utils + 0.1-SNAPSHOT + + StAX IT + + Test that the StAX based readers/writers do not have a dependency on plexus-utils' Xpp3Dom if the model + does not use DOM fields. + + + + + + stax + stax-api + 1.0.1 + compile + + + org.codehaus.woodstox + wstx-asl + 3.2.0 + compile + + + + + test + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.4 + 1.4 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.2 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.4.3 + + + org.codehaus.modello + modello-maven-plugin + @project.version@ + + 1.0.0 + + src/main/mdo/thing.mdo + + + + + standard + + java + stax-reader + stax-writer + + + + + + + diff --git a/modello-maven-plugin/src/it/stax-no-plexus-utils/src/main/mdo/thing.mdo b/modello-maven-plugin/src/it/stax-no-plexus-utils/src/main/mdo/thing.mdo new file mode 100644 index 000000000..4ac21bf8d --- /dev/null +++ b/modello-maven-plugin/src/it/stax-no-plexus-utils/src/main/mdo/thing.mdo @@ -0,0 +1,134 @@ + + thing + Thing + + + package + test + + + + + SuperThing + 1.0.0 + + + Thing + SuperThing + 1.0.0 + + + + someBoolean + 1.0.0 + boolean + + + someChar + 1.0.0 + char + + + someByte + 1.0.0 + byte + + + someShort + 1.0.0 + short + + + someInt + 1.0.0 + int + + + someLong + 1.0.0 + long + + + someFloat + 1.0.0 + float + + + someDouble + 1.0.0 + double + + + someString + 1.0.0 + String + + + someDate + 1.0.0 + Date + + + + someProperties + 1.0.0 + Properties + + String + * + + + + someStringList + 1.0.0 + List + + String + * + + + + someStringSet + 1.0.0 + Set + + String + * + + + + + thingy + 1.0.0 + + Thingy + 1 + + + + thingyList + 1.0.0 + List + + Thingy + * + + + + thingySet + 1.0.0 + Set + + Thingy + * + + + + + + Thingy + SuperThing + 1.0.0 + + + diff --git a/modello-maven-plugin/src/it/stax-no-plexus-utils/verify.bsh b/modello-maven-plugin/src/it/stax-no-plexus-utils/verify.bsh new file mode 100644 index 000000000..4964471cf --- /dev/null +++ b/modello-maven-plugin/src/it/stax-no-plexus-utils/verify.bsh @@ -0,0 +1,13 @@ +import java.io.*; + +File readerClass = new File( basedir, "target/classes/test/io/stax/ThingStaxReader.class" ); +if ( !readerClass.isFile() ) +{ + throw new FileNotFoundException( "Missing " + readerClass ); +} + +File writerClass = new File( basedir, "target/classes/test/io/stax/ThingStaxWriter.class" ); +if ( !writerClass.isFile() ) +{ + throw new FileNotFoundException( "Missing " + writerClass ); +} diff --git a/modello-plugins/modello-plugin-converters/src/test/java/org/codehaus/modello/plugin/converters/ConverterGeneratorTest.java b/modello-plugins/modello-plugin-converters/src/test/java/org/codehaus/modello/plugin/converters/ConverterGeneratorTest.java index df8788e60..6663032cd 100644 --- a/modello-plugins/modello-plugin-converters/src/test/java/org/codehaus/modello/plugin/converters/ConverterGeneratorTest.java +++ b/modello-plugins/modello-plugin-converters/src/test/java/org/codehaus/modello/plugin/converters/ConverterGeneratorTest.java @@ -50,7 +50,6 @@ public void testConverterGenerator() generateConverterClasses( getXmlResourceReader( "/features.mdo" ), "1.0.0", "1.1.0" ); addDependency( "stax", "stax-api", "1.0.1" ); - addDependency( "net.java.dev.stax-utils", "stax-utils", "20060502" ); addDependency( "org.codehaus.woodstox", "wstx-asl", "3.2.0" ); compileGeneratedSources(); diff --git a/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java b/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java index d477d3046..2d270f22d 100644 --- a/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java +++ b/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java @@ -52,11 +52,16 @@ public class Dom4jReaderGenerator extends AbstractXmlJavaGenerator { + + private boolean requiresDomSupport; + public void generate( Model model, Properties parameters ) throws ModelloException { initialize( model, parameters ); + requiresDomSupport = false; + try { generateDom4jReader(); @@ -91,7 +96,6 @@ private void generateDom4jReader() jClass.addImport( "java.text.DateFormat" ); jClass.addImport( "java.text.ParsePosition" ); jClass.addImport( "java.util.Iterator" ); - jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); jClass.addImport( "org.dom4j.Attribute" ); jClass.addImport( "org.dom4j.Document" ); jClass.addImport( "org.dom4j.DocumentException" ); @@ -219,6 +223,12 @@ private void generateDom4jReader() writeHelpers( jClass ); + if ( requiresDomSupport ) + { + jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); + writeDomHelpers( jClass ); + } + // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- @@ -753,6 +763,8 @@ else if ( "Date".equals( type ) ) else if ( "DOM".equals( type ) ) { sc.add( objectName + "." + setterName + "( writeElementToXpp3Dom( " + childElementName + " ) );" ); + + requiresDomSupport = true; } else { @@ -907,48 +919,6 @@ private void writeHelpers( JClass jClass ) // -------------------------------------------------------------------- - method = new JMethod( "writeElementToXpp3Dom", new JClass( "Xpp3Dom" ), null ); - method.getModifiers().makePrivate(); - - method.addParameter( new JParameter( new JClass( "Element" ), "element" ) ); - - 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.addMethod( method ); - - // -------------------------------------------------------------------- - method = new JMethod( "checkFieldWithDuplicate", JType.BOOLEAN, null ); method.getModifiers().makePrivate(); @@ -998,6 +968,49 @@ private void writeHelpers( JClass jClass ) jClass.addMethod( method ); } + private void writeDomHelpers( JClass jClass ) + { + JMethod method = new JMethod( "writeElementToXpp3Dom", new JClass( "Xpp3Dom" ), null ); + method.getModifiers().makePrivate(); + + method.addParameter( new JParameter( new 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.addMethod( method ); + } + private JMethod convertNumericalType( String methodName, JType returnType, String expression, String typeDesc ) { JMethod method = new JMethod( methodName, returnType, null ); diff --git a/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jWriterGenerator.java b/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jWriterGenerator.java index 41052018d..6c129e039 100644 --- a/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jWriterGenerator.java +++ b/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jWriterGenerator.java @@ -54,11 +54,16 @@ public class Dom4jWriterGenerator extends AbstractXmlJavaGenerator { + + private boolean requiresDomSupport; + public void generate( Model model, Properties parameters ) throws ModelloException { initialize( model, parameters ); + requiresDomSupport = false; + try { generateDom4jWriter(); @@ -90,7 +95,6 @@ private void generateDom4jWriter() jClass.addImport( "java.util.Iterator" ); jClass.addImport( "java.util.Locale" ); jClass.addImport( "java.text.DateFormat" ); - jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); jClass.addImport( "org.dom4j.Document" ); jClass.addImport( "org.dom4j.DocumentException" ); jClass.addImport( "org.dom4j.DocumentFactory" ); @@ -133,7 +137,11 @@ private void generateDom4jWriter() writeAllClasses( objectModel, jClass ); - writeHelpers( jClass ); + if ( requiresDomSupport ) + { + jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); + writeDomHelpers( jClass ); + } jClass.print( sourceWriter ); @@ -398,6 +406,8 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, if ( "DOM".equals( field.getType() ) ) { sc.add( "writeXpp3DomToElement( (Xpp3Dom) " + value + ", element );" ); + + requiresDomSupport = true; } else { @@ -410,7 +420,7 @@ private void processField( ModelField field, XmlFieldMetadata xmlFieldMetadata, } } - private void writeHelpers( JClass jClass ) + private void writeDomHelpers( JClass jClass ) { JMethod method = new JMethod( "writeXpp3DomToElement" ); method.getModifiers().makePrivate(); diff --git a/modello-plugins/modello-plugin-jdom/src/main/java/org/codehaus/modello/plugin/jdom/JDOMWriterGenerator.java b/modello-plugins/modello-plugin-jdom/src/main/java/org/codehaus/modello/plugin/jdom/JDOMWriterGenerator.java index d2c418a00..85b603631 100644 --- a/modello-plugins/modello-plugin-jdom/src/main/java/org/codehaus/modello/plugin/jdom/JDOMWriterGenerator.java +++ b/modello-plugins/modello-plugin-jdom/src/main/java/org/codehaus/modello/plugin/jdom/JDOMWriterGenerator.java @@ -46,10 +46,15 @@ public class JDOMWriterGenerator extends AbstractJDOMGenerator { + private boolean requiresDomSupport; + public void generate( Model model, Properties parameters ) throws ModelloException { initialize( model, parameters ); + + requiresDomSupport = false; + try { generateJDOMWriter(); @@ -98,7 +103,6 @@ private void generateJDOMWriter() 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 ); @@ -127,7 +131,15 @@ private void generateJDOMWriter() jClass.addMethods( generateUtilityMethods() ); writeAllClasses( objectModel, jClass, rootClass ); + + if ( requiresDomSupport ) + { + jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); + jClass.addMethods( generateDomMethods() ); + } + jClass.print( sourceWriter ); + sourceWriter.close(); } @@ -486,13 +498,18 @@ private JMethod[] generateUtilityMethods() sc.add( "}" ); sc.add( "return element;" ); + return new JMethod[] { findRSElement, updateElement, insAtPref, findRSProps, findRSLists }; + } + + private JMethod[] generateDomMethods() + { 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(); + JSourceCode 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 )" ); @@ -568,7 +585,7 @@ private JMethod[] generateUtilityMethods() sc.addIndented( "parent.setText( parentDom.getValue() );" ); sc.add( "}" ); - return new JMethod[]{findRSElement, updateElement, insAtPref, findRSProps, findRSLists, findRSDom, findRSDom2}; + return new JMethod[] { findRSDom, findRSDom2 }; } private void writeAllClasses( Model objectModel, JClass jClass, ModelClass rootClass ) @@ -693,6 +710,8 @@ private void updateClass( ModelClass clazz, JClass jClass, List alwa { sc.add( "findAndReplaceXpp3DOM( innerCount, root, \"" + fieldTagName + "\", (Xpp3Dom) " + value + " );" ); + + requiresDomSupport = true; } else { diff --git a/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java b/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java index d5ffec483..9c6998d93 100644 --- a/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java +++ b/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java @@ -56,11 +56,16 @@ public class StaxReaderGenerator extends AbstractStaxGenerator { + + private boolean requiresDomSupport; + public void generate( Model model, Properties parameters ) throws ModelloException { initialize( model, parameters ); + requiresDomSupport = false; + try { generateStaxReader(); @@ -119,7 +124,6 @@ private void generateStaxReader() jClass.addImport( "java.util.regex.Pattern" ); jClass.addImport( "java.util.Locale" ); jClass.addImport( "javax.xml.stream.*" ); - jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); addModelImports( jClass, null ); @@ -266,7 +270,11 @@ private void generateStaxReader() writeHelpers( jClass ); - writeBuildDomMethod( jClass ); + if ( requiresDomSupport ) + { + jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); + writeBuildDomMethod( jClass ); + } // ---------------------------------------------------------------------- // @@ -1411,6 +1419,8 @@ else if ( "Date".equals( type ) ) else if ( "DOM".equals( type ) ) { sc.add( objectName + "." + setterName + "( buildDom( xmlStreamReader ) );" ); + + requiresDomSupport = true; } else { diff --git a/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxWriterGenerator.java b/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxWriterGenerator.java index fc0de2d16..fe5ab885e 100644 --- a/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxWriterGenerator.java +++ b/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxWriterGenerator.java @@ -55,6 +55,8 @@ public class StaxWriterGenerator extends AbstractStaxGenerator { + private boolean requiresDomSupport; + private StaxSerializerGenerator serializerGenerator; public void generate( Model model, Properties parameters ) @@ -62,6 +64,8 @@ public void generate( Model model, Properties parameters ) { initialize( model, parameters ); + requiresDomSupport = false; + try { generateStaxWriter(); @@ -99,7 +103,6 @@ private void generateStaxWriter() jClass.addImport( "java.util.Locale" ); jClass.addImport( "java.util.jar.Manifest" ); jClass.addImport( "javax.xml.stream.*" ); - jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); addModelImports( jClass, null ); @@ -162,10 +165,14 @@ private void generateStaxWriter() jClass.addMethod( marshall ); - createWriteDomMethod( jClass ); - writeAllClasses( objectModel, jClass ); + if ( requiresDomSupport ) + { + jClass.addImport( "org.codehaus.plexus.util.xml.Xpp3Dom" ); + createWriteDomMethod( jClass ); + } + jClass.print( sourceWriter ); sourceWriter.close(); @@ -472,6 +479,8 @@ private void writeClass( ModelClass modelClass, JClass jClass ) if ( "DOM".equals( field.getType() ) ) { sc.add( "writeDom( (Xpp3Dom) " + value + ", serializer );" ); + + requiresDomSupport = true; } else { diff --git a/modello-plugins/modello-plugin-stax/src/test/java/org/codehaus/modello/generator/xml/stax/FeaturesStaxGeneratorTest.java b/modello-plugins/modello-plugin-stax/src/test/java/org/codehaus/modello/generator/xml/stax/FeaturesStaxGeneratorTest.java index b1d9f805d..f26a59b4d 100644 --- a/modello-plugins/modello-plugin-stax/src/test/java/org/codehaus/modello/generator/xml/stax/FeaturesStaxGeneratorTest.java +++ b/modello-plugins/modello-plugin-stax/src/test/java/org/codehaus/modello/generator/xml/stax/FeaturesStaxGeneratorTest.java @@ -55,7 +55,6 @@ public void testJavaGenerator() addDependency( "stax", "stax-api", "1.0.1" ); addDependency( "org.codehaus.woodstox", "wstx-asl", "3.2.0" ); - addDependency( "net.java.dev.stax-utils", "stax-utils", "20060502" ); addDependency( "xmlunit", "xmlunit", "1.2" ); compileGeneratedSources(); From b8ed0efd2902e9a880ef6c75db4cdce405349925 Mon Sep 17 00:00:00 2001 From: bentmann Date: Sun, 18 Apr 2010 17:56:18 +0000 Subject: [PATCH 09/10] o Extended documentation --- .../maven/ModelloXpp3ExtendedReaderMojo.java | 3 +- .../plugin/java/JavaModelloGenerator.java | 21 +++- src/site/apt/location-tracking.apt | 111 ++++++++++++++++++ src/site/site.xml | 1 + 4 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 src/site/apt/location-tracking.apt diff --git a/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java b/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java index 3246cf412..f5694b7a4 100644 --- a/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java +++ b/modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXpp3ExtendedReaderMojo.java @@ -23,7 +23,8 @@ */ /** - * Creates an XPP3 extended reader from the model. + * Creates an XPP3 extended reader from the model. An extended reader populates the parsed model with metadata about the + * line/column from which the data was read. * * @goal xpp3-extended-reader * 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 41c2ddcf5..30c4c64db 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 @@ -44,6 +44,7 @@ import org.codehaus.modello.plugin.java.javasource.JClass; import org.codehaus.modello.plugin.java.javasource.JCollectionType; import org.codehaus.modello.plugin.java.javasource.JConstructor; +import org.codehaus.modello.plugin.java.javasource.JDocDescriptor; import org.codehaus.modello.plugin.java.javasource.JField; import org.codehaus.modello.plugin.java.javasource.JInterface; import org.codehaus.modello.plugin.java.javasource.JMethod; @@ -725,12 +726,17 @@ private String generateLocationTracker( Model objectModel, ModelClass locationCl suppressAllWarnings( objectModel, jInterface ); JMethodSignature jMethod = new JMethodSignature( "get" + propertyName, new JType( locationClass.getName() ) ); - jMethod.addParameter( new JParameter( new JType( "Object" ), "field" ) ); + jMethod.setComment( "Gets the location of the specified field in the input source." ); + addParameter( jMethod, "Object", "field", "The key of the field, must not be null." ); + String returnDoc = "The location of the field in the input source or null if unknown."; + jMethod.getJDocComment().addDescriptor( JDocDescriptor.createReturnDesc( returnDoc ) ); jInterface.addMethod( jMethod ); jMethod = new JMethodSignature( "set" + propertyName, null ); - jMethod.addParameter( new JParameter( new JType( "Object" ), "field" ) ); - jMethod.addParameter( new JParameter( new JType( locationClass.getName() ), singular( locationField ) ) ); + jMethod.setComment( "Sets the location of the specified field." ); + addParameter( jMethod, "Object", "field", "The key of the field, must not be null." ); + addParameter( jMethod, locationClass.getName(), singular( locationField ), + "The location of the field, may be null." ); jInterface.addMethod( jMethod ); jInterface.print( sourceWriter ); @@ -808,6 +814,7 @@ private void generateLocationBean( JClass jClass, ModelClass locationClass, Mode // int lineNumber; ModelField lineNumber = new ModelField( locationClass, "lineNumber" ); + lineNumber.setDescription( "The one-based line number. The value will be non-positive if unknown." ); lineNumber.setType( "int" ); lineNumber.setDefaultValue( "-1" ); lineNumber.addMetadata( readOnlyField ); @@ -815,6 +822,7 @@ private void generateLocationBean( JClass jClass, ModelClass locationClass, Mode // int columnNumber; ModelField columnNumber = new ModelField( locationClass, "columnNumber" ); + columnNumber.setDescription( "The one-based column number. The value will be non-positive if unknown." ); columnNumber.setType( "int" ); columnNumber.setDefaultValue( "-1" ); columnNumber.addMetadata( readOnlyField ); @@ -1762,4 +1770,11 @@ else if ( useTo ) return type; } + + private void addParameter( JMethodSignature jMethod, String type, String name, String comment ) + { + jMethod.addParameter( new JParameter( new JType( type ), name ) ); + jMethod.getJDocComment().getParamDescriptor( name ).setDescription( comment ); + } + } diff --git a/src/site/apt/location-tracking.apt b/src/site/apt/location-tracking.apt new file mode 100644 index 000000000..412b233db --- /dev/null +++ b/src/site/apt/location-tracking.apt @@ -0,0 +1,111 @@ + ------ + Location Tracking + ------ + Benjamin Bentmann + ------ + 2010-04-18 + ------ + +Location Tracking + + Starting with Modello 1.4, some parsers (currently only XPP3) support the tracking of line/column information for the + input data. This means that additional metadata is stored in the model that can be used to query the location of some + model element in the input source, e.g. for means of better error reporting to the user. + + To store the line/column information, one class of the model has to be specifically attributed: + ++----+ + + Location + 1.0.0+ + + + + ++----+ + + The attribute <<>> in the snippet above signals to Modello that this class should be used to record + line/column metadata during parsing. The class can be modelled as usual but the fields to save the line and column + number along with their accessors are automatically generated by Modello. + + All other model classes will be equipped with a field to hold instances of the <<>> class and accessors to + query them. This way, each model class keeps track of the input locations for its fields: + ++----+ +public class Model +{ + + private Map locations; + + public Location getLocation( Object field ) + { + return ( locations != null ) ? locations.get( field ) : null; + } + + [...] + +} ++----+ + + The location map shown above is keyed by field name. An empty string is used to query the location of the bean + itself (or its text contents). For collections or maps, the returned <<>> instance can be further queried + for its items. The key to query an item depends on the type of collection. For lists the zero-based index is used, + for sets the item itself is used and for maps/properties the mapping key is used. For example, consider this input + XML: + ++----+ + + hello + + list + + + set + + + value + + ++----+ + + For this data model, one could query the location metadata like this (neglecting null checking): + ++----+ +Model model = ; + +// to query the location of the element itself +Location location1 = model.getLocation( "" ); + +// to query the location of the contents of , i.e. "hello" +Location location2 = model.getLocation( "someString" ); + +// to query the location of the first list item, i.e. "list" +Location location3 = model.getLocation( "listItems" ).getLocation( Integer.valueOf( 0 ) ); + +// to query the location of the set item, i.e. "set" +Location location4 = model.getLocation( "setItems" ).getLocation( "set" ); + +// to query the location of the properties data, i.e. "value" +Location location5 = model.getLocation( "properties" ).getLocation( "key" ); ++----+ + + For performance reasons, generation of location metadata during parsing has to be explicitly requested. Usually, this + means to use an reader instead of the normal reader generated by Modello. + + Occasionally, just tracking the line/column number is not enough but the input file of the model needs to be recorded + as well. For this reason, another class of the model can be marked as a source tracker: + ++----+ + + Source + 1.0.0+ + + + + ++----+ + + The fields of this source tracking class are entirely up to the application, Modello will merely extend the generated + <<>> class to support a reference to the <<>> class. An instance of the source tracking class can + be provided to the extended readers which will then use it to populate all the generated <<>> instances. + diff --git a/src/site/site.xml b/src/site/site.xml index 27de950ec..83a289f44 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -31,6 +31,7 @@ + From f03cc573db02db198b90616ca6621c6a0d613be8 Mon Sep 17 00:00:00 2001 From: bentmann Date: Mon, 19 Apr 2010 10:21:37 +0000 Subject: [PATCH 10/10] o Merged r1453-r1457 from trunk --- .../plugin/dom4j/Dom4jReaderGenerator.java | 38 ++++++++++ .../plugin/stax/StaxReaderGenerator.java | 37 ++++++++++ pom.xml | 70 +++++++++++++++---- src/site/xdoc/index.xml | 9 +-- 4 files changed, 132 insertions(+), 22 deletions(-) diff --git a/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java b/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java index 2d270f22d..9f64a1dd9 100644 --- a/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java +++ b/modello-plugins/modello-plugin-dom4j/src/main/java/org/codehaus/modello/plugin/dom4j/Dom4jReaderGenerator.java @@ -88,6 +88,7 @@ private void generateDom4jReader() initHeader( jClass ); suppressAllWarnings( objectModel, jClass ); + jClass.addImport( "java.io.InputStream" ); jClass.addImport( "java.io.IOException" ); jClass.addImport( "java.io.Reader" ); jClass.addImport( "java.net.URL" ); @@ -174,6 +175,43 @@ private void generateDom4jReader() jClass.addMethod( unmarshall ); + // ---------------------------------------------------------------------- + // Write the read(InputStream[,boolean]) methods which will do the unmarshalling. + // ---------------------------------------------------------------------- + + unmarshall = new JMethod( "read", rootType, null ); + + unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "stream" ) ); + unmarshall.addParameter( new JParameter( JType.BOOLEAN, "strict" ) ); + + unmarshall.addException( new JClass( "IOException" ) ); + unmarshall.addException( new 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.addMethod( unmarshall ); + + // ---------------------------------------------------------------------- + + unmarshall = new JMethod( "read", rootType, null ); + + unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "stream" ) ); + + unmarshall.addException( new JClass( "IOException" ) ); + unmarshall.addException( new JClass( "DocumentException" ) ); + + sc = unmarshall.getSourceCode(); + + sc.add( "return read( stream, true );" ); + + jClass.addMethod( unmarshall ); + // ---------------------------------------------------------------------- // Write the read(URL[,boolean]) methods which will do the unmarshalling. // ---------------------------------------------------------------------- diff --git a/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java b/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java index 9c6998d93..f3e5319f3 100644 --- a/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java +++ b/modello-plugins/modello-plugin-stax/src/main/java/org/codehaus/modello/plugin/stax/StaxReaderGenerator.java @@ -114,6 +114,7 @@ private void generateStaxReader() jClass.addImport( "java.io.Reader" ); jClass.addImport( "java.io.File" ); jClass.addImport( "java.io.FileInputStream" ); + jClass.addImport( "java.io.InputStream" ); jClass.addImport( "java.io.StringWriter" ); jClass.addImport( "java.io.StringReader" ); jClass.addImport( "java.io.ByteArrayInputStream" ); @@ -209,6 +210,42 @@ private void generateStaxReader() jClass.addMethod( unmarshall ); + // ---------------------------------------------------------------------- + // Write the read(InputStream[,boolean]) methods which will do the unmarshalling. + // ---------------------------------------------------------------------- + + unmarshall = new JMethod( "read", rootType, null ); + + unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "stream" ) ); + unmarshall.addParameter( new JParameter( JType.BOOLEAN, "strict" ) ); + + unmarshall.addException( new JClass( "IOException" ) ); + unmarshall.addException( new JClass( "XMLStreamException" ) ); + + sc = unmarshall.getSourceCode(); + + sc.add( "XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader( stream );" ); + + sc.add( "" ); + + sc.add( "return read( xmlStreamReader, strict );" ); + + jClass.addMethod( unmarshall ); + + // ---------------------------------------------------------------------- + + unmarshall = new JMethod( "read", rootType, null ); + + unmarshall.addParameter( new JParameter( new JClass( "InputStream" ), "stream" ) ); + + unmarshall.addException( new JClass( "IOException" ) ); + unmarshall.addException( new JClass( "XMLStreamException" ) ); + + sc = unmarshall.getSourceCode(); + sc.add( "return read( stream, true );" ); + + jClass.addMethod( unmarshall ); + // ---------------------------------------------------------------------- // Write the read(String[,boolean]) methods which will do the unmarshalling. // ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index c476837f8..c49213e23 100644 --- a/pom.xml +++ b/pom.xml @@ -334,17 +334,6 @@ - - - - false - - codehaus-snapshots - Codehaus Snapshot Development Repository - http://snapshots.repository.codehaus.org/ - - - @@ -356,6 +345,11 @@ + + org.apache.maven.plugins + maven-assembly-plugin + 2.2-beta-5 + org.apache.maven.plugins maven-clean-plugin @@ -375,6 +369,11 @@ maven-deploy-plugin 2.5 + + org.apache.maven.plugins + maven-gpg-plugin + 1.0 + org.apache.maven.plugins maven-install-plugin @@ -406,9 +405,9 @@ true clean install - true + false deploy - -Prelease + -Pmodello-release @@ -450,9 +449,50 @@ - release + modello-release + + maven-assembly-plugin + + + org.apache.apache.resources + apache-source-release-assembly-descriptor + 1.0.2 + + + + + source-release-assembly + package + + single + + + true + + source-release + + gnu + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + ${gpg.passphrase} + + + + sign-artifacts + + sign + + + + org.apache.maven.plugins maven-source-plugin @@ -460,7 +500,7 @@ attach-sources - jar + jar-no-fork diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index 6160e619e..db0aec8b2 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -4,7 +4,7 @@ Codestin Search App - Hervé Boutemy + HervĂ© Boutemy @@ -17,12 +17,7 @@ and documentation.

- - +