alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * 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.
 */
package org.apache.axis2.maven2.mar;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;



/**
 * Abstract base class of all the mojos in the axis2-mar-maven-plugin.
 */
public abstract class AbstractMarMojo
    extends AbstractMojo
{

    /**
     * The projects base directory.
     *
     * @parameter expression="${project.basedir}"
     * @required
     * @readonly
     */
    protected File baseDir;
    
    /**
     * The maven project.
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    protected MavenProject project;

    /**
     * The directory containing generated classes.
     *
     * @parameter expression="${project.build.outputDirectory}"
     * @required
     */
    private File classesDirectory;

    /**
     * The directory where the mar is built.
     *
     * @parameter expression="${project.build.directory}/mar"
     * @required
     */
    protected File marDirectory;

    /**
     * The location of the module.xml file.  If it is present in the META-INF
     * directory in src/main/resources with that name then it will automatically be 
     * included. Otherwise this parameter must be set.
     *
     * @parameter 
     */
    private File moduleXmlFile;

    /**
     * Additional file sets, which are being added to the archive.
     *
     * @parameter
     */
    private FileSet[] fileSets;

    /**
     * Whether the dependency jars should be included in the mar
     * 
     * @parameter expression="${includeDependencies}" default-value="true"
     */
    private boolean includeDependencies;
    
    /**
     * Builds the exploded mar file.
     * @throws MojoExecutionException
     */
    protected void buildExplodedMar( )
        throws MojoExecutionException
    {
        getLog().debug( "Exploding mar..." );

        marDirectory.mkdirs();
        getLog().debug( "Assembling mar " + project.getArtifactId() + " in " + marDirectory );

        try
        {
            final File metaInfDir = new File( marDirectory, "META-INF" );
            final File libDir = new File(marDirectory, "lib");
            final File moduleFileTarget = new File( metaInfDir, "module.xml" );
            boolean existsBeforeCopyingClasses = moduleFileTarget.exists();

            if ( classesDirectory.exists() && ( !classesDirectory.equals( marDirectory ) ) )
            {
                FileUtils.copyDirectoryStructure( classesDirectory, marDirectory );
            }

            if ( fileSets != null )
            {
                for ( int i = 0;  i < fileSets.length;   i++ )
                {
                    FileSet fileSet = fileSets[i];
                    copyFileSet( fileSet, marDirectory );
                }
            }
            
            copyMetaInfFile( moduleXmlFile, moduleFileTarget, existsBeforeCopyingClasses, "module.xml file" );

            if(includeDependencies){
                Set artifacts = project.getArtifacts();
    
                List duplicates = findDuplicates( artifacts );
    
                for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
                {
                	Artifact artifact = (Artifact) iter.next();
                	String targetFileName = getDefaultFinalName( artifact );
    
                	getLog().debug( "Processing: " + targetFileName );
    
                	if ( duplicates.contains( targetFileName ) )
                	{
                		getLog().debug( "Duplicate found: " + targetFileName );
                		targetFileName = artifact.getGroupId() + "-" + targetFileName;
                		getLog().debug( "Renamed to: " + targetFileName );
                	}
    
                	// TODO: utilise appropriate methods from project builder
                	ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
                	if ( !artifact.isOptional() && filter.include( artifact ) )
                	{
                		String type = artifact.getType();
                		if ( "jar".equals( type ) )
                		{
                			copyFileIfModified( artifact.getFile(), new File( libDir, targetFileName ) );
                		}
                	}
                }
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Could not explode mar...", e );
        }
    }

    /**
     * Searches a set of artifacts for duplicate filenames and returns a list of duplicates.
     *
     * @param artifacts set of artifacts
     * @return List of duplicated artifacts
     */
    private List findDuplicates( Set artifacts )
    {
        List duplicates = new ArrayList();
        List identifiers = new ArrayList();
        for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
        {
            Artifact artifact = (Artifact) iter.next();
            String candidate = getDefaultFinalName( artifact );
            if ( identifiers.contains( candidate ) )
            {
                duplicates.add( candidate );
            }
            else
            {
                identifiers.add( candidate );
            }
        }
        return duplicates;
    }

    /**
     * Converts the filename of an artifact to artifactId-version.type format.
     *
     * @param artifact
     * @return converted filename of the artifact
     */
    private String getDefaultFinalName( Artifact artifact )
    {
        return artifact.getArtifactId() + "-" + artifact.getVersion() + "." +
            artifact.getArtifactHandler().getExtension();
    }

    /**
     * Copy file from source to destination only if source timestamp is later than the destination timestamp.
     * The directories up to <code>destination will be created if they don't already exist.
     * <code>destination will be overwritten if it already exists.
     *
     * @param source      An existing non-directory <code>File to copy bytes from.
     * @param destination A non-directory <code>File to write bytes to (possibly
     *                    overwriting).
     * @throws IOException                   if <code>source does not exist, destination cannot be
     *                                       written to, or an IO error occurs during copying.
     * @throws java.io.FileNotFoundException if <code>destination is a directory
     *                                       <p/>
     *                                       TO DO: Remove this method when Maven moves to plexus-utils version 1.4
     */
    private void copyFileIfModified( File source, File destination )
        throws IOException
    {
        // TO DO: Remove this method and use the method in WarFileUtils when Maven 2 changes
        // to plexus-utils 1.2.
        if ( destination.lastModified() < source.lastModified() )
        {
            FileUtils.copyFile( source.getCanonicalFile(), destination );
            // preserve timestamp
            destination.setLastModified( source.lastModified() );
        }
    }

    private void copyFileSet( FileSet fileSet, File targetDirectory )
        throws IOException
    {
        File dir = fileSet.getDirectory();
        if ( dir == null )
        {
            dir = baseDir;
        }
        File targetDir = targetDirectory;
        if ( fileSet.getOutputDirectory() != null )
        {
            targetDir = new File( targetDir, fileSet.getOutputDirectory() );
        }
        if ( targetDir.equals( dir ) )
        {
            return;
        }

        DirectoryScanner ds = new DirectoryScanner();
        ds.setBasedir( dir );
        if ( !fileSet.isSkipDefaultExcludes() )
        {
            ds.addDefaultExcludes();
        }
        final String[] excludes = fileSet.getExcludes();
        if ( excludes != null )
        {
            ds.setExcludes( excludes );
        }
        final String[] includes = fileSet.getIncludes();
        if ( includes != null )
        {
            ds.setIncludes( includes );
        }
        ds.scan();
        String[] files = ds.getIncludedFiles();
        for ( int i = 0;  i < files.length;  i++ )
        {
            File sourceFile = new File( dir, files[i] );
            File targetFile = new File( targetDir, files[i] );
            FileUtils.copyFile( sourceFile, targetFile );
        }
    }


    private void copyMetaInfFile( final File pSource, final File pTarget,
                                  final boolean pExistsBeforeCopying,
                                  final String pDescription )
        throws MojoExecutionException, IOException
    {
        if ( pSource != null  &&  pTarget != null )
        {
            if ( !pSource.exists() )
            {
                throw new MojoExecutionException( "The configured " + pDescription + " could not be found at "
                                                  + pSource );
            }

            if ( !pExistsBeforeCopying  &&  pTarget.exists() )
            {
                getLog().warn( "The configured " + pDescription + " overwrites another file from the classpath." );
            }

            FileUtils.copyFile( pSource, pTarget );
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.