mirror of https://github.com/apache/maven.git
o Added new IT plugin to inspect the runtime state of the POM and things like by dumping expression values into a properties file
git-svn-id: https://svn.apache.org/repos/asf/maven/core-integration-testing/trunk@701503 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9827bcae94
commit
800c4e4c1f
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>maven-it-plugins</artifactId>
|
||||
<groupId>org.apache.maven.its.plugins</groupId>
|
||||
<version>2.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>maven-it-plugin-expression</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>Maven Integration Test Plugin :: Expression</name>
|
||||
<description>
|
||||
A test plugin that creates a properties file with the effective values of some user-defined expressions. As such it
|
||||
allows to analyze the runtime state of the POM similar to the Help Plugin.
|
||||
</description>
|
||||
<inceptionYear>2008</inceptionYear>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,171 @@
|
|||
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 org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Creates a properties file with the effective values of some user-defined expressions. Unlike Maven's built-in
|
||||
* expression syntax for interpolation, these expressions use forward slashes to navigate down the object graph and
|
||||
* support access to individual collection/array elements. Furthermore, the result of an expression need not be a scalar
|
||||
* value but can also be a collection/array or a bean-like object (from the Maven model). For example, the expression
|
||||
* "project/dependencies/0" would extract the first project dependency. In more detail, this example expression could
|
||||
* output the following keys to the properties file:
|
||||
*
|
||||
* <pre>
|
||||
* project.dependencies.0.groupId = org.apache.maven
|
||||
* project.dependencies.0.artifactId = maven-project
|
||||
* project.dependencies.0.type = jar
|
||||
* project.dependencies.0.version = 2.0
|
||||
* project.dependencies.0.optional = false
|
||||
* project.dependencies.0.exclusions = 2
|
||||
* project.dependencies.0.exclusions.0.groupId = plexus
|
||||
* project.dependencies.0.exclusions.0.artifactId = plexus-utils
|
||||
* project.dependencies.0.exclusions.1.groupId = plexus
|
||||
* project.dependencies.0.exclusions.1.artifactId = plexus-container-default
|
||||
* </pre>
|
||||
*
|
||||
* Expressions that reference non-existing objects or use invalid collection/array indices silently resolve to
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @goal eval
|
||||
* @phase initialize
|
||||
*
|
||||
* @author Benjamin Bentmann
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EvalMojo
|
||||
extends AbstractMojo
|
||||
{
|
||||
|
||||
/**
|
||||
* The path to the output file for the properties with the expression values. For each expression given by the
|
||||
* parameter {@link #expressions} an similar named properties key will be used to save the expression value. If an
|
||||
* expression evaluated to <code>null</code>, there will be no corresponding key in the properties file.
|
||||
*
|
||||
* @parameter expression="${expression.outputFile}" default-value="${project.build.directory}/expression.properties"
|
||||
*/
|
||||
private File outputFile;
|
||||
|
||||
/**
|
||||
* The set of expressions to evaluate.
|
||||
*
|
||||
* @parameter
|
||||
*/
|
||||
private String[] expressions;
|
||||
|
||||
/**
|
||||
* The comma separated set of expressions to evaluate.
|
||||
*
|
||||
* @parameter expression="${expression.expressions}"
|
||||
*/
|
||||
private String expressionList;
|
||||
|
||||
/**
|
||||
* The current Maven project against which expressions are evaluated.
|
||||
*
|
||||
* @parameter default-value="${project}"
|
||||
* @readonly
|
||||
*/
|
||||
private Object project;
|
||||
|
||||
/**
|
||||
* The merged user/global settings of the current build against which expressions are evaluated.
|
||||
*
|
||||
* @parameter default-value="${settings}"
|
||||
* @readonly
|
||||
*/
|
||||
private Object settings;
|
||||
|
||||
/**
|
||||
* The session context of the current build against which expressions are evaluated.
|
||||
*
|
||||
* @parameter default-value="${session}"
|
||||
* @readonly
|
||||
*/
|
||||
private Object session;
|
||||
|
||||
/**
|
||||
* The local repository of the current build against which expressions are evaluated.
|
||||
*
|
||||
* @parameter default-value="${localRepository}"
|
||||
* @readonly
|
||||
*/
|
||||
private Object localRepository;
|
||||
|
||||
/**
|
||||
* Runs this mojo.
|
||||
*
|
||||
* @throws MojoExecutionException If the output file could not be created.
|
||||
* @throws MojoFailureException If the output file has not been set.
|
||||
*/
|
||||
public void execute()
|
||||
throws MojoExecutionException, MojoFailureException
|
||||
{
|
||||
if ( outputFile == null )
|
||||
{
|
||||
throw new MojoFailureException( "Path name for output file has not been specified" );
|
||||
}
|
||||
|
||||
getLog().info( "[MAVEN-CORE-IT-LOG] Creating output file: " + outputFile );
|
||||
|
||||
Properties expressionProperties = new Properties();
|
||||
|
||||
if ( expressionList != null && expressionList.length() > 0 )
|
||||
{
|
||||
expressions = expressionList.split( "," );
|
||||
}
|
||||
if ( expressions != null && expressions.length > 0 )
|
||||
{
|
||||
Map contexts = new HashMap();
|
||||
contexts.put( "project", project );
|
||||
contexts.put( "pom", project );
|
||||
contexts.put( "settings", settings );
|
||||
contexts.put( "session", session );
|
||||
contexts.put( "localRepository", localRepository );
|
||||
|
||||
for ( int i = 0; i < expressions.length; i++ )
|
||||
{
|
||||
Object value = ExpressionUtil.evaluate( expressions[i], contexts );
|
||||
PropertyUtil.store( expressionProperties, expressions[i].replace( '/', '.' ), value );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PropertyUtil.write( expressionProperties, outputFile );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
throw new MojoExecutionException( "Output file could not be created: " + outputFile, e );
|
||||
}
|
||||
|
||||
getLog().info( "[MAVEN-CORE-IT-LOG] Created output file: " + outputFile );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
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.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Assists in evaluating expressions.
|
||||
*
|
||||
* @author Benjamin Bentmann
|
||||
* @version $Id$
|
||||
*/
|
||||
class ExpressionUtil
|
||||
{
|
||||
|
||||
private static final Object[] NO_ARGS = {};
|
||||
|
||||
private static final Class[] NO_PARAMS = {};
|
||||
|
||||
private static final Class[] OBJECT_PARAM = { Object.class };
|
||||
|
||||
private static final Class[] STRING_PARAM = { String.class };
|
||||
|
||||
/**
|
||||
* Evaluates the specified expression. Expressions are composed of segments which are separated by a forward slash
|
||||
* ('/'). Each segment specifies a (public) bean property of the current object and drives the evaluation further
|
||||
* down the object graph. For lists, arrays and maps segments can additionally specify the index/key of an element.
|
||||
* The initial segment denotes the root object and the parameter <code>contexts</code> is used to specify which
|
||||
* root objects are available. For instance, if <code>contexts</code> maps the token "project" to a Maven project
|
||||
* instance, the expression "project/build/resources/0/directory" specifies the first resource directory of the
|
||||
* project.
|
||||
*
|
||||
* @param expression The expression to evaluate, may be <code>null</code>.
|
||||
* @param contexts The possible root objects for the expression evaluation, indexed by their identifying token, must
|
||||
* not be <code>null</code>.
|
||||
* @return The value of the expression or <code>null</code> if the expression could not be evaluated.
|
||||
*/
|
||||
public static Object evaluate( String expression, Map contexts )
|
||||
{
|
||||
Object value = null;
|
||||
|
||||
if ( expression != null && expression.length() > 0 )
|
||||
{
|
||||
List segments = Arrays.asList( expression.split( "/", 0 ) );
|
||||
if ( !segments.isEmpty() )
|
||||
{
|
||||
Object context = contexts.get( segments.get( 0 ) );
|
||||
if ( context != null )
|
||||
{
|
||||
value = evaluate( context, segments.subList( 1, segments.size() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given expression segments against the specified object.
|
||||
*
|
||||
* @param context The object to evaluate the segments against, may be <code>null</code>.
|
||||
* @param segments The expression segments to evaluate, must not be <code>null</code>.
|
||||
* @return The value of the evaluation or <code>null</code> if the segments could not be evaluated.
|
||||
*/
|
||||
private static Object evaluate( Object context, List segments )
|
||||
{
|
||||
Object value = null;
|
||||
|
||||
if ( segments.isEmpty() )
|
||||
{
|
||||
value = context;
|
||||
}
|
||||
else if ( context != null )
|
||||
{
|
||||
Object target = null;
|
||||
String segment = (String) segments.get( 0 );
|
||||
if ( segment.length() <= 0 )
|
||||
{
|
||||
value = context;
|
||||
}
|
||||
else if ( context.getClass().isArray() && Character.isDigit( segment.charAt( 0 ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
int index = Integer.parseInt( segment );
|
||||
target = Array.get( context, index );
|
||||
}
|
||||
catch ( RuntimeException e )
|
||||
{
|
||||
// invalid index, just ignore
|
||||
}
|
||||
}
|
||||
else if ( ( context instanceof List ) && Character.isDigit( segment.charAt( 0 ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
int index = Integer.parseInt( segment );
|
||||
target = ( (List) context ).get( index );
|
||||
}
|
||||
catch ( RuntimeException e )
|
||||
{
|
||||
// invalid index, just ignore
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target = getProperty( context, segment );
|
||||
}
|
||||
value = evaluate( target, segments.subList( 1, segments.size() ) );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a (public) bean property from the specified object.
|
||||
*
|
||||
* @param context The object whose bean property should be retrieved, must not be <code>null</code>.
|
||||
* @param property The name of the bean property, must not be <code>null</code>.
|
||||
* @return The value of the bean property or <code>null</code> if the property does not exist.
|
||||
*/
|
||||
static Object getProperty( Object context, String property )
|
||||
{
|
||||
Object value;
|
||||
|
||||
Class type = context.getClass();
|
||||
if ( context instanceof Collection )
|
||||
{
|
||||
type = Collection.class;
|
||||
}
|
||||
else if ( context instanceof Map )
|
||||
{
|
||||
type = Map.class;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = type.getMethod( property, NO_PARAMS );
|
||||
value = method.invoke( context, NO_ARGS );
|
||||
}
|
||||
catch ( NoSuchMethodException e )
|
||||
{
|
||||
try
|
||||
{
|
||||
String name = "get" + Character.toUpperCase( property.charAt( 0 ) ) + property.substring( 1 );
|
||||
Method method = type.getMethod( name, NO_PARAMS );
|
||||
value = method.invoke( context, NO_ARGS );
|
||||
}
|
||||
catch ( NoSuchMethodException e1 )
|
||||
{
|
||||
try
|
||||
{
|
||||
String name = "is" + Character.toUpperCase( property.charAt( 0 ) ) + property.substring( 1 );
|
||||
Method method = type.getMethod( name, NO_PARAMS );
|
||||
value = method.invoke( context, NO_ARGS );
|
||||
}
|
||||
catch ( NoSuchMethodException e2 )
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method;
|
||||
try
|
||||
{
|
||||
method = type.getMethod( "get", STRING_PARAM );
|
||||
}
|
||||
catch ( NoSuchMethodException e3 )
|
||||
{
|
||||
method = type.getMethod( "get", OBJECT_PARAM );
|
||||
}
|
||||
value = method.invoke( context, new Object[] { property } );
|
||||
}
|
||||
catch ( NoSuchMethodException e3 )
|
||||
{
|
||||
try
|
||||
{
|
||||
Field field = type.getField( property );
|
||||
value = field.get( context );
|
||||
}
|
||||
catch ( NoSuchFieldException e4 )
|
||||
{
|
||||
if ( "length".equals( property ) && type.isArray() )
|
||||
{
|
||||
value = new Integer( Array.getLength( context ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
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.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Assists in serializing primitives and beans into properties for later inspection/verification.
|
||||
*
|
||||
* @author Benjamin Bentmann
|
||||
* @version $Id$
|
||||
*/
|
||||
class PropertyUtil
|
||||
{
|
||||
|
||||
private static final Object[] NO_ARGS = {};
|
||||
|
||||
/**
|
||||
* Serializes the specified object into the given properties, using the provided key. The object may be a scalar
|
||||
* value like a string or some array/collection/map or a bean.
|
||||
*
|
||||
* @param props The properties to serialize into, must not be <code>null</code>.
|
||||
* @param key The key to use for serialization of the object data, must not be <code>null</code>.
|
||||
* @param obj The object to serialize, may be <code>null</code>.
|
||||
*/
|
||||
public static void store( Properties props, String key, Object obj )
|
||||
{
|
||||
store( props, key, obj, new HashSet() );
|
||||
}
|
||||
|
||||
/**
|
||||
* /** Serializes the specified object into the given properties, using the provided key. The object may be a scalar
|
||||
* value like a string or some array/collection/map or a bean.
|
||||
*
|
||||
* @param props The properties to serialize into, must not be <code>null</code>.
|
||||
* @param key The key to use for serialization of the object data, must not be <code>null</code>.
|
||||
* @param obj The object to serialize, may be <code>null</code>.
|
||||
* @param visited The set/stack of already visited objects, used to detect back references in the object graph, must
|
||||
* not be <code>null</code>.
|
||||
*/
|
||||
private static void store( Properties props, String key, Object obj, Collection visited )
|
||||
{
|
||||
if ( obj != null )
|
||||
{
|
||||
if ( ( obj instanceof String ) || ( obj instanceof Number ) || ( obj instanceof Boolean )
|
||||
|| ( obj instanceof File ) )
|
||||
{
|
||||
props.put( key, obj.toString() );
|
||||
}
|
||||
else if ( obj instanceof Collection )
|
||||
{
|
||||
Collection coll = (Collection) obj;
|
||||
props.put( key, Integer.toString( coll.size() ) );
|
||||
int index = 0;
|
||||
for ( Iterator it = coll.iterator(); it.hasNext(); index++ )
|
||||
{
|
||||
Object elem = it.next();
|
||||
store( props, key + "." + index, elem );
|
||||
}
|
||||
}
|
||||
else if ( obj instanceof Map )
|
||||
{
|
||||
Map map = (Map) obj;
|
||||
props.put( key, Integer.toString( map.size() ) );
|
||||
int index = 0;
|
||||
for ( Iterator it = map.entrySet().iterator(); it.hasNext(); index++ )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) it.next();
|
||||
store( props, key + "." + entry.getKey(), entry.getValue() );
|
||||
}
|
||||
}
|
||||
else if ( obj.getClass().isArray() )
|
||||
{
|
||||
int length = Array.getLength( obj );
|
||||
props.put( key, Integer.toString( length ) );
|
||||
for ( int index = 0; index < length; index++ )
|
||||
{
|
||||
Object elem = Array.get( obj, index );
|
||||
store( props, key + "." + index, elem );
|
||||
}
|
||||
}
|
||||
else if ( obj != null && !visited.contains( obj ) )
|
||||
{
|
||||
visited.add( obj );
|
||||
Class type = obj.getClass();
|
||||
Method[] methods = type.getMethods();
|
||||
for ( int i = 0; i < methods.length; i++ )
|
||||
{
|
||||
Method method = methods[i];
|
||||
if ( Modifier.isStatic( method.getModifiers() ) || method.getParameterTypes().length > 0
|
||||
|| !method.getName().matches( "(get|is)\\p{Lu}.*" ) || method.getName().endsWith( "AsMap" )
|
||||
|| Class.class.isAssignableFrom( method.getReturnType() )
|
||||
|| Object.class.equals( method.getReturnType() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Object value = method.invoke( obj, NO_ARGS );
|
||||
store( props, key + "." + getPropertyName( method.getName() ), value, visited );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
// just ignore
|
||||
}
|
||||
}
|
||||
visited.remove( obj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives the bean property name from the specified method for its getter.
|
||||
*
|
||||
* @param methodName The method name of the property's getter, must not be <code>null</code>.
|
||||
* @return The property name, never <code>null</code>.
|
||||
*/
|
||||
static String getPropertyName( String methodName )
|
||||
{
|
||||
String propertyName = methodName;
|
||||
if ( methodName.startsWith( "get" ) && methodName.length() > 3 )
|
||||
{
|
||||
propertyName = Character.toLowerCase( methodName.charAt( 3 ) ) + methodName.substring( 4 );
|
||||
}
|
||||
else if ( methodName.startsWith( "is" ) && methodName.length() > 2 )
|
||||
{
|
||||
propertyName = Character.toLowerCase( methodName.charAt( 2 ) ) + methodName.substring( 3 );
|
||||
}
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified properties to the given file.
|
||||
*
|
||||
* @param props The properties to write, must not be <code>null</code>.
|
||||
* @param file The output file for the properties, must not be <code>null</code>.
|
||||
* @throws IOException If the properties could not be written to the file.
|
||||
*/
|
||||
public static void write( Properties props, File file )
|
||||
throws IOException
|
||||
{
|
||||
OutputStream out = null;
|
||||
try
|
||||
{
|
||||
file.getParentFile().mkdirs();
|
||||
out = new FileOutputStream( file );
|
||||
props.store( out, "MAVEN-CORE-IT-LOG" );
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ( out != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
// just ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
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.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Benjamin Bentmann
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ExpressionUtilTest
|
||||
extends TestCase
|
||||
{
|
||||
|
||||
public void testEvaluate()
|
||||
{
|
||||
Object array = new String[] { "one", "two", "three" };
|
||||
Object list = Arrays.asList( new String[] { "0", "-1", "-2" } );
|
||||
Object map = Collections.singletonMap( "some.key", "value" );
|
||||
Object bean = new BeanTwo();
|
||||
|
||||
Map contexts = new HashMap();
|
||||
contexts.put( "array", array );
|
||||
contexts.put( "list", list );
|
||||
contexts.put( "map", map );
|
||||
contexts.put( "bean", bean );
|
||||
|
||||
assertSame( array, ExpressionUtil.evaluate( "array", contexts ) );
|
||||
assertSame( array, ExpressionUtil.evaluate( "array/", contexts ) );
|
||||
assertSame( list, ExpressionUtil.evaluate( "list", contexts ) );
|
||||
assertSame( map, ExpressionUtil.evaluate( "map", contexts ) );
|
||||
assertSame( bean, ExpressionUtil.evaluate( "bean", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "no-root", contexts ) );
|
||||
|
||||
assertEquals( new Integer( 3 ), ExpressionUtil.evaluate( "array/length", contexts ) );
|
||||
assertEquals( "three", ExpressionUtil.evaluate( "array/2", contexts ) );
|
||||
assertEquals( new Integer( 5 ), ExpressionUtil.evaluate( "array/2/length", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "array/invalid", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "array/-1", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "array/999", contexts ) );
|
||||
|
||||
assertEquals( new Integer( 3 ), ExpressionUtil.evaluate( "list/size", contexts ) );
|
||||
assertEquals( "-2", ExpressionUtil.evaluate( "list/2", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "list/invalid", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "list/-1", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "list/999", contexts ) );
|
||||
|
||||
assertEquals( new Integer( 1 ), ExpressionUtil.evaluate( "map/size", contexts ) );
|
||||
assertEquals( "value", ExpressionUtil.evaluate( "map/some.key", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "map/invalid", contexts ) );
|
||||
|
||||
assertEquals( "field", ExpressionUtil.evaluate( "bean/field", contexts ) );
|
||||
assertNull( ExpressionUtil.evaluate( "bean/invalid", contexts ) );
|
||||
assertEquals( "prop", ExpressionUtil.evaluate( "bean/bean/prop", contexts ) );
|
||||
assertEquals( "flag", ExpressionUtil.evaluate( "bean/bean/flag", contexts ) );
|
||||
assertEquals( "arg", ExpressionUtil.evaluate( "bean/bean/arg", contexts ) );
|
||||
}
|
||||
|
||||
public void testGetProperty()
|
||||
{
|
||||
BeanOne bean1 = new BeanOne();
|
||||
BeanTwo bean2 = new BeanTwo();
|
||||
|
||||
assertEquals( bean1.isFlag(), ExpressionUtil.getProperty( bean1, "flag" ) );
|
||||
assertEquals( bean1.getProp(), ExpressionUtil.getProperty( bean1, "prop" ) );
|
||||
assertEquals( bean1.get( "get" ), ExpressionUtil.getProperty( bean1, "get" ) );
|
||||
|
||||
assertNull( ExpressionUtil.getProperty( bean2, "invalid" ) );
|
||||
assertEquals( bean2.field, ExpressionUtil.getProperty( bean2, "field" ) );
|
||||
assertSame( bean2.bean, ExpressionUtil.getProperty( bean2, "bean" ) );
|
||||
|
||||
assertEquals( new Integer( 0 ), ExpressionUtil.getProperty( new String[0], "length" ) );
|
||||
}
|
||||
|
||||
public static class BeanOne
|
||||
{
|
||||
public String isFlag()
|
||||
{
|
||||
return "flag";
|
||||
}
|
||||
|
||||
public String getProp()
|
||||
{
|
||||
return "prop";
|
||||
}
|
||||
|
||||
public String get( String arg )
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BeanTwo
|
||||
{
|
||||
public String field = "field";
|
||||
|
||||
public BeanOne bean = new BeanOne();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
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.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Benjamin Bentmann
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PropertyUtilTest
|
||||
extends TestCase
|
||||
{
|
||||
|
||||
public void testStoreScalar()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
PropertyUtil.store( props, "null", null );
|
||||
PropertyUtil.store( props, "string", "str" );
|
||||
PropertyUtil.store( props, "boolean", Boolean.TRUE );
|
||||
PropertyUtil.store( props, "int", new Integer( 7 ) );
|
||||
PropertyUtil.store( props, "file", new File( "pom.xml" ) );
|
||||
|
||||
assertNull( props.get( "null" ) );
|
||||
assertEquals( "str", props.get( "string" ) );
|
||||
assertEquals( "true", props.get( "boolean" ) );
|
||||
assertEquals( "7", props.get( "int" ) );
|
||||
assertEquals( "pom.xml", props.get( "file" ) );
|
||||
assertEquals( 4, props.size() );
|
||||
}
|
||||
|
||||
public void testStoreArray()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
PropertyUtil.store( props, "arr", new String[] { "one", "two" } );
|
||||
|
||||
assertEquals( "2", props.get( "arr" ) );
|
||||
assertEquals( "one", props.get( "arr.0" ) );
|
||||
assertEquals( "two", props.get( "arr.1" ) );
|
||||
assertEquals( 3, props.size() );
|
||||
}
|
||||
|
||||
public void testStoreList()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
PropertyUtil.store( props, "arr", Arrays.asList( new String[] { "one", "two" } ) );
|
||||
|
||||
assertEquals( "2", props.get( "arr" ) );
|
||||
assertEquals( "one", props.get( "arr.0" ) );
|
||||
assertEquals( "two", props.get( "arr.1" ) );
|
||||
assertEquals( 3, props.size() );
|
||||
}
|
||||
|
||||
public void testStoreMap()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
PropertyUtil.store( props, "map", Collections.singletonMap( "key", "value" ) );
|
||||
|
||||
assertEquals( "1", props.get( "map" ) );
|
||||
assertEquals( "value", props.get( "map.key" ) );
|
||||
assertEquals( 2, props.size() );
|
||||
}
|
||||
|
||||
public void testStoreBean()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
PropertyUtil.store( props, "bean", new Bean() );
|
||||
|
||||
assertEquals( "name", props.get( "bean.name" ) );
|
||||
assertEquals( "false", props.get( "bean.enabled" ) );
|
||||
assertEquals( 2, props.size() );
|
||||
}
|
||||
|
||||
public void testGetPropertyName()
|
||||
{
|
||||
assertEquals( "name", PropertyUtil.getPropertyName( "getName" ) );
|
||||
assertEquals( "enabled", PropertyUtil.getPropertyName( "isEnabled" ) );
|
||||
}
|
||||
|
||||
public static class Bean
|
||||
{
|
||||
public String getName()
|
||||
{
|
||||
return "name";
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "excluded";
|
||||
}
|
||||
|
||||
public Object getUntypedReturnValue()
|
||||
{
|
||||
return "excluded";
|
||||
}
|
||||
|
||||
public Bean getCyclicReference()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -39,6 +39,7 @@ under the License.
|
|||
<module>maven-it-plugin-context-passing</module>
|
||||
<module>maven-it-plugin-core-stubs</module>
|
||||
<module>maven-it-plugin-dependency-resolution</module>
|
||||
<module>maven-it-plugin-expression</module>
|
||||
<module>maven-it-plugin-file</module>
|
||||
<module>maven-it-plugin-fork</module>
|
||||
<module>maven-it-plugin-generate-envar-properties</module>
|
||||
|
|
Loading…
Reference in New Issue