package org.codehaus.mojo.solaris;
/*
* 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.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.InterpolationFilterReader;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Arrays;
/**
* Copies System V-specific resources.
*
* This goal will copy the following files from <code>src/main/solaris</code>:
* <ul>
* <li>
* <code>pkginfo</code> - The pkginfo file will be read and these values will be interpolated:
* <ul>
* <li>${project.artifactId}</li>
* <li>${project.version}</li>
* <li>${project.name}</li>
* <li>${project.description}</li>
* </ul>
* </li>
* <li>
* <code>prototype</code> - The prototype file will be copied to the directory specified by <code>packageRoot</code>.
* </li>
* </ul>
*
* @author <a href="mailto:trygvis@codehaus.org">Trygve Laugstøl</a>
* @version $Id$
* @goal resources
*/
public class ResourcesMojo
extends AbstractSolarisMojo
{
private static final String[] DEFAULT_INCLUDES = {"**/**"};
/**
* Package metadata resources (e.g. prototype and pkginfo) to copy into the package.
*
* Will default to <code>src/main/resources-solaris</code>, include all files and then exclude common SCM files.
* See <a href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/DirectoryScanner.html">
* the documentation</a> for the full reference.
*
* @parameter
*/
private Resource solarisResources;
/**
* Resources to copy into the package.
*
* @parameter expression="${project.resources}"
* @required
*/
private List resources;
/**
* The <code>pkginfo</code> file to interpolate and copy.
*
* @parameter expression="src/main/resources-solaris/pkginfo"
* @required
*/
private File pkginfo;
/**
* There directory where <code>pkgmk</code> and <code>pkgtrans</code> will be executed. All files that are to be
* a part of the package has to be in this directory before the prototype file is generated.
*
* @parameter expression="${project.build.directory}/solaris/assembled-pkg"
* @required
*/
private File packageRoot;
/**
* Additional properties to be used when interpolating the <code>pkginfo</code> file.
*
* @parameter
*/
private Properties properties;
/**
* The artifact id of the project. Used when interpolating the <code>pkginfo</code> file.
*
* @parameter expression="${project.artifactId}"
* @readonly
*/
private String artifactId;
/**
* The version of the project. Used when interpolating the <code>pkginfo</code> file.
*
* @parameter expression="${project.version}"
* @readonly
*/
private String version;
/**
* The name of the project. Used when interpolating the <code>pkginfo</code> file.
*
* @parameter expression="${project.name}"
* @readonly
*/
private String name;
/**
* The description of the project. Used when interpolating the <code>pkginfo</code> file.
*
* @parameter expression="${project.description}"
* @readonly
*/
private String description;
/**
* @parameter expression="${basedir}"
* @readonly
*/
private File basedir;
// -----------------------------------------------------------------------
// Mojo Implementation
// -----------------------------------------------------------------------
public void execute()
throws MojoExecutionException, MojoFailureException
{
mkdirs( packageRoot );
copyResources();
copySolarisResources();
copyPkginfo();
}
private void copyResources()
throws MojoExecutionException
{
for ( Iterator it = resources.iterator(); it.hasNext(); )
{
Resource resource = (Resource) it.next();
copyResource( resource );
}
}
private void copySolarisResources()
throws MojoExecutionException
{
if ( solarisResources == null )
{
solarisResources = new Resource();
solarisResources.setDirectory( new File( basedir, "src/main/resources-solaris" ).getAbsolutePath() );
}
copyResource( solarisResources );
}
private void copyPkginfo()
throws MojoFailureException, MojoExecutionException
{
Properties properties = new Properties();
properties.put( "project.artifactId", artifactId );
properties.put( "project.version", version );
properties.put( "project.name", StringUtils.clean( name ) );
properties.put( "project.description", StringUtils.clean( description ) );
if ( this.properties != null )
{
properties.putAll( this.properties );
}
// -----------------------------------------------------------------------
// Validate
// -----------------------------------------------------------------------
if ( !pkginfo.canRead() )
{
throw new MojoFailureException( "Can't read template pkginfo file: '" + pkginfo.getAbsolutePath() + "'." );
}
File processedPkginfo = new File( packageRoot, "pkginfo" );
// -----------------------------------------------------------------------
// Do it!
// -----------------------------------------------------------------------
FileWriter pkginfoWriter = null;
FileReader fileReader = null;
try
{
fileReader = new FileReader( pkginfo );
InterpolationFilterReader reader = new InterpolationFilterReader( fileReader, properties );
pkginfoWriter = new FileWriter( processedPkginfo );
IOUtil.copy( reader, pkginfoWriter );
}
catch ( IOException e )
{
// All common causes to this should have been removed with previous checks.
throw new MojoExecutionException( "Error while interpolating pkginfo.", e );
}
finally
{
IOUtil.close( pkginfoWriter );
IOUtil.close( fileReader );
}
}
private void copyResource( Resource resource )
throws MojoExecutionException
{
File directory = getFile( resource.getDirectory() );
if ( directory == null || !directory.isDirectory() )
{
getLog().debug( "Not a directory: " + directory );
return;
}
try
{
resource.setTargetPath( packageRoot.getAbsolutePath() );
copy( resource );
}
catch ( IOException e )
{
throw new MojoExecutionException( "Could not copy files from '" + directory.getAbsolutePath() +
"' to '" + packageRoot.getAbsolutePath() + "'.", e );
}
}
private void copy( Resource resource )
throws IOException
{
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( resource.getDirectory() );
String[] includes = DEFAULT_INCLUDES;
List includesList = resource.getIncludes();
if ( includesList != null && !includesList.isEmpty() )
{
scanner.setIncludes( (String[]) includesList.toArray( new String[ includesList.size() ] ) );
}
scanner.setIncludes( includes );
String[] excludes = null;
if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
{
excludes = (String[]) resource.getExcludes().toArray( new String[ resource.getExcludes().size() ] );
}
scanner.setExcludes( excludes );
getLog().debug( "Copying resources..." );
getLog().debug( " From: " + resource.getDirectory() );
getLog().debug( " To: " + resource.getTargetPath() );
getLog().debug( " Includes: " + StringUtils.join( includes, "," ) );
if ( excludes != null )
{
getLog().debug( " Excludes: " + StringUtils.join( excludes, "," ) );
}
else
{
getLog().debug( " Excludes: none" );
}
scanner.addDefaultExcludes();
scanner.scan();
List includedFiles = Arrays.asList( scanner.getIncludedFiles() );
for ( Iterator j = includedFiles.iterator(); j.hasNext(); )
{
String name = (String) j.next();
File source = new File( resource.getDirectory(), name );
File destinationFile = new File( resource.getTargetPath(), name );
if ( !destinationFile.getParentFile().exists() )
{
destinationFile.getParentFile().mkdirs();
}
if ( destinationFile.lastModified() < source.lastModified() )
{
FileUtils.copyFile( source, destinationFile );
}
}
}
private File getFile( String path )
{
if ( path == null )
{
return null;
}
File f = new File( path );
if ( f.isAbsolute() )
{
return f;
}
return new File( basedir, path );
}
}