| /* |
| * 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 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; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| |
| |
| /** |
| * 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</code> will be created if they don't already exist. |
| * <code>destination</code> will be overwritten if it already exists. |
| * |
| * @param source An existing non-directory <code>File</code> to copy bytes from. |
| * @param destination A non-directory <code>File</code> to write bytes to (possibly |
| * overwriting). |
| * @throws IOException if <code>source</code> does not exist, <code>destination</code> cannot be |
| * written to, or an IO error occurs during copying. |
| * @throws java.io.FileNotFoundException if <code>destination</code> 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 ); |
| } |
| } |
| } |