Package org.apache.maven

Source Code of org.apache.maven.MavenUtils

package org.apache.maven;

/* ====================================================================
*   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.commons.jelly.JellyContext;
import org.apache.commons.jelly.expression.CompositeExpression;
import org.apache.commons.jelly.expression.Expression;
import org.apache.commons.jelly.expression.jexl.JexlExpressionFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.maven.jelly.JellyUtils;
import org.apache.maven.jelly.MavenJellyContext;
import org.apache.maven.project.Project;
import org.apache.tools.ant.DirectoryScanner;
import org.codehaus.plexus.util.CollectionUtils;
import org.codehaus.plexus.util.StringUtils;
import org.xml.sax.SAXException;

import com.werken.forehead.ForeheadClassLoader;

import java.beans.IntrospectionException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.parsers.ParserConfigurationException;

/**
* Utilities for reading maven project descriptors, profile descriptors and workspace descriptors.
*
* @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
*
* @todo Remove all the context creation code and make a ContextBuilder class.
* @todo [RC2] split getProject (project.properties + defaults) != getPluginProject (plugin.properties only)
*/
public class MavenUtils
{
    /** Log. */
    private static final Log LOGGER = LogFactory.getLog( MavenUtils.class );

    /** Map of loaded POMs. */
    private static HashMap parentPoms = new HashMap();

    /** Maven unknown error message. */
    public static final String MAVEN_UNKNOWN_ERROR = "Unknown error reading project";

    /**
     * Create a Project object given a file descriptor.
     *
     * @param projectDescriptor
     *            a maven project.xml
     * @return the Maven project object for the given project descriptor
     * @throws MavenException
     *             when any errors occur
     */
    public static Project getProject( File projectDescriptor ) throws MavenException
    {
        return getProject( projectDescriptor, null );
    }

    /**
     * Create a Project object given a file descriptor, and a parent context
     *
     * @param projectDescriptor
     *            The file to create the project from
     * @param parentContext
     *            the parent Maven Jelly Context
     * @return a new Project
     * @throws MavenException
     *             when any error happens.
     */
    public static Project getProject( File projectDescriptor, MavenJellyContext parentContext ) throws MavenException
    {
        return getProject( projectDescriptor, parentContext, true );
    }

    /**
     * Create a Project object given a file descriptor and optionally a parent Jelly context.
     *
     * @param projectDescriptor
     *            a maven project.xml {@link File}
     * @param parentContext
     *            the parent context for the new project
     * @param useParentPom
     *            whether a parent project should be respected
     * @return the MavenSession project object for the given project descriptor
     * @throws MavenException
     *             when any errors occur
     */
    public static Project getProject( File projectDescriptor, MavenJellyContext parentContext, boolean useParentPom )
        throws MavenException
    {
        Project project = null;
        try
        {
            project = getNonJellyProject( projectDescriptor, parentContext, useParentPom );
            project = getJellyProject( project );
            project.setFile( projectDescriptor );

            // Fully initialize the project.
            project.initialize();
        }
        catch ( IntrospectionException e )
        {
            throw new MavenException( "Error creating a string from the project", e );
        }
        catch ( IOException e )
        {
            throw new MavenException( "Error reading XML or initializing", e );
        }
        catch ( ParserConfigurationException e )
        {
            throw new MavenException( "Error creating a JAXP Parser", e );
        }
        catch ( SAXException e )
        {
            throw new MavenException( "Error parsing XML", e );
        }
        catch ( MavenException e )
        {
            throw e;
        }
        catch ( Exception e )
        {
            // FIXME
            throw new MavenException( MAVEN_UNKNOWN_ERROR, e );
        }

        return project;
    }

    /**
     * Get a project, but not a Jelly-ised project. ie Don't evaluate the variables. We are doing several things when
     * creating a POM object, the phases are outlined here:
     *
     * 1) The project.xml file is read in using betwixt which creates for us a Project object that, at this point, has
     * not been run through Jelly i.e. no interpolation has occured yet.
     *
     * 2) The context for the project is created and set. So each project manages its own context. See the
     * createContext() method for the details context creation process.
     *
     * 3) We check to see if the &lt;extend&gt; tag is being employed. If so, the parent project.xml file is read in. At
     * this point we have a child and parent POM and the values are merged where the child's values override those of
     * the parent.
     *
     * @param projectDescriptor
     *            the project file
     * @param parentContext
     *            the parent context for the new project
     * @param useParentPom
     *            whether a parent project should be respected
     * @return the project
     * @throws MavenException
     *             when there are errors reading the descriptor
     * @throws IOException
     *             when resolving file names and paths
     */
    public static Project getNonJellyProject( File projectDescriptor, MavenJellyContext parentContext,
                                              boolean useParentPom ) throws MavenException, IOException
    {
        // 1)
        Project project = null;
        try
        {
            project = new Project( projectDescriptor.toURL() );
        }
        catch ( Exception e )
        {
            throw new MavenException( "Error parsing project.xml '" + projectDescriptor.getAbsolutePath() + "'", e );
        }

        // 2)
        MavenJellyContext context =
            MavenUtils.createContextNoDefaults( projectDescriptor.getParentFile(), parentContext );

        // 3)
        String pomToExtend = project.getExtend();

        if ( ( pomToExtend != null ) && useParentPom )
        {
            // We must look in the <extend/> element for expressions that may be present as
            //
            // <extend>../project.xml</extend>
            Expression e = JellyUtils.decomposeExpression( pomToExtend, context );
            pomToExtend = e.evaluateAsString( context );
            pomToExtend = MavenUtils.makeAbsolutePath( projectDescriptor.getParentFile(), pomToExtend );
            project.setExtend( pomToExtend );

            File parentPom = new File( pomToExtend );
            parentPom = parentPom.getCanonicalFile();
            if ( !parentPom.exists() )
            {
                throw new FileNotFoundException( "Parent POM not found: " + parentPom );
            }

            String parentPomPath = parentPom.getPath();
            if ( parentPomPath.equals( projectDescriptor.getCanonicalPath() ) )
            {
                throw new MavenException( "Parent POM is equal to the current POM" );
            }

            Project parent = (Project) parentPoms.get( parentPomPath );
            if ( parent == null )
            {
                parent = getNonJellyProject( parentPom, parentContext, true );
                parent.setFile( parentPom );
                parentPoms.put( parentPom.getCanonicalPath(), parent );
                context.setParent( parent.getContext() );
            }

            // Map in the parent context which already has the properties loaded
            integrateMapInContext( parent.getContext().getVariables(), context );

            project.mergeParent( parent );
        }

        project.resolveIds();

        applyDefaults( context );

        // Set the created context, and put the project itself in the context. This
        // is how we get the ${pom} reference in the project.xml file to work.
        project.setContext( context );
        context.setProject( project );

        return project;
    }

    /**
     * This is currently used for the reactor but may be generally useful.
     *
     * @param directory
     *            the directory to scan for maven projects
     * @param includes
     *            the pattern that matches a project that you want included
     * @param excludes
     *            the pattern that matches a project that you don't want included
     * @return a {link List} of {@link Project}s
     * @throws MavenException
     *             when anything goes wrong.
     */
    public static List getProjects( File directory, String includes, String excludes ) throws MavenException
    {
        return getProjects( directory, includes, excludes, null );
    }

    /**
     * This is currently used for the reactor but may be generally useful.
     *
     * @param directory
     *            the directory to scan for maven projects
     * @param includes
     *            Patterns to include.
     * @param excludes
     *            Patterns to exclude.
     * @param context
     *            the parent context
     * @return a {link List} of {@link Project}s
     * @throws MavenException
     *             when anything goes wrong.
     */
    public static List getProjects( File directory, String includes, String excludes, MavenJellyContext context )
        throws MavenException
    {
        String[] files = getFiles( directory, includes, excludes );

        List projects = new ArrayList();

        for ( int i = 0; i < files.length; i++ )
        {
            Project p = getProject( new File( files[i] ), context );
            projects.add( p );
        }

        return projects;
    }

    /**
     * Take the POM and interpolate the value of the project's context to create a new version of the POM with expanded
     * context values.
     *
     * @param project
     *            the maven POM
     * @return Jelly interpolated project.
     * @throws Exception
     *             when there are errors reading FIXME
     */
    public static Project getJellyProject( Project project ) throws Exception
    {
        // Keep a copy of the original context
        MavenJellyContext originalContext = project.getContext();

        // We don't want any taglib references in the context or Jelly
        // gets confused. All we want are the variables for interpolation. We
        // can change this but I think we would like to avoid general Jelly
        // idiom in the POM anyway.
        JellyContext context = new JellyContext();
        JellyUtils.populateVariables( context, originalContext );

        // We don't want the context or the parent being written out into the XML which
        // is the interpolated POM.
        project.setContext( null );
        Project parent = project.getParent();
        project.setParent( null );

        // Interpolate
        project = getInterpolatedPOM( project, context );

        // Restore parent and context
        project.setParent( parent );
        project.setContext( originalContext );
        project.getContext().setProject( project );

        return project;
    }

    /**
     * Get the POM with all variables resolved.
     *
     * @param project
     *            the project to resolve
     * @param context
     *            the context to retrieve variables from
     * @return a project with no unresolved elements.
     * @throws Exception
     *             if there is an error parsing the project FIXME
     */
    private static Project getInterpolatedPOM( Project project, JellyContext context ) throws Exception
    {
        String projectString = project.getProjectAsString();
        Expression e = JellyUtils.decomposeExpression( projectString, context );
        String newProjectString = e.evaluateAsString( context );
        // We can use a Reader and not an URL/path here to read
        // the POM because this is a memory model without XML entities.
        project = new Project( new StringReader( newProjectString ) );
        return project;
    }

    /**
     * Get a set of files from a specifed directory with a set of includes.
     *
     * @param directory
     *            Directory to scan.
     * @param includes
     *            Comma separated list of includes.
     * @return files
     */
    public static String[] getFiles( File directory, String includes )
    {
        return getFiles( directory, includes, null );
    }

    /**
     * Get a set of files from a specifed directory with a set of includes.
     *
     * @param directory
     *            Directory to scan.
     * @param includes
     *            Comma separated list of includes.
     * @param excludes
     *            Comma separated list of excludes.
     * @return files
     */
    public static String[] getFiles( File directory, String includes, String excludes )
    {
        String[] includePatterns = null;
        if ( includes != null )
        {
            includePatterns = StringUtils.split( includes, "," );
        }

        String[] excludePatterns = null;
        if ( excludes != null )
        {
            excludePatterns = StringUtils.split( excludes, "," );
        }

        DirectoryScanner directoryScanner = new DirectoryScanner();
        directoryScanner.setBasedir( directory );
        directoryScanner.setIncludes( includePatterns );
        directoryScanner.setExcludes( excludePatterns );
        directoryScanner.scan();
        String[] files = directoryScanner.getIncludedFiles();

        for ( int i = 0; i < files.length; i++ )
        {
            files[i] = new File( directory, files[i] ).getAbsolutePath();
        }

        return files;
    }

    /**
     * Take a dominant and recessive Map and merge the key:value pairs where the recessive Map may add key:value pairs
     * to the dominant Map but may not override any existing key:value pairs.
     *
     * If we have two Maps, a dominant and recessive, and their respective keys are as follows:
     *
     * dominantMapKeys = { a, b, c, d, e, f } recessiveMapKeys = { a, b, c, x, y, z }
     *
     * Then the result should be the following:
     *
     * resultantKeys = { a, b, c, d, e, f, x, y, z }
     *
     * @param dominantMap
     *            Dominant Map.
     * @param recessiveMap
     *            Recessive Map.
     * @return The result map with combined dominant and recessive values.
     */
    public static Map mergeMaps( Map dominantMap, Map recessiveMap )
    {
        Map result = new HashMap();

        if ( ( dominantMap == null ) && ( recessiveMap == null ) )
        {
            return null;
        }

        if ( ( dominantMap != null ) && ( recessiveMap == null ) )
        {
            return dominantMap;
        }

        if ( dominantMap == null )
        {
            return recessiveMap;
        }

        // Grab the keys from the dominant and recessive maps.
        Set dominantMapKeys = dominantMap.keySet();
        Set recessiveMapKeys = recessiveMap.keySet();

        // Create the set of keys that will be contributed by the
        // recessive Map by subtracting the intersection of keys
        // from the recessive Map's keys.
        Collection contributingRecessiveKeys =
            CollectionUtils.subtract( recessiveMapKeys,
                                      CollectionUtils.intersection( dominantMapKeys, recessiveMapKeys ) );

        result.putAll( dominantMap );

        // Now take the keys we just found and extract the values from
        // the recessiveMap and put the key:value pairs into the dominantMap.
        for ( Iterator i = contributingRecessiveKeys.iterator(); i.hasNext(); )
        {
            Object key = i.next();
            result.put( key, recessiveMap.get( key ) );
        }

        return result;
    }

    /**
     * Take a series of <code>Map</code>s and merge them where the ordering of the array from 0..n is the dominant
     * order.
     *
     * @param maps
     *            An array of Maps to merge.
     * @return Map The result Map produced after the merging process.
     */
    public static Map mergeMaps( Map[] maps )
    {
        Map result;

        if ( maps.length == 0 )
        {
            result = null;
        }
        else if ( maps.length == 1 )
        {
            result = maps[0];
        }
        else
        {
            result = mergeMaps( maps[0], maps[1] );

            for ( int i = 2; i < maps.length; i++ )
            {
                result = mergeMaps( result, maps[i] );
            }
        }

        return result;
    }

    /**
     * Load the build.properties file for a project.
     *
     * @param directory
     *            the directory of the project
     * @return the properties
     */
    private static Properties loadProjectBuildProperties( File directory )
    {
        // project build properties
        File projectBuildPropertiesFile = new File( directory, "build.properties" );

        LOGGER.debug( "Using projectBuildPropertiesFile: " + projectBuildPropertiesFile.getAbsolutePath() );
        return loadProperties( projectBuildPropertiesFile );
    }

    /**
     * Load the project.properties file for a project.
     *
     * @param directory
     *            the directory of the project
     * @return the properties
     */
    private static Properties loadProjectProperties( File directory )
    {
        // project properties
        File projectPropertiesFile = new File( directory, "project.properties" );

        LOGGER.debug( "Using projectPropertiesFile: " + projectPropertiesFile.getAbsolutePath() );
        return loadProperties( projectPropertiesFile );
    }

    /**
     * Create a jelly context given a descriptor directory.
     *
     * @param descriptorDirectory
     *            The directory from which to pull the standard maven properties files from.
     * @return The generated maven based on the contents of the standard maven properties files.
     */
    public static MavenJellyContext createContext( File descriptorDirectory )
    {
        return createContext( descriptorDirectory, null );
    }

    /**
     * Create a jelly context given a descriptor directory and parent jelly context.
     *
     * @param descriptorDirectory
     *            The directory from which to pull the standard maven properties files from.
     * @param parentContext
     *            The parent jelly context.
     * @todo should premerge driver, etc if they are being kept
     * @return The generated maven based on the contents of the standard maven properties files.
     */
    public static MavenJellyContext createContext( File descriptorDirectory, MavenJellyContext parentContext )
    {
        MavenJellyContext context = createContextNoDefaults( descriptorDirectory, parentContext );
        applyDefaults( context );
        return context;
    }

    /**
     * Create a jelly context given a descriptor directory and parent jelly context, but don't apply any defaults.
     *
     * @param descriptorDirectory
     *            The directory from which to pull the standard maven properties files from.
     * @param parentContext
     *            The parent jelly context.
     * @todo should premerge driver, etc if they are being kept
     * @return The generated maven based on the contents of the standard maven properties files.
     */
    private static MavenJellyContext createContextNoDefaults( File descriptorDirectory, MavenJellyContext parentContext )
    {
        // System properties
        Properties systemProperties = System.getProperties();

        // User build properties
        File userBuildPropertiesFile = new File( System.getProperty( "user.home" ), "build.properties" );

        LOGGER.debug( "Using userBuildPropertiesFile: " + userBuildPropertiesFile.getAbsolutePath() );
        Properties userBuildProperties = loadProperties( userBuildPropertiesFile );

        Properties projectProperties = loadProjectProperties( descriptorDirectory );
        Properties projectBuildProperties = loadProjectBuildProperties( descriptorDirectory );

        Properties driverProperties =
            loadProperties( MavenUtils.class.getResourceAsStream( MavenConstants.DRIVER_PROPERTIES ) );

        Map result =
            MavenUtils.mergeMaps( new Map[] { systemProperties, userBuildProperties, projectBuildProperties,
                projectProperties, driverProperties } );

        MavenJellyContext context;

        if ( parentContext != null )
        {
            context = new MavenJellyContext( parentContext );
        }
        else
        {
            context = new MavenJellyContext();
        }

        // Turn off inheritence so parent values are overriden
        context.setInherit( false );

        // integrate everything else...
        MavenUtils.integrateMapInContext( result, context );

        // Turn inheritance back on to make the parent's values visible.
        context.setInherit( true );

        // Set the basedir value in the context.
        context.setVariable( "basedir", descriptorDirectory.getAbsolutePath() );

        return context;
    }

    /**
     * Apply default settings.
     *
     * @param context
     *            Jelly context to apply the defaults.
     */
    private static void applyDefaults( MavenJellyContext context )
    {
        Properties defaultProperties =
            loadProperties( MavenUtils.class.getResourceAsStream( MavenConstants.DEFAULTS_PROPERTIES ) );

        // integrate defaults...
        MavenUtils.integrateMapInContext( defaultProperties, context );

        // deliberately use the original base directory for these variables
        context.resolveRelativePaths( new File( System.getProperty( "user.dir" ) ) );
    }

    /**
     * Integrate a Map of key:value pairs into a <code>MavenJellyContext</code>. The values in the Map may be
     * <code>CompositeExpression</code>s that need to be evaluated before being placed into the context.
     *
     * @param map
     *            Map to integrate into the provided jelly context.
     * @param context
     *            Jelly context to integrate the map into.
     */
    public static void integrateMapInContext( Map map, MavenJellyContext context )
    {
        if ( map == null )
        {
            return;
        }

        JexlExpressionFactory factory = new JexlExpressionFactory();

        for ( Iterator i = map.keySet().iterator(); i.hasNext(); )
        {
            String key = (String) i.next();
            Object value;

            // Parent contexts are already handled, so only concern ourselves with whether it exists in the current
            // context
            if ( context.getVariables().get( key ) == null )
            {
                value = map.get( key );

                if ( value instanceof String )
                {
                    try
                    {
                        String literalValue = (String) value;
                        Expression expr = CompositeExpression.parse( literalValue, factory );

                        if ( expr != null )
                        {
                            value = expr;
                        }
                        else
                        {
                            value = literalValue;
                        }
                    }
                    catch ( Exception e )
                    {
                        // do nothing.
                        LOGGER.debug( "Unexpected error evaluating expression", e );
                    }
                }
                context.setVariable( key, value );
            }
        }
    }

    /**
     * Load properties from a <code>File</code>.
     *
     * @param file
     *            Propertie file to load.
     * @return The loaded Properties.
     */
    private static Properties loadProperties( File file )
    {
        FileInputStream fis = null;
        try
        {
            if ( file.exists() )
            {
                fis = new FileInputStream( file );
                return loadProperties( fis );
            }
        }
        catch ( Exception e )
        {
            // ignore
            LOGGER.debug( "Unexpected error loading properties", e );
        }
        finally
        {
            if ( fis != null )
            {
                try
                {
                    fis.close();
                }
                catch ( IOException e )
                {
                    LOGGER.debug( "WARNING: Cannot close stream!", e );
                }
                fis = null;
            }
        }

        return null;
    }

    /**
     * Load properties from an <code>InputStream</code>.
     *
     * @param is
     *            InputStream from which load properties.
     * @return The loaded Properties.
     */
    private static Properties loadProperties( InputStream is )
    {
        try
        {
            Properties properties = new Properties();
            properties.load( is );

            for ( Iterator i = properties.keySet().iterator(); i.hasNext(); )
            {
                String property = (String) i.next();
                properties.setProperty( property, properties.getProperty( property ).trim() );
            }

            return properties;
        }
        catch ( IOException e )
        {
            // ignore
            LOGGER.debug( "Unexpected exception loading properties", e );
        }
        finally
        {
            try
            {
                if ( is != null )
                {
                    is.close();
                }
            }
            catch ( IOException e )
            {
                // ignore
                LOGGER.debug( "Unexpected exception loading properties", e );
            }
        }

        return null;
    }

    /** Resource bundle with user messages. */
    private static ResourceBundle messages;

    /**
     * Load MavenSession user messages from a resource bundle given the user's locale.
     *
     * @todo Move locale tools into their own class.
     */
    private static void loadMessages()
    {
        try
        {
            // Look for the message bundle corresponding to the user's locale.
            messages = ResourceBundle.getBundle( "org/apache/maven/messages/messages" );
        }
        catch ( MissingResourceException e )
        {
            // If we can't find the appropriate message bundle for the locale then
            // we will fall back to English.
            messages = ResourceBundle.getBundle( "org/apache/maven/messages/messages", Locale.ENGLISH );
        }
    }

    /**
     * Retrieve a user message.
     *
     * @param messageId
     *            Id of message type to use.
     * @return Message for the user's locale.
     */
    public static String getMessage( String messageId )
    {
        return getMessage( messageId, null );
    }

    /**
     * Retrieve a user message.
     *
     * @param messageId
     *            Id of message type to use.
     * @param variable
     *            Value to substitute for ${1} in the given message.
     * @return Message for the user's locale.
     */
    public static String getMessage( String messageId, Object variable )
    {
        if ( messages == null )
        {
            try
            {
                loadMessages();
            }
            catch ( MissingResourceException mre )
            {
                LOGGER.error( mre );
                return messageId + ( variable == null ? "" : " " + variable );
            }
        }

        if ( variable == null )
        {
            return messages.getString( messageId );
        }
        else
        {
            return StringUtils.replace( messages.getString( messageId ), "${1}", variable.toString() );
        }
    }

    /**
     * Resolve directory against a base directory if it is not already absolute.
     *
     * @param basedir
     *            the base directory for relative paths
     * @param dir
     *            the directory to resolve
     * @throws IOException
     *             if canonical path fails
     * @return the canonical path of the directory if not absolute
     */
    public static String makeAbsolutePath( File basedir, String dir ) throws IOException
    {
        File f = new File( dir );
        if ( ( f.isAbsolute() ) )
        {
            return f.getCanonicalPath();
        }
        else
        {
            return new File( basedir, dir ).getCanonicalPath();
        }
    }

    /**
     * Convert an absolute path to a relative path if it is under a given base directory.
     *
     * @param basedir
     *            the base directory for relative paths
     * @param path
     *            the directory to resolve
     * @return the relative path
     * @throws IOException
     *             if canonical path fails
     */
    public static String makeRelativePath( File basedir, String path ) throws IOException
    {
        String canonicalBasedir = basedir.getCanonicalPath();
        File pathFile = new File( path );
        if ( !pathFile.isAbsolute() )
        {
            LOGGER.warn( "WARNING: path is not an absolute pathname! Returning path." );
            return path;
        }
        String canonicalPath = pathFile.getCanonicalPath();

        if ( canonicalPath.equals( canonicalBasedir ) )
        {
            return ".";
        }

        if ( canonicalPath.startsWith( canonicalBasedir ) )
        {
            if ( canonicalPath.charAt( canonicalBasedir.length() ) == File.separatorChar )
            {
                canonicalPath = canonicalPath.substring( canonicalBasedir.length() + 1 );
            }
            else
            {
                canonicalPath = canonicalPath.substring( canonicalBasedir.length() );
            }
        }
        else
        {
            LOGGER.warn( "WARNING: path does not start with basedir! Returning path." );
            return path;
        }
        return canonicalPath;
    }

    /**
     * Get a list of goals from a CSV list.
     *
     * @param goalCsv
     *            the goals
     * @return the list of goal names
     */
    public static List getGoalListFromCsv( String goalCsv )
    {
        StringTokenizer tok = new StringTokenizer( goalCsv, "," );
        List goals = new ArrayList();
        while ( tok.hasMoreTokens() )
        {
            goals.add( tok.nextToken().trim() );
        }
        return goals;
    }

    /**
     * Debugging function.
     *
     * @param classLoader
     *            the class loader
     */
    public static void displayClassLoaderContents( ForeheadClassLoader classLoader )
    {
        LOGGER.info( "ClassLoader name: " + classLoader.getName() );

        URL[] urls = classLoader.getURLs();

        for ( int i = 0; i < urls.length; i++ )
        {
            LOGGER.info( "urls[" + i + "] = " + urls[i] );
        }

        ClassLoader parent = classLoader.getParent();
        if ( ( parent != null ) && ( parent instanceof ForeheadClassLoader ) )
        {
            LOGGER.info( "Displaying Parent classloader: " );
            displayClassLoaderContents( (ForeheadClassLoader) classLoader.getParent() );
        }
    }


}
TOP

Related Classes of org.apache.maven.MavenUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.