package org.codehaus.mojo.appassembler; /* * The MIT License * * Copyright 2005-2007 The Codehaus. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.installer.ArtifactInstallationException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.codehaus.plexus.util.FileUtils; /** * Creates an appassembler repository. Note that this is deliberately a bit more specific than the assembly plugin * version - if it can generate a flat layout and exclude JARs, it may be a suitable replacement. * * @author <a href="mailto:kristian.nordal@gmail.com">Kristian Nordal</a> * @version $Id$ * @goal create-repository * @requiresDependencyResolution runtime * @phase package */ public class CreateRepositoryMojo extends AbstractMojo { // ----------------------------------------------------------------------- // Parameters // ----------------------------------------------------------------------- /** * The directory that will be used to assemble the artifacts in and place the bin scripts. * * @required * @parameter expression="${project.build.directory}/appassembler" */ private File assembleDirectory; /** * The directory that will be used for the dependencies, relative to <code>assembleDirectory</code>. * * @required * @parameter default-value="repo" * @todo customisation doesn't work due to the shell scripts not honouring it */ private String repoPath; /** * The layout of the generated Maven repository. Supported types - "default" (Maven2) | "legacy" (Maven1) | "flat" * (flat <code>lib/</code> style). * * @parameter default-value="default" */ private String repositoryLayout; // ----------------------------------------------------------------------- // Read-only parameters // ----------------------------------------------------------------------- /** * @readonly * @parameter expression="${project.artifacts}" */ private Set artifacts; /** * @readonly * @parameter expression="${plugin.version}" */ private String pluginVersion; /** * @readonly * @parameter expression="${localRepository}" */ private ArtifactRepository localRepository; /** * @readonly * @parameter expression="${project.artifact}" */ private Artifact projectArtifact; /** * Whether to install the booter artifacts into the repository. This may be needed if you are using the Shell script * generators. * * @parameter default-value="false" */ private boolean installBooterArtifacts; // ----------------------------------------------------------------------- // Components // ----------------------------------------------------------------------- /** @component */ private ArtifactFactory artifactFactory; /** * @component */ private ArtifactRepositoryFactory artifactRepositoryFactory; /** * @component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout" */ private Map availableRepositoryLayouts; /** @component */ private ArtifactResolver artifactResolver; /** @component */ private ArtifactMetadataSource metadataSource; public void execute() throws MojoExecutionException, MojoFailureException { // ---------------------------------------------------------------------- // Create new repository for dependencies // ---------------------------------------------------------------------- ArtifactRepositoryLayout artifactRepositoryLayout = (ArtifactRepositoryLayout) availableRepositoryLayouts.get( repositoryLayout ); if ( artifactRepositoryLayout == null ) { throw new MojoFailureException( "Unknown repository layout '" + repositoryLayout + "'." ); } // ----------------------------------------------------------------------- // Initialize // ----------------------------------------------------------------------- String path = "file://" + assembleDirectory.getAbsolutePath() + "/" + repoPath; ArtifactRepository artifactRepository = artifactRepositoryFactory.createDeploymentArtifactRepository( "appassembler", path, artifactRepositoryLayout, true ); // ----------------------------------------------------------------------- // Install the project's artifact in the new repository // ----------------------------------------------------------------------- installArtifact( projectArtifact, artifactRepository ); // ---------------------------------------------------------------------- // Install dependencies in the new repository // ---------------------------------------------------------------------- // TODO: merge with the artifacts below so no duplicate versions included for ( Iterator it = artifacts.iterator(); it.hasNext(); ) { Artifact artifact = (Artifact) it.next(); installArtifact( artifact, artifactRepository ); } if ( installBooterArtifacts ) { // ---------------------------------------------------------------------- // Install appassembler booter in the new repos // ---------------------------------------------------------------------- installBooterArtifacts( artifactRepository ); } } private void installBooterArtifacts( ArtifactRepository artifactRepository ) throws MojoExecutionException { Artifact artifact = artifactFactory.createDependencyArtifact( "org.codehaus.mojo.appassembler", "appassembler-booter", VersionRange.createFromVersion( pluginVersion ), "jar", null, Artifact.SCOPE_RUNTIME ); try { Artifact p = artifactFactory.createBuildArtifact( "org.codehaus.mojo.appassembler", "appassembler-maven-plugin", pluginVersion, "jar" ); ArtifactFilter filter = new ExcludesArtifactFilter( Collections.singletonList( "junit:junit" ) ); ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( artifact ), p, localRepository, Collections.EMPTY_LIST, metadataSource, filter ); for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); ) { Artifact a = (Artifact) i.next(); installArtifact( a, artifactRepository ); } } catch ( ArtifactResolutionException e ) { throw new MojoExecutionException( "Failed to copy artifact.", e ); } catch ( ArtifactNotFoundException e ) { throw new MojoExecutionException( "Failed to copy artifact.", e ); } } private void installArtifact( Artifact artifact, ArtifactRepository artifactRepository ) throws MojoExecutionException { if ( artifact.getFile() != null ) { try { // Necessary for the artifact's baseVersion to be set correctly // See: http://mail-archives.apache.org/mod_mbox/maven-dev/200511.mbox/%3c437288F4.4080003@apache.org%3e artifact.isSnapshot(); install( artifact.getFile(), artifact, artifactRepository ); } catch ( ArtifactInstallationException e ) { throw new MojoExecutionException( "Failed to copy artifact.", e ); } } } public void setAvailableRepositoryLayouts( Map availableRepositoryLayouts ) { this.availableRepositoryLayouts = availableRepositoryLayouts; } public void install( File source, Artifact artifact, ArtifactRepository localRepository ) throws ArtifactInstallationException { try { String localPath = localRepository.pathOf( artifact ); File destination = new File( localRepository.getBasedir(), localPath ); if ( !destination.getParentFile().exists() ) { destination.getParentFile().mkdirs(); } getLog().info( "Installing artifact " + source.getPath() + " to " + destination ); FileUtils.copyFile( source, destination ); } catch ( IOException e ) { throw new ArtifactInstallationException( "Error installing artifact: " + e.getMessage(), e ); } } }