diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/IntegrationTestSuite.java b/its/core-it-suite/src/test/java/org/apache/maven/it/IntegrationTestSuite.java index 5767730777..8e2ee4a697 100644 --- a/its/core-it-suite/src/test/java/org/apache/maven/it/IntegrationTestSuite.java +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/IntegrationTestSuite.java @@ -87,6 +87,7 @@ public class IntegrationTestSuite suite.addTestSuite( MavenITmng4345DefaultPluginExecutionOrderTest.class ); suite.addTestSuite( MavenITmng4344ManagedPluginExecutionOrderTest.class ); + suite.addTestSuite( MavenITmng4342IndependentMojoParameterDefaultValuesTest.class ); suite.addTestSuite( MavenITmng4341PluginExecutionOrderTest.class ); suite.addTestSuite( MavenITmng4338OptionalMojosTest.class ); suite.addTestSuite( MavenITmng4335SettingsOfflineModeTest.class ); diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4342IndependentMojoParameterDefaultValuesTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4342IndependentMojoParameterDefaultValuesTest.java new file mode 100644 index 0000000000..e3553402b2 --- /dev/null +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4342IndependentMojoParameterDefaultValuesTest.java @@ -0,0 +1,65 @@ +package org.apache.maven.it; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.it.Verifier; +import org.apache.maven.it.util.ResourceExtractor; + +import java.io.File; +import java.util.Properties; + +/** + * This is a test set for MNG-4342. + * + * @author Benjamin Bentmann + */ +public class MavenITmng4342IndependentMojoParameterDefaultValuesTest + extends AbstractMavenIntegrationTestCase +{ + + public MavenITmng4342IndependentMojoParameterDefaultValuesTest() + { + super( ALL_MAVEN_VERSIONS ); + } + + /** + * Test that multiple goals within a single execution get their default configuration properly injected. In + * particular, the default values for one goal should not influence the default values of the other goal. + */ + public void testit() + throws Exception + { + File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-4342" ); + + Verifier verifier = new Verifier( testDir.getAbsolutePath() ); + verifier.setAutoclean( false ); + verifier.deleteDirectory( "target" ); + verifier.executeGoal( "validate" ); + verifier.verifyErrorFreeLog(); + verifier.resetStreams(); + + Properties props1 = verifier.loadProperties( "target/config1.properties" ); + assertEquals( "maven-core-it", props1.getProperty( "defaultParam" ) ); + + Properties props2 = verifier.loadProperties( "target/config2.properties" ); + assertEquals( "test", props2.getProperty( "defaultParam" ) ); + } + +} diff --git a/its/core-it-suite/src/test/resources/mng-4342/pom.xml b/its/core-it-suite/src/test/resources/mng-4342/pom.xml new file mode 100644 index 0000000000..0f2d1a4bae --- /dev/null +++ b/its/core-it-suite/src/test/resources/mng-4342/pom.xml @@ -0,0 +1,60 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4342 + test + 0.1 + jar + + Maven Integration Test :: MNG-4342 + + Test that multiple goals within a single execution get their default configuration properly injected. In + particular, the default values for one goal should not influence the default values of the other goal. + + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + + target/config1.properties + target/config2.properties + + + + test + validate + + + config + append-config + + + + + + + diff --git a/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/AppendConfigMojo.java b/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/AppendConfigMojo.java new file mode 100644 index 0000000000..ea63ff3bdb --- /dev/null +++ b/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/AppendConfigMojo.java @@ -0,0 +1,178 @@ +package org.apache.maven.plugin.coreit; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; + +/** + * Appends this mojo's configuration into a properties file. + * + * @goal append-config + * @phase validate + * + * @author Benjamin Bentmann + * @version $Id$ + */ +public class AppendConfigMojo + extends AbstractMojo +{ + + /** + * The current project's base directory, used for path alignment. + * + * @parameter default-value="${basedir}" + * @readonly + */ + private File basedir; + + /** + * The path to the properties file into which to save the mojo configuration. Note: This intentionally uses + * another parameter name for the output file than {@link ConfigMojo}. + * + * @parameter expression="${config.outputFile}" + */ + private File outputFile; + + /** + * A parameter with a constant default value. Note: This has intentionally a different default value than + * the equally named parameter from {@link ConfigMojo}. + * + * @parameter default-value="test" + */ + private String defaultParam; + + /** + * A simple parameter of type {@link java.lang.String}. + * + * @parameter expression="${config.stringParam}" + */ + private String stringParam; + + /** + * A simple parameter of type {@link java.io.File}. + * + * @parameter expression="${config.fileParam}" + */ + private File fileParam; + + /** + * An array parameter of component type {@link java.lang.String}. + * + * @parameter + */ + private String[] stringParams; + + /** + * An array parameter of component type {@link java.io.File}. + * + * @parameter + */ + private File[] fileParams; + + /** + * A collection parameter of type {@link java.util.List}. + * + * @parameter + */ + private List listParam; + + /** + * A collection parameter of type {@link java.util.Set}. + * + * @parameter + */ + private Set setParam; + + /** + * A collection parameter of type {@link java.util.Map}. + * + * @parameter + */ + private Map mapParam; + + /** + * A collection parameter of type {@link java.util.Properties}. + * + * @parameter + */ + private Properties propertiesParam; + + /** + * Runs this mojo. + * + * @throws MojoExecutionException If the output file could not be created. + */ + public void execute() + throws MojoExecutionException + { + getLog().info( "[MAVEN-CORE-IT-LOG] Using output file path: " + outputFile ); + + if ( outputFile == null ) + { + throw new MojoExecutionException( "Path name for output file has not been specified" ); + } + + if ( !outputFile.isAbsolute() ) + { + outputFile = new File( basedir, outputFile.getPath() ).getAbsoluteFile(); + } + + Properties configProps = PropertiesUtil.read( outputFile ); + + dumpConfiguration( configProps ); + + getLog().info( "[MAVEN-CORE-IT-LOG] Creating output file: " + outputFile ); + + PropertiesUtil.write( outputFile, configProps ); + + getLog().info( "[MAVEN-CORE-IT-LOG] Created output file: " + outputFile ); + } + + /** + * Dumps the mojo configuration into the specified properties. + * + * @param props The properties to dump the configuration into, must not be null. + */ + private void dumpConfiguration( Properties props ) + { + /* + * NOTE: This intentionally does not dump the absolute path of a file to check the actual value that was + * injected by Maven. + */ + PropertiesUtil.serialize( props, "propertiesFile", outputFile ); + PropertiesUtil.serialize( props, "defaultParam", defaultParam ); + PropertiesUtil.serialize( props, "stringParam", stringParam ); + PropertiesUtil.serialize( props, "fileParam", fileParam ); + PropertiesUtil.serialize( props, "stringParams", stringParams ); + PropertiesUtil.serialize( props, "fileParams", fileParams ); + PropertiesUtil.serialize( props, "listParam", listParam ); + PropertiesUtil.serialize( props, "setParam", setParam ); + PropertiesUtil.serialize( props, "mapParam", mapParam ); + PropertiesUtil.serialize( props, "propertiesParam", propertiesParam ); + } + +} diff --git a/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/ConfigMojo.java b/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/ConfigMojo.java index c829a24324..8ef4c27f80 100644 --- a/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/ConfigMojo.java +++ b/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/ConfigMojo.java @@ -20,17 +20,9 @@ package org.apache.maven.plugin.coreit; */ import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Array; import java.net.URI; import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.Collection; import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; @@ -278,35 +270,12 @@ public class ConfigMojo } Properties configProps = new Properties(); + dumpConfiguration( configProps ); getLog().info( "[MAVEN-CORE-IT-LOG] Creating output file: " + propertiesFile ); - OutputStream out = null; - try - { - propertiesFile.getParentFile().mkdirs(); - out = new FileOutputStream( propertiesFile ); - configProps.store( out, "MAVEN-CORE-IT-LOG" ); - } - catch ( IOException e ) - { - throw new MojoExecutionException( "Output file could not be created: " + propertiesFile, e ); - } - finally - { - if ( out != null ) - { - try - { - out.close(); - } - catch ( IOException e ) - { - // just ignore - } - } - } + PropertiesUtil.write( propertiesFile, configProps ); getLog().info( "[MAVEN-CORE-IT-LOG] Created output file: " + propertiesFile ); } @@ -322,119 +291,44 @@ public class ConfigMojo * NOTE: This intentionally does not dump the absolute path of a file to check the actual value that was * injected by Maven. */ - dumpValue( props, "propertiesFile", propertiesFile ); - dumpValue( props, "aliasParam", aliasParam ); - dumpValue( props, "defaultParam", defaultParam ); - dumpValue( props, "defaultParamWithExpression", defaultParamWithExpression ); - dumpValue( props, "aliasDefaultExpressionParam", aliasDefaultExpressionParam ); - dumpValue( props, "booleanParam", booleanParam ); + PropertiesUtil.serialize( props, "propertiesFile", propertiesFile ); + PropertiesUtil.serialize( props, "aliasParam", aliasParam ); + PropertiesUtil.serialize( props, "defaultParam", defaultParam ); + PropertiesUtil.serialize( props, "defaultParamWithExpression", defaultParamWithExpression ); + PropertiesUtil.serialize( props, "aliasDefaultExpressionParam", aliasDefaultExpressionParam ); + PropertiesUtil.serialize( props, "booleanParam", booleanParam ); if ( primitiveBooleanParam ) { - dumpValue( props, "primitiveBooleanParam", Boolean.valueOf( primitiveBooleanParam ) ); + PropertiesUtil.serialize( props, "primitiveBooleanParam", Boolean.valueOf( primitiveBooleanParam ) ); } - dumpValue( props, "byteParam", byteParam ); - dumpValue( props, "shortParam", shortParam ); - dumpValue( props, "integerParam", integerParam ); + PropertiesUtil.serialize( props, "byteParam", byteParam ); + PropertiesUtil.serialize( props, "shortParam", shortParam ); + PropertiesUtil.serialize( props, "integerParam", integerParam ); if ( primitiveIntegerParam != 0 ) { - dumpValue( props, "primitiveIntegerParam", new Integer( primitiveIntegerParam ) ); + PropertiesUtil.serialize( props, "primitiveIntegerParam", new Integer( primitiveIntegerParam ) ); } - dumpValue( props, "longParam", longParam ); - dumpValue( props, "floatParam", floatParam ); - dumpValue( props, "doubleParam", doubleParam ); - dumpValue( props, "characterParam", characterParam ); - dumpValue( props, "stringParam", stringParam ); - dumpValue( props, "fileParam", fileParam ); - dumpValue( props, "dateParam", dateParam ); - dumpValue( props, "urlParam", urlParam ); - dumpValue( props, "uriParam", uriParam ); - dumpValue( props, "stringParams", stringParams ); - dumpValue( props, "fileParams", fileParams ); - dumpValue( props, "listParam", listParam ); - dumpValue( props, "setParam", setParam ); - dumpValue( props, "mapParam", mapParam ); - dumpValue( props, "propertiesParam", propertiesParam ); - dumpValue( props, "domParam", domParam ); + PropertiesUtil.serialize( props, "longParam", longParam ); + PropertiesUtil.serialize( props, "floatParam", floatParam ); + PropertiesUtil.serialize( props, "doubleParam", doubleParam ); + PropertiesUtil.serialize( props, "characterParam", characterParam ); + PropertiesUtil.serialize( props, "stringParam", stringParam ); + PropertiesUtil.serialize( props, "fileParam", fileParam ); + PropertiesUtil.serialize( props, "dateParam", dateParam ); + PropertiesUtil.serialize( props, "urlParam", urlParam ); + PropertiesUtil.serialize( props, "uriParam", uriParam ); + PropertiesUtil.serialize( props, "stringParams", stringParams ); + PropertiesUtil.serialize( props, "fileParams", fileParams ); + PropertiesUtil.serialize( props, "listParam", listParam ); + PropertiesUtil.serialize( props, "setParam", setParam ); + PropertiesUtil.serialize( props, "mapParam", mapParam ); + PropertiesUtil.serialize( props, "propertiesParam", propertiesParam ); + PropertiesUtil.serialize( props, "domParam", domParam ); if ( beanParam != null ) { - dumpValue( props, "beanParam.fieldParam", beanParam.fieldParam ); - dumpValue( props, "beanParam.setterParam", beanParam.setterParam ); - dumpValue( props, "beanParam.setterCalled", Boolean.valueOf( beanParam.setterCalled ) ); - } - } - - private void dumpValue( Properties props, String key, Object value ) - { - if ( value != null && value.getClass().isArray() ) - { - props.setProperty( key, Integer.toString( Array.getLength( value ) ) ); - for ( int i = Array.getLength( value ) - 1; i >= 0; i-- ) - { - dumpValue( props, key + "." + i, Array.get( value, i ) ); - } - } - else if ( value instanceof Collection ) - { - Collection collection = (Collection) value; - props.setProperty( key, Integer.toString( collection.size() ) ); - int i = 0; - for ( Iterator it = collection.iterator(); it.hasNext(); i++ ) - { - dumpValue( props, key + "." + i, it.next() ); - } - } - else if ( value instanceof Map ) - { - Map map = (Map) value; - props.setProperty( key, Integer.toString( map.size() ) ); - int i = 0; - for ( Iterator it = map.keySet().iterator(); it.hasNext(); i++ ) - { - Object k = it.next(); - Object v = map.get( k ); - dumpValue( props, key + "." + k, v ); - } - } - else if ( value instanceof PlexusConfiguration ) - { - PlexusConfiguration config = (PlexusConfiguration) value; - - String val = config.getValue( null ); - if ( val != null ) - { - props.setProperty( key + ".value", val ); - } - - String[] attributes = config.getAttributeNames(); - props.setProperty( key + ".attributes", Integer.toString( attributes.length ) ); - for ( int i = attributes.length - 1; i >= 0; i-- ) - { - props.setProperty( key + ".attributes." + attributes[i], config.getAttribute( attributes[i], "" ) ); - } - - PlexusConfiguration children[] = config.getChildren(); - props.setProperty( key + ".children", Integer.toString( children.length ) ); - Map indices = new HashMap(); - for ( int i = 0; i < children.length; i++ ) - { - PlexusConfiguration child = children[i]; - String name = child.getName(); - Integer index = (Integer) indices.get( name ); - if ( index == null ) - { - index = new Integer( 0 ); - } - dumpValue( props, key + ".children." + name + "." + index, child ); - indices.put( name, new Integer( index.intValue() + 1 ) ); - } - } - else if ( value instanceof Date ) - { - props.setProperty( key, new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( (Date) value ) ); - } - else if ( value != null ) - { - props.setProperty( key, value.toString() ); + PropertiesUtil.serialize( props, "beanParam.fieldParam", beanParam.fieldParam ); + PropertiesUtil.serialize( props, "beanParam.setterParam", beanParam.setterParam ); + PropertiesUtil.serialize( props, "beanParam.setterCalled", Boolean.valueOf( beanParam.setterCalled ) ); } } diff --git a/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/PropertiesUtil.java b/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/PropertiesUtil.java new file mode 100644 index 0000000000..db7b026d50 --- /dev/null +++ b/its/core-it-support/core-it-plugins/maven-it-plugin-configuration/src/main/java/org/apache/maven/plugin/coreit/PropertiesUtil.java @@ -0,0 +1,191 @@ +package org.apache.maven.plugin.coreit; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import org.apache.maven.plugin.MojoExecutionException; +import org.codehaus.plexus.configuration.PlexusConfiguration; + +/** + * Assists in handling properties. + * + * @author Benjamin Bentmann + */ +class PropertiesUtil +{ + + public static Properties read( File inputFile ) + throws MojoExecutionException + { + Properties props = new Properties(); + + if ( inputFile.exists() ) + { + InputStream is = null; + try + { + is = new FileInputStream( inputFile ); + props.load( is ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Input file " + inputFile + " could not be read: " + e.getMessage(), + e ); + } + finally + { + if ( is != null ) + { + try + { + is.close(); + } + catch ( IOException e ) + { + // just ignore + } + } + } + } + + return props; + } + + public static void write( File outputFile, Properties props ) + throws MojoExecutionException + { + OutputStream os = null; + try + { + outputFile.getParentFile().mkdirs(); + os = new FileOutputStream( outputFile ); + props.store( os, "MAVEN-CORE-IT-LOG" ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Output file " + outputFile + " could not be created: " + e.getMessage(), + e ); + } + finally + { + if ( os != null ) + { + try + { + os.close(); + } + catch ( IOException e ) + { + // just ignore + } + } + } + } + + public static void serialize( Properties props, String key, Object value ) + { + if ( value != null && value.getClass().isArray() ) + { + props.setProperty( key, Integer.toString( Array.getLength( value ) ) ); + for ( int i = Array.getLength( value ) - 1; i >= 0; i-- ) + { + serialize( props, key + "." + i, Array.get( value, i ) ); + } + } + else if ( value instanceof Collection ) + { + Collection collection = (Collection) value; + props.setProperty( key, Integer.toString( collection.size() ) ); + int i = 0; + for ( Iterator it = collection.iterator(); it.hasNext(); i++ ) + { + serialize( props, key + "." + i, it.next() ); + } + } + else if ( value instanceof Map ) + { + Map map = (Map) value; + props.setProperty( key, Integer.toString( map.size() ) ); + int i = 0; + for ( Iterator it = map.keySet().iterator(); it.hasNext(); i++ ) + { + Object k = it.next(); + Object v = map.get( k ); + serialize( props, key + "." + k, v ); + } + } + else if ( value instanceof PlexusConfiguration ) + { + PlexusConfiguration config = (PlexusConfiguration) value; + + String val = config.getValue( null ); + if ( val != null ) + { + props.setProperty( key + ".value", val ); + } + + String[] attributes = config.getAttributeNames(); + props.setProperty( key + ".attributes", Integer.toString( attributes.length ) ); + for ( int i = attributes.length - 1; i >= 0; i-- ) + { + props.setProperty( key + ".attributes." + attributes[i], config.getAttribute( attributes[i], "" ) ); + } + + PlexusConfiguration children[] = config.getChildren(); + props.setProperty( key + ".children", Integer.toString( children.length ) ); + Map indices = new HashMap(); + for ( int i = 0; i < children.length; i++ ) + { + PlexusConfiguration child = children[i]; + String name = child.getName(); + Integer index = (Integer) indices.get( name ); + if ( index == null ) + { + index = new Integer( 0 ); + } + serialize( props, key + ".children." + name + "." + index, child ); + indices.put( name, new Integer( index.intValue() + 1 ) ); + } + } + else if ( value instanceof Date ) + { + props.setProperty( key, new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( (Date) value ) ); + } + else if ( value != null ) + { + props.setProperty( key, value.toString() ); + } + } + +}