mirror of https://github.com/apache/maven.git
move utils to plexus-utils
git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@164078 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
082bda52a0
commit
bc738a21f4
|
@ -18,10 +18,10 @@ package org.apache.maven.plugin;
|
|||
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.apache.maven.project.path.PathTranslator;
|
||||
import org.apache.maven.util.introspection.ReflectionValueExtractor;
|
||||
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
|
||||
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
||||
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
|
||||
import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.apache.maven.model.Plugin;
|
|||
import org.apache.maven.model.PluginManagement;
|
||||
import org.apache.maven.model.Reports;
|
||||
import org.apache.maven.model.Scm;
|
||||
import org.apache.maven.util.Xpp3DomUtils;
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -739,8 +738,8 @@ public class MavenProject
|
|||
Xpp3Dom goalConfiguration = (Xpp3Dom) goal.getConfiguration();
|
||||
if ( goalConfiguration != null )
|
||||
{
|
||||
Xpp3Dom newDom = Xpp3DomUtils.copyXpp3Dom( goalConfiguration );
|
||||
dom = Xpp3DomUtils.mergeXpp3Dom( newDom, dom );
|
||||
Xpp3Dom newDom = new Xpp3Dom( goalConfiguration );
|
||||
dom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.apache.maven.model.Plugin;
|
|||
import org.apache.maven.model.PluginManagement;
|
||||
import org.apache.maven.model.Repository;
|
||||
import org.apache.maven.model.Scm;
|
||||
import org.apache.maven.util.Xpp3DomUtils;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
|
||||
|
@ -273,7 +272,7 @@ public class DefaultModelInheritanceAssembler
|
|||
{
|
||||
Xpp3Dom childDom = (Xpp3Dom) childGoal.getConfiguration();
|
||||
Xpp3Dom parentDom = (Xpp3Dom) parentGoal.getConfiguration();
|
||||
childGoal.setConfiguration( Xpp3DomUtils.mergeXpp3Dom( childDom, parentDom ) );
|
||||
childGoal.setConfiguration( Xpp3Dom.mergeXpp3Dom( childDom, parentDom ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.apache.maven.model.Goal;
|
|||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.PluginManagement;
|
||||
import org.apache.maven.util.Xpp3DomUtils;
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -123,7 +122,7 @@ public class DefaultModelDefaultsInjector
|
|||
Xpp3Dom goalConfiguration = (Xpp3Dom) localGoal.getConfiguration();
|
||||
Xpp3Dom defaultGoalConfiguration = (Xpp3Dom) defaultGoal.getConfiguration();
|
||||
localGoal.setConfiguration(
|
||||
Xpp3DomUtils.mergeXpp3Dom( goalConfiguration, defaultGoalConfiguration ) );
|
||||
Xpp3Dom.mergeXpp3Dom( goalConfiguration, defaultGoalConfiguration ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +131,7 @@ public class DefaultModelDefaultsInjector
|
|||
|
||||
Xpp3Dom pluginConfiguration = (Xpp3Dom) plugin.getConfiguration();
|
||||
Xpp3Dom defaultPluginConfiguration = (Xpp3Dom) def.getConfiguration();
|
||||
plugin.setConfiguration( Xpp3DomUtils.mergeXpp3Dom( pluginConfiguration, defaultPluginConfiguration ) );
|
||||
plugin.setConfiguration( Xpp3Dom.mergeXpp3Dom( pluginConfiguration, defaultPluginConfiguration ) );
|
||||
}
|
||||
|
||||
private void injectDependencyDefaults( List dependencies, DependencyManagement dependencyManagement )
|
||||
|
|
|
@ -19,10 +19,10 @@ package org.apache.maven.project.interpolation;
|
|||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
|
||||
import org.apache.maven.util.introspection.ReflectionValueExtractor;
|
||||
import org.codehaus.plexus.logging.AbstractLogEnabled;
|
||||
import org.codehaus.plexus.logging.Logger;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
package org.apache.maven.util;
|
||||
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
|
||||
/*
|
||||
* Copyright 2001-2005 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO: describe
|
||||
*
|
||||
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Xpp3DomUtils
|
||||
{
|
||||
private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
|
||||
{
|
||||
// TODO: how to mergeXpp3Dom lists rather than override?
|
||||
// TODO: share this as some sort of assembler, implement a walk interface?
|
||||
if ( recessive == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Xpp3Dom[] children = recessive.getChildren();
|
||||
for ( int i = 0; i < children.length; i++ )
|
||||
{
|
||||
Xpp3Dom child = children[i];
|
||||
Xpp3Dom childDom = dominant.getChild( child.getName() );
|
||||
if ( childDom != null )
|
||||
{
|
||||
mergeIntoXpp3Dom( childDom, child );
|
||||
}
|
||||
else
|
||||
{
|
||||
dominant.addChild( copyXpp3Dom( child ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Xpp3Dom copyXpp3Dom( Xpp3Dom src )
|
||||
{
|
||||
// TODO: into Xpp3Dom as a copy constructor
|
||||
Xpp3Dom dom = new Xpp3Dom( src.getName() );
|
||||
dom.setValue( src.getValue() );
|
||||
|
||||
String[] attributeNames = src.getAttributeNames();
|
||||
for ( int i = 0; i < attributeNames.length; i++ )
|
||||
{
|
||||
String attributeName = attributeNames[i];
|
||||
dom.setAttribute( attributeName, src.getAttribute( attributeName ) );
|
||||
}
|
||||
|
||||
Xpp3Dom[] children = src.getChildren();
|
||||
for ( int i = 0; i < children.length; i++ )
|
||||
{
|
||||
dom.addChild( copyXpp3Dom( children[i] ) );
|
||||
}
|
||||
|
||||
return dom;
|
||||
}
|
||||
|
||||
public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
|
||||
{
|
||||
if ( dominant != null )
|
||||
{
|
||||
mergeIntoXpp3Dom( dominant, recessive );
|
||||
return dominant;
|
||||
}
|
||||
return recessive;
|
||||
}
|
||||
}
|
|
@ -1,520 +0,0 @@
|
|||
package org.apache.maven.util.introspection;
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2001-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A cache of introspection information for a specific class instance.
|
||||
* Keys {@link java.lang.Method} objects by a concatenation of the
|
||||
* method name and the names of classes that make up the parameters.
|
||||
*
|
||||
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
|
||||
* @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
|
||||
* @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
|
||||
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ClassMap
|
||||
{
|
||||
private static final class CacheMiss
|
||||
{
|
||||
}
|
||||
|
||||
private static final CacheMiss CACHE_MISS = new CacheMiss();
|
||||
private static final Object OBJECT = new Object();
|
||||
|
||||
/**
|
||||
* Class passed into the constructor used to as
|
||||
* the basis for the Method map.
|
||||
*/
|
||||
|
||||
private Class clazz;
|
||||
|
||||
/**
|
||||
* Cache of Methods, or CACHE_MISS, keyed by method
|
||||
* name and actual arguments used to find it.
|
||||
*/
|
||||
private Map methodCache = new Hashtable();
|
||||
|
||||
private MethodMap methodMap = new MethodMap();
|
||||
|
||||
/**
|
||||
* Standard constructor
|
||||
*/
|
||||
public ClassMap( Class clazz )
|
||||
{
|
||||
this.clazz = clazz;
|
||||
populateMethodCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the class object whose methods are cached by this map.
|
||||
*/
|
||||
Class getCachedClass()
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a Method using the methodKey
|
||||
* provided.
|
||||
* <p/>
|
||||
* Look in the methodMap for an entry. If found,
|
||||
* it'll either be a CACHE_MISS, in which case we
|
||||
* simply give up, or it'll be a Method, in which
|
||||
* case, we return it.
|
||||
* <p/>
|
||||
* If nothing is found, then we must actually go
|
||||
* and introspect the method from the MethodMap.
|
||||
*/
|
||||
public Method findMethod( String name, Object[] params )
|
||||
throws MethodMap.AmbiguousException
|
||||
{
|
||||
String methodKey = makeMethodKey( name, params );
|
||||
Object cacheEntry = methodCache.get( methodKey );
|
||||
|
||||
if ( cacheEntry == CACHE_MISS )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( cacheEntry == null )
|
||||
{
|
||||
try
|
||||
{
|
||||
cacheEntry = methodMap.find( name,
|
||||
params );
|
||||
}
|
||||
catch ( MethodMap.AmbiguousException ae )
|
||||
{
|
||||
/*
|
||||
* that's a miss :)
|
||||
*/
|
||||
|
||||
methodCache.put( methodKey,
|
||||
CACHE_MISS );
|
||||
|
||||
throw ae;
|
||||
}
|
||||
|
||||
if ( cacheEntry == null )
|
||||
{
|
||||
methodCache.put( methodKey,
|
||||
CACHE_MISS );
|
||||
}
|
||||
else
|
||||
{
|
||||
methodCache.put( methodKey,
|
||||
cacheEntry );
|
||||
}
|
||||
}
|
||||
|
||||
// Yes, this might just be null.
|
||||
|
||||
return (Method) cacheEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the Map of direct hits. These
|
||||
* are taken from all the public methods
|
||||
* that our class provides.
|
||||
*/
|
||||
private void populateMethodCache()
|
||||
{
|
||||
StringBuffer methodKey;
|
||||
|
||||
/*
|
||||
* get all publicly accessible methods
|
||||
*/
|
||||
|
||||
Method[] methods = getAccessibleMethods( clazz );
|
||||
|
||||
/*
|
||||
* map and cache them
|
||||
*/
|
||||
|
||||
for ( int i = 0; i < methods.length; i++ )
|
||||
{
|
||||
Method method = methods[i];
|
||||
|
||||
/*
|
||||
* now get the 'public method', the method declared by a
|
||||
* public interface or class. (because the actual implementing
|
||||
* class may be a facade...
|
||||
*/
|
||||
|
||||
Method publicMethod = getPublicMethod( method );
|
||||
|
||||
/*
|
||||
* it is entirely possible that there is no public method for
|
||||
* the methods of this class (i.e. in the facade, a method
|
||||
* that isn't on any of the interfaces or superclass
|
||||
* in which case, ignore it. Otherwise, map and cache
|
||||
*/
|
||||
|
||||
if ( publicMethod != null )
|
||||
{
|
||||
methodMap.add( publicMethod );
|
||||
methodCache.put( makeMethodKey( publicMethod ), publicMethod );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a methodKey for the given method using
|
||||
* the concatenation of the name and the
|
||||
* types of the method parameters.
|
||||
*/
|
||||
private String makeMethodKey( Method method )
|
||||
{
|
||||
Class[] parameterTypes = method.getParameterTypes();
|
||||
|
||||
StringBuffer methodKey = new StringBuffer( method.getName() );
|
||||
|
||||
for ( int j = 0; j < parameterTypes.length; j++ )
|
||||
{
|
||||
/*
|
||||
* If the argument type is primitive then we want
|
||||
* to convert our primitive type signature to the
|
||||
* corresponding Object type so introspection for
|
||||
* methods with primitive types will work correctly.
|
||||
*/
|
||||
if ( parameterTypes[j].isPrimitive() )
|
||||
{
|
||||
if ( parameterTypes[j].equals( Boolean.TYPE ) )
|
||||
methodKey.append( "java.lang.Boolean" );
|
||||
else if ( parameterTypes[j].equals( Byte.TYPE ) )
|
||||
methodKey.append( "java.lang.Byte" );
|
||||
else if ( parameterTypes[j].equals( Character.TYPE ) )
|
||||
methodKey.append( "java.lang.Character" );
|
||||
else if ( parameterTypes[j].equals( Double.TYPE ) )
|
||||
methodKey.append( "java.lang.Double" );
|
||||
else if ( parameterTypes[j].equals( Float.TYPE ) )
|
||||
methodKey.append( "java.lang.Float" );
|
||||
else if ( parameterTypes[j].equals( Integer.TYPE ) )
|
||||
methodKey.append( "java.lang.Integer" );
|
||||
else if ( parameterTypes[j].equals( Long.TYPE ) )
|
||||
methodKey.append( "java.lang.Long" );
|
||||
else if ( parameterTypes[j].equals( Short.TYPE ) )
|
||||
methodKey.append( "java.lang.Short" );
|
||||
}
|
||||
else
|
||||
{
|
||||
methodKey.append( parameterTypes[j].getName() );
|
||||
}
|
||||
}
|
||||
|
||||
return methodKey.toString();
|
||||
}
|
||||
|
||||
private static String makeMethodKey( String method, Object[] params )
|
||||
{
|
||||
StringBuffer methodKey = new StringBuffer().append( method );
|
||||
|
||||
for ( int j = 0; j < params.length; j++ )
|
||||
{
|
||||
Object arg = params[j];
|
||||
|
||||
if ( arg == null )
|
||||
{
|
||||
arg = OBJECT;
|
||||
}
|
||||
|
||||
methodKey.append( arg.getClass().getName() );
|
||||
}
|
||||
|
||||
return methodKey.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves public methods for a class. In case the class is not
|
||||
* public, retrieves methods with same signature as its public methods
|
||||
* from public superclasses and interfaces (if they exist). Basically
|
||||
* upcasts every method to the nearest acccessible method.
|
||||
*/
|
||||
private static Method[] getAccessibleMethods( Class clazz )
|
||||
{
|
||||
Method[] methods = clazz.getMethods();
|
||||
|
||||
/*
|
||||
* Short circuit for the (hopefully) majority of cases where the
|
||||
* clazz is public
|
||||
*/
|
||||
|
||||
if ( Modifier.isPublic( clazz.getModifiers() ) )
|
||||
{
|
||||
return methods;
|
||||
}
|
||||
|
||||
/*
|
||||
* No luck - the class is not public, so we're going the longer way.
|
||||
*/
|
||||
|
||||
MethodInfo[] methodInfos = new MethodInfo[methods.length];
|
||||
|
||||
for ( int i = methods.length; i-- > 0; )
|
||||
{
|
||||
methodInfos[i] = new MethodInfo( methods[i] );
|
||||
}
|
||||
|
||||
int upcastCount = getAccessibleMethods( clazz, methodInfos, 0 );
|
||||
|
||||
/*
|
||||
* Reallocate array in case some method had no accessible counterpart.
|
||||
*/
|
||||
|
||||
if ( upcastCount < methods.length )
|
||||
{
|
||||
methods = new Method[upcastCount];
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for ( int i = 0; i < methodInfos.length; ++i )
|
||||
{
|
||||
MethodInfo methodInfo = methodInfos[i];
|
||||
if ( methodInfo.upcast )
|
||||
{
|
||||
methods[j++] = methodInfo.method;
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively finds a match for each method, starting with the class, and then
|
||||
* searching the superclass and interfaces.
|
||||
*
|
||||
* @param clazz Class to check
|
||||
* @param methodInfos array of methods we are searching to match
|
||||
* @param upcastCount current number of methods we have matched
|
||||
* @return count of matched methods
|
||||
*/
|
||||
private static int getAccessibleMethods( Class clazz, MethodInfo[] methodInfos, int upcastCount )
|
||||
{
|
||||
int l = methodInfos.length;
|
||||
|
||||
/*
|
||||
* if this class is public, then check each of the currently
|
||||
* 'non-upcasted' methods to see if we have a match
|
||||
*/
|
||||
|
||||
if ( Modifier.isPublic( clazz.getModifiers() ) )
|
||||
{
|
||||
for ( int i = 0; i < l && upcastCount < l; ++i )
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodInfo methodInfo = methodInfos[i];
|
||||
|
||||
if ( !methodInfo.upcast )
|
||||
{
|
||||
methodInfo.tryUpcasting( clazz );
|
||||
upcastCount++;
|
||||
}
|
||||
}
|
||||
catch ( NoSuchMethodException e )
|
||||
{
|
||||
/*
|
||||
* Intentionally ignored - it means
|
||||
* it wasn't found in the current class
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Short circuit if all methods were upcast
|
||||
*/
|
||||
|
||||
if ( upcastCount == l )
|
||||
{
|
||||
return upcastCount;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Examine superclass
|
||||
*/
|
||||
|
||||
Class superclazz = clazz.getSuperclass();
|
||||
|
||||
if ( superclazz != null )
|
||||
{
|
||||
upcastCount = getAccessibleMethods( superclazz, methodInfos, upcastCount );
|
||||
|
||||
/*
|
||||
* Short circuit if all methods were upcast
|
||||
*/
|
||||
|
||||
if ( upcastCount == l )
|
||||
{
|
||||
return upcastCount;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Examine interfaces. Note we do it even if superclazz == null.
|
||||
* This is redundant as currently java.lang.Object does not implement
|
||||
* any interfaces, however nothing guarantees it will not in future.
|
||||
*/
|
||||
|
||||
Class[] interfaces = clazz.getInterfaces();
|
||||
|
||||
for ( int i = interfaces.length; i-- > 0; )
|
||||
{
|
||||
upcastCount = getAccessibleMethods( interfaces[i], methodInfos, upcastCount );
|
||||
|
||||
/*
|
||||
* Short circuit if all methods were upcast
|
||||
*/
|
||||
|
||||
if ( upcastCount == l )
|
||||
{
|
||||
return upcastCount;
|
||||
}
|
||||
}
|
||||
|
||||
return upcastCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given method, retrieves its publicly accessible counterpart.
|
||||
* This method will look for a method with same name
|
||||
* and signature declared in a public superclass or implemented interface of this
|
||||
* method's declaring class. This counterpart method is publicly callable.
|
||||
*
|
||||
* @param method a method whose publicly callable counterpart is requested.
|
||||
* @return the publicly callable counterpart method. Note that if the parameter
|
||||
* method is itself declared by a public class, this method is an identity
|
||||
* function.
|
||||
*/
|
||||
public static Method getPublicMethod( Method method )
|
||||
{
|
||||
Class clazz = method.getDeclaringClass();
|
||||
|
||||
/*
|
||||
* Short circuit for (hopefully the majority of) cases where the declaring
|
||||
* class is public.
|
||||
*/
|
||||
|
||||
if ( ( clazz.getModifiers() & Modifier.PUBLIC ) != 0 )
|
||||
{
|
||||
return method;
|
||||
}
|
||||
|
||||
return getPublicMethod( clazz, method.getName(), method.getParameterTypes() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the method with specified name and signature in the first public
|
||||
* superclass or implemented interface of the class.
|
||||
*
|
||||
* @param class the class whose method is sought
|
||||
* @param name the name of the method
|
||||
* @param paramTypes the classes of method parameters
|
||||
*/
|
||||
private static Method getPublicMethod( Class clazz, String name, Class[] paramTypes )
|
||||
{
|
||||
/*
|
||||
* if this class is public, then try to get it
|
||||
*/
|
||||
|
||||
if ( ( clazz.getModifiers() & Modifier.PUBLIC ) != 0 )
|
||||
{
|
||||
try
|
||||
{
|
||||
return clazz.getMethod( name, paramTypes );
|
||||
}
|
||||
catch ( NoSuchMethodException e )
|
||||
{
|
||||
/*
|
||||
* If the class does not have the method, then neither its
|
||||
* superclass nor any of its interfaces has it so quickly return
|
||||
* null.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* try the superclass
|
||||
*/
|
||||
|
||||
|
||||
Class superclazz = clazz.getSuperclass();
|
||||
|
||||
if ( superclazz != null )
|
||||
{
|
||||
Method superclazzMethod = getPublicMethod( superclazz, name, paramTypes );
|
||||
|
||||
if ( superclazzMethod != null )
|
||||
{
|
||||
return superclazzMethod;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* and interfaces
|
||||
*/
|
||||
|
||||
Class[] interfaces = clazz.getInterfaces();
|
||||
|
||||
for ( int i = 0; i < interfaces.length; ++i )
|
||||
{
|
||||
Method interfaceMethod = getPublicMethod( interfaces[i], name, paramTypes );
|
||||
|
||||
if ( interfaceMethod != null )
|
||||
{
|
||||
return interfaceMethod;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for the iterative discovery process for public methods.
|
||||
*/
|
||||
private static final class MethodInfo
|
||||
{
|
||||
Method method;
|
||||
String name;
|
||||
Class[] parameterTypes;
|
||||
boolean upcast;
|
||||
|
||||
MethodInfo( Method method )
|
||||
{
|
||||
this.method = null;
|
||||
name = method.getName();
|
||||
parameterTypes = method.getParameterTypes();
|
||||
upcast = false;
|
||||
}
|
||||
|
||||
void tryUpcasting( Class clazz )
|
||||
throws NoSuchMethodException
|
||||
{
|
||||
method = clazz.getMethod( name, parameterTypes );
|
||||
name = null;
|
||||
parameterTypes = null;
|
||||
upcast = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,465 +0,0 @@
|
|||
package org.apache.maven.util.introspection;
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2001-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
|
||||
* @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
|
||||
* @author <a href="mailto:Christoph.Reck@dlr.de">Christoph Reck</a>
|
||||
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
|
||||
* @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class MethodMap
|
||||
{
|
||||
private static final int MORE_SPECIFIC = 0;
|
||||
private static final int LESS_SPECIFIC = 1;
|
||||
private static final int INCOMPARABLE = 2;
|
||||
|
||||
/**
|
||||
* Keep track of all methods with the same name.
|
||||
*/
|
||||
Map methodByNameMap = new Hashtable();
|
||||
|
||||
/**
|
||||
* Add a method to a list of methods by name.
|
||||
* For a particular class we are keeping track
|
||||
* of all the methods with the same name.
|
||||
*/
|
||||
public void add(Method method)
|
||||
{
|
||||
String methodName = method.getName();
|
||||
|
||||
List l = get( methodName );
|
||||
|
||||
if ( l == null)
|
||||
{
|
||||
l = new ArrayList();
|
||||
methodByNameMap.put(methodName, l);
|
||||
}
|
||||
|
||||
l.add(method);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of methods with the same name.
|
||||
*
|
||||
* @param String key
|
||||
* @return List list of methods
|
||||
*/
|
||||
public List get(String key)
|
||||
{
|
||||
return (List) methodByNameMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Find a method. Attempts to find the
|
||||
* most specific applicable method using the
|
||||
* algorithm described in the JLS section
|
||||
* 15.12.2 (with the exception that it can't
|
||||
* distinguish a primitive type argument from
|
||||
* an object type argument, since in reflection
|
||||
* primitive type arguments are represented by
|
||||
* their object counterparts, so for an argument of
|
||||
* type (say) java.lang.Integer, it will not be able
|
||||
* to decide between a method that takes int and a
|
||||
* method that takes java.lang.Integer as a parameter.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This turns out to be a relatively rare case
|
||||
* where this is needed - however, functionality
|
||||
* like this is needed.
|
||||
* </p>
|
||||
*
|
||||
* @param methodName name of method
|
||||
* @param args the actual arguments with which the method is called
|
||||
* @return the most specific applicable method, or null if no
|
||||
* method is applicable.
|
||||
* @throws AmbiguousException if there is more than one maximally
|
||||
* specific applicable method
|
||||
*/
|
||||
public Method find(String methodName, Object[] args)
|
||||
throws AmbiguousException
|
||||
{
|
||||
List methodList = get(methodName);
|
||||
|
||||
if (methodList == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int l = args.length;
|
||||
Class[] classes = new Class[l];
|
||||
|
||||
for(int i = 0; i < l; ++i)
|
||||
{
|
||||
Object arg = args[i];
|
||||
|
||||
/*
|
||||
* if we are careful down below, a null argument goes in there
|
||||
* so we can know that the null was passed to the method
|
||||
*/
|
||||
classes[i] =
|
||||
arg == null ? null : arg.getClass();
|
||||
}
|
||||
|
||||
return getMostSpecific(methodList, classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* simple distinguishable exception, used when
|
||||
* we run across ambiguous overloading
|
||||
*/
|
||||
public static class AmbiguousException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private static Method getMostSpecific(List methods, Class[] classes)
|
||||
throws AmbiguousException
|
||||
{
|
||||
LinkedList applicables = getApplicables(methods, classes);
|
||||
|
||||
if(applicables.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(applicables.size() == 1)
|
||||
{
|
||||
return (Method)applicables.getFirst();
|
||||
}
|
||||
|
||||
/*
|
||||
* This list will contain the maximally specific methods. Hopefully at
|
||||
* the end of the below loop, the list will contain exactly one method,
|
||||
* (the most specific method) otherwise we have ambiguity.
|
||||
*/
|
||||
|
||||
LinkedList maximals = new LinkedList();
|
||||
|
||||
for (Iterator applicable = applicables.iterator();
|
||||
applicable.hasNext();)
|
||||
{
|
||||
Method app = (Method) applicable.next();
|
||||
Class[] appArgs = app.getParameterTypes();
|
||||
boolean lessSpecific = false;
|
||||
|
||||
for (Iterator maximal = maximals.iterator();
|
||||
!lessSpecific && maximal.hasNext();)
|
||||
{
|
||||
Method max = (Method) maximal.next();
|
||||
|
||||
switch(moreSpecific(appArgs, max.getParameterTypes()))
|
||||
{
|
||||
case MORE_SPECIFIC:
|
||||
{
|
||||
/*
|
||||
* This method is more specific than the previously
|
||||
* known maximally specific, so remove the old maximum.
|
||||
*/
|
||||
|
||||
maximal.remove();
|
||||
break;
|
||||
}
|
||||
|
||||
case LESS_SPECIFIC:
|
||||
{
|
||||
/*
|
||||
* This method is less specific than some of the
|
||||
* currently known maximally specific methods, so we
|
||||
* won't add it into the set of maximally specific
|
||||
* methods
|
||||
*/
|
||||
|
||||
lessSpecific = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!lessSpecific)
|
||||
{
|
||||
maximals.addLast(app);
|
||||
}
|
||||
}
|
||||
|
||||
if(maximals.size() > 1)
|
||||
{
|
||||
// We have more than one maximally specific method
|
||||
throw new AmbiguousException();
|
||||
}
|
||||
|
||||
return (Method)maximals.getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which method signature (represented by a class array) is more
|
||||
* specific. This defines a partial ordering on the method signatures.
|
||||
* @param c1 first signature to compare
|
||||
* @param c2 second signature to compare
|
||||
* @return MORE_SPECIFIC if c1 is more specific than c2, LESS_SPECIFIC if
|
||||
* c1 is less specific than c2, INCOMPARABLE if they are incomparable.
|
||||
*/
|
||||
private static int moreSpecific(Class[] c1, Class[] c2)
|
||||
{
|
||||
boolean c1MoreSpecific = false;
|
||||
boolean c2MoreSpecific = false;
|
||||
|
||||
for(int i = 0; i < c1.length; ++i)
|
||||
{
|
||||
if(c1[i] != c2[i])
|
||||
{
|
||||
c1MoreSpecific =
|
||||
c1MoreSpecific ||
|
||||
isStrictMethodInvocationConvertible(c2[i], c1[i]);
|
||||
c2MoreSpecific =
|
||||
c2MoreSpecific ||
|
||||
isStrictMethodInvocationConvertible(c1[i], c2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(c1MoreSpecific)
|
||||
{
|
||||
if(c2MoreSpecific)
|
||||
{
|
||||
/*
|
||||
* Incomparable due to cross-assignable arguments (i.e.
|
||||
* foo(String, Object) vs. foo(Object, String))
|
||||
*/
|
||||
|
||||
return INCOMPARABLE;
|
||||
}
|
||||
|
||||
return MORE_SPECIFIC;
|
||||
}
|
||||
|
||||
if(c2MoreSpecific)
|
||||
{
|
||||
return LESS_SPECIFIC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Incomparable due to non-related arguments (i.e.
|
||||
* foo(Runnable) vs. foo(Serializable))
|
||||
*/
|
||||
|
||||
return INCOMPARABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all methods that are applicable to actual argument types.
|
||||
* @param methods list of all candidate methods
|
||||
* @param classes the actual types of the arguments
|
||||
* @return a list that contains only applicable methods (number of
|
||||
* formal and actual arguments matches, and argument types are assignable
|
||||
* to formal types through a method invocation conversion).
|
||||
*/
|
||||
private static LinkedList getApplicables(List methods, Class[] classes)
|
||||
{
|
||||
LinkedList list = new LinkedList();
|
||||
|
||||
for (Iterator imethod = methods.iterator(); imethod.hasNext();)
|
||||
{
|
||||
Method method = (Method) imethod.next();
|
||||
|
||||
if(isApplicable(method, classes))
|
||||
{
|
||||
list.add(method);
|
||||
}
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the supplied method is applicable to actual
|
||||
* argument types.
|
||||
*/
|
||||
private static boolean isApplicable(Method method, Class[] classes)
|
||||
{
|
||||
Class[] methodArgs = method.getParameterTypes();
|
||||
|
||||
if(methodArgs.length != classes.length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < classes.length; ++i)
|
||||
{
|
||||
if(!isMethodInvocationConvertible(methodArgs[i], classes[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a type represented by a class object is
|
||||
* convertible to another type represented by a class object using a
|
||||
* method invocation conversion, treating object types of primitive
|
||||
* types as if they were primitive types (that is, a Boolean actual
|
||||
* parameter type matches boolean primitive formal type). This behavior
|
||||
* is because this method is used to determine applicable methods for
|
||||
* an actual parameter list, and primitive types are represented by
|
||||
* their object duals in reflective method calls.
|
||||
*
|
||||
* @param formal the formal parameter type to which the actual
|
||||
* parameter type should be convertible
|
||||
* @param actual the actual parameter type.
|
||||
* @return true if either formal type is assignable from actual type,
|
||||
* or formal is a primitive type and actual is its corresponding object
|
||||
* type or an object type of a primitive type that can be converted to
|
||||
* the formal type.
|
||||
*/
|
||||
private static boolean isMethodInvocationConvertible(Class formal,
|
||||
Class actual)
|
||||
{
|
||||
/*
|
||||
* if it's a null, it means the arg was null
|
||||
*/
|
||||
if (actual == null && !formal.isPrimitive())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for identity or widening reference conversion
|
||||
*/
|
||||
|
||||
if (actual != null && formal.isAssignableFrom(actual))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for boxing with widening primitive conversion. Note that
|
||||
* actual parameters are never primitives.
|
||||
*/
|
||||
|
||||
if (formal.isPrimitive())
|
||||
{
|
||||
if(formal == Boolean.TYPE && actual == Boolean.class)
|
||||
return true;
|
||||
if(formal == Character.TYPE && actual == Character.class)
|
||||
return true;
|
||||
if(formal == Byte.TYPE && actual == Byte.class)
|
||||
return true;
|
||||
if(formal == Short.TYPE &&
|
||||
(actual == Short.class || actual == Byte.class))
|
||||
return true;
|
||||
if(formal == Integer.TYPE &&
|
||||
(actual == Integer.class || actual == Short.class ||
|
||||
actual == Byte.class))
|
||||
return true;
|
||||
if(formal == Long.TYPE &&
|
||||
(actual == Long.class || actual == Integer.class ||
|
||||
actual == Short.class || actual == Byte.class))
|
||||
return true;
|
||||
if(formal == Float.TYPE &&
|
||||
(actual == Float.class || actual == Long.class ||
|
||||
actual == Integer.class || actual == Short.class ||
|
||||
actual == Byte.class))
|
||||
return true;
|
||||
if(formal == Double.TYPE &&
|
||||
(actual == Double.class || actual == Float.class ||
|
||||
actual == Long.class || actual == Integer.class ||
|
||||
actual == Short.class || actual == Byte.class))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a type represented by a class object is
|
||||
* convertible to another type represented by a class object using a
|
||||
* method invocation conversion, without matching object and primitive
|
||||
* types. This method is used to determine the more specific type when
|
||||
* comparing signatures of methods.
|
||||
*
|
||||
* @param formal the formal parameter type to which the actual
|
||||
* parameter type should be convertible
|
||||
* @param actual the actual parameter type.
|
||||
* @return true if either formal type is assignable from actual type,
|
||||
* or formal and actual are both primitive types and actual can be
|
||||
* subject to widening conversion to formal.
|
||||
*/
|
||||
private static boolean isStrictMethodInvocationConvertible(Class formal,
|
||||
Class actual)
|
||||
{
|
||||
/*
|
||||
* we shouldn't get a null into, but if so
|
||||
*/
|
||||
if (actual == null && !formal.isPrimitive())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for identity or widening reference conversion
|
||||
*/
|
||||
|
||||
if(formal.isAssignableFrom(actual))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for widening primitive conversion.
|
||||
*/
|
||||
|
||||
if(formal.isPrimitive())
|
||||
{
|
||||
if(formal == Short.TYPE && (actual == Byte.TYPE))
|
||||
return true;
|
||||
if(formal == Integer.TYPE &&
|
||||
(actual == Short.TYPE || actual == Byte.TYPE))
|
||||
return true;
|
||||
if(formal == Long.TYPE &&
|
||||
(actual == Integer.TYPE || actual == Short.TYPE ||
|
||||
actual == Byte.TYPE))
|
||||
return true;
|
||||
if(formal == Float.TYPE &&
|
||||
(actual == Long.TYPE || actual == Integer.TYPE ||
|
||||
actual == Short.TYPE || actual == Byte.TYPE))
|
||||
return true;
|
||||
if(formal == Double.TYPE &&
|
||||
(actual == Float.TYPE || actual == Long.TYPE ||
|
||||
actual == Integer.TYPE || actual == Short.TYPE ||
|
||||
actual == Byte.TYPE))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
package org.apache.maven.util.introspection;
|
||||
|
||||
/*
|
||||
* Copyright 2001-2005 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Using simple dotted expressions extract the values from a MavenProject
|
||||
* instance, For example we might want to extract a value like:
|
||||
* project.build.sourceDirectory
|
||||
*
|
||||
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ReflectionValueExtractor
|
||||
{
|
||||
private static Class[] args = new Class[ 0 ];
|
||||
|
||||
private static Object[] params = new Object[ 0 ];
|
||||
|
||||
private static ClassMap classMap;
|
||||
|
||||
private static Map classMaps = new HashMap();
|
||||
|
||||
private ReflectionValueExtractor()
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: don't throw Exception
|
||||
public static Object evaluate( String expression, Object root )
|
||||
throws Exception
|
||||
{
|
||||
// ----------------------------------------------------------------------
|
||||
// Remove the leading "project" token
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
expression = expression.substring( expression.indexOf( '.' ) + 1 );
|
||||
|
||||
Object value = root;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Walk the dots and retrieve the ultimate value desired from the
|
||||
// MavenProject instance.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
StringTokenizer parser = new StringTokenizer( expression, "." );
|
||||
|
||||
while ( parser.hasMoreTokens() )
|
||||
{
|
||||
String token = parser.nextToken();
|
||||
|
||||
classMap = getClassMap( value.getClass() );
|
||||
|
||||
String methodName = "get" + StringUtils.capitalizeFirstLetter( token );
|
||||
|
||||
Method method = classMap.findMethod( methodName, args );
|
||||
|
||||
if ( method == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
value = method.invoke( value, params );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static ClassMap getClassMap( Class clazz )
|
||||
{
|
||||
classMap = (ClassMap) classMaps.get( clazz );
|
||||
|
||||
if ( classMap == null )
|
||||
{
|
||||
classMap = new ClassMap( clazz );
|
||||
|
||||
classMaps.put( clazz, classMap );
|
||||
}
|
||||
|
||||
return classMap;
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package org.apache.maven.util.introspection;
|
||||
|
||||
/*
|
||||
* Copyright 2001-2005 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import org.apache.maven.MavenTestCase;
|
||||
import org.apache.maven.model.Build;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ReflectionValueExtractorTest
|
||||
extends MavenTestCase
|
||||
{
|
||||
private MavenProject project;
|
||||
|
||||
protected void setUp()
|
||||
throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
File f = getFileForClasspathResource( "pom.xml" );
|
||||
|
||||
project = getProject( f );
|
||||
}
|
||||
|
||||
public void testValueExtraction()
|
||||
throws Exception
|
||||
{
|
||||
// ----------------------------------------------------------------------
|
||||
// Top level values
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
assertEquals( "4.0.0", ReflectionValueExtractor.evaluate( "project.modelVersion", project ) );
|
||||
|
||||
assertEquals( "org.apache.maven", ReflectionValueExtractor.evaluate( "project.groupId", project ) );
|
||||
|
||||
assertEquals( "maven-core", ReflectionValueExtractor.evaluate( "project.artifactId", project ) );
|
||||
|
||||
assertEquals( "Maven", ReflectionValueExtractor.evaluate( "project.name", project ) );
|
||||
|
||||
assertEquals( "2.0-SNAPSHOT", ReflectionValueExtractor.evaluate( "project.version", project ) );
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// SCM
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
assertEquals( "scm-connection", ReflectionValueExtractor.evaluate( "project.scm.connection", project ) );
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Dependencies
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
List dependencies = (List) ReflectionValueExtractor.evaluate( "project.dependencies", project );
|
||||
|
||||
assertNotNull( dependencies );
|
||||
|
||||
assertEquals( 2, dependencies.size() );
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Build
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Build build = (Build) ReflectionValueExtractor.evaluate( "project.build", project );
|
||||
|
||||
assertNotNull( build );
|
||||
}
|
||||
|
||||
public void testValueExtractorWithAInvalidExpression()
|
||||
throws Exception
|
||||
{
|
||||
assertNull( ReflectionValueExtractor.evaluate( "project.foo", project ) );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue