Embed maven-repository-builder, temporary allow maven-compat with compile scope

git-svn-id: https://svn.apache.org/repos/asf/maven/plugins/trunk@1722459 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 67d4953..e35f050 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,7 +93,7 @@
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-compat</artifactId>
       <version>${mavenVersion}</version>
-      <scope>test</scope>
+<!-- <scope>test</scope> -->
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
@@ -166,9 +166,9 @@
       <version>3.0.22</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.maven.shared</groupId>
-      <artifactId>maven-repository-builder</artifactId>
-      <version>1.1-SNAPSHOT</version>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>1.6</version>
     </dependency>
     <dependency>
       <groupId>org.apache.maven.plugin-testing</groupId>
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhase.java b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhase.java
index e11e398..8799a1f 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhase.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhase.java
@@ -28,12 +28,12 @@
 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
 import org.apache.maven.plugins.assembly.model.Assembly;
 import org.apache.maven.plugins.assembly.model.Repository;
+import org.apache.maven.plugins.assembly.repository.RepositoryAssembler;
+import org.apache.maven.plugins.assembly.repository.RepositoryAssemblyException;
+import org.apache.maven.plugins.assembly.repository.RepositoryBuilderConfigSource;
+import org.apache.maven.plugins.assembly.repository.model.RepositoryInfo;
 import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
 import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
-import org.apache.maven.shared.repository.RepositoryAssembler;
-import org.apache.maven.shared.repository.RepositoryAssemblyException;
-import org.apache.maven.shared.repository.RepositoryBuilderConfigSource;
-import org.apache.maven.shared.repository.model.RepositoryInfo;
 import org.codehaus.plexus.archiver.Archiver;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/GroupVersionAlignmentWrapper.java b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/GroupVersionAlignmentWrapper.java
index 7149b32..d981909 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/GroupVersionAlignmentWrapper.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/GroupVersionAlignmentWrapper.java
@@ -27,7 +27,7 @@
  * @version $Id$
  */
 class GroupVersionAlignmentWrapper
-    implements org.apache.maven.shared.repository.model.GroupVersionAlignment
+    implements org.apache.maven.plugins.assembly.repository.model.GroupVersionAlignment
 {
 
     private final GroupVersionAlignment alignment;
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoBuilderConfigSourceWrapper.java b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoBuilderConfigSourceWrapper.java
index 0c1023d..5d012d2 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoBuilderConfigSourceWrapper.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoBuilderConfigSourceWrapper.java
@@ -21,8 +21,8 @@
 
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
+import org.apache.maven.plugins.assembly.repository.RepositoryBuilderConfigSource;
 import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.repository.RepositoryBuilderConfigSource;
 
 /**
  * @version $Id$
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoInfoWrapper.java b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoInfoWrapper.java
index 07b21cb..a1066d2 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoInfoWrapper.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/phase/wrappers/RepoInfoWrapper.java
@@ -21,7 +21,7 @@
 
 import org.apache.maven.plugins.assembly.model.GroupVersionAlignment;
 import org.apache.maven.plugins.assembly.model.Repository;
-import org.apache.maven.shared.repository.model.RepositoryInfo;
+import org.apache.maven.plugins.assembly.repository.model.RepositoryInfo;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/DefaultRepositoryAssembler.java b/src/main/java/org/apache/maven/plugins/assembly/repository/DefaultRepositoryAssembler.java
new file mode 100644
index 0000000..81a757c
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/DefaultRepositoryAssembler.java
@@ -0,0 +1,734 @@
+package org.apache.maven.plugins.assembly.repository;

+

+/*

+ * 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.artifact.Artifact;

+import org.apache.maven.artifact.ArtifactUtils;

+import org.apache.maven.artifact.factory.ArtifactFactory;

+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.ArtifactRepositoryPolicy;

+import org.apache.maven.artifact.repository.DefaultArtifactRepository;

+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;

+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;

+import org.apache.maven.artifact.repository.metadata.Versioning;

+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;

+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.AndArtifactFilter;

+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;

+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;

+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;

+import org.apache.maven.artifact.versioning.VersionRange;

+import org.apache.maven.model.Dependency;

+import org.apache.maven.model.DependencyManagement;

+import org.apache.maven.model.Exclusion;

+import org.apache.maven.plugins.assembly.repository.model.GroupVersionAlignment;

+import org.apache.maven.plugins.assembly.repository.model.RepositoryInfo;

+import org.apache.maven.project.DefaultMavenProjectBuilder;

+import org.apache.maven.project.MavenProject;

+import org.apache.maven.project.MavenProjectBuilder;

+import org.apache.maven.project.ProjectBuildingException;

+import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;

+import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;

+import org.apache.maven.shared.artifact.filter.ScopeArtifactFilter;

+import org.apache.maven.shared.utils.io.FileUtils;

+import org.apache.maven.shared.utils.io.IOUtil;

+import org.codehaus.plexus.PlexusConstants;

+import org.codehaus.plexus.PlexusContainer;

+import org.codehaus.plexus.component.annotations.Component;

+import org.codehaus.plexus.component.annotations.Requirement;

+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;

+import org.codehaus.plexus.context.Context;

+import org.codehaus.plexus.context.ContextException;

+import org.codehaus.plexus.logging.AbstractLogEnabled;

+import org.codehaus.plexus.logging.Logger;

+import org.codehaus.plexus.logging.console.ConsoleLogger;

+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileWriter;

+import java.io.IOException;

+import java.io.Writer;

+import java.lang.reflect.Field;

+import java.text.DateFormat;

+import java.text.SimpleDateFormat;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collections;

+import java.util.Date;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+import java.util.TimeZone;

+

+import static org.apache.commons.codec.digest.DigestUtils.md5Hex;

+import static org.apache.commons.codec.digest.DigestUtils.shaHex;

+

+/**

+ * @author Jason van Zyl

+ */

+

+// todo will need to pop the processed project cache using reflection

+@Component( role = RepositoryAssembler.class )

+public class DefaultRepositoryAssembler

+    extends AbstractLogEnabled

+    implements RepositoryAssembler, Contextualizable

+{

+    private static final String[] PREFERRED_RESOLVER_HINTS = { "project-cache-aware", // Provided in Maven 2.1-SNAPSHOT

+        "default" };

+

+    protected static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );

+

+    protected static final String UTC_TIMESTAMP_PATTERN = "yyyyMMddHHmmss";

+

+    @Requirement

+    protected ArtifactFactory artifactFactory;

+

+    // Replaced by Contextualizable code, to select the resolver in order of preference.

+    //

+    // @plexus.requirement

+    //

+    protected ArtifactResolver artifactResolver;

+

+    @Requirement

+    protected ArtifactRepositoryLayout repositoryLayout;

+

+    @Requirement

+    protected ArtifactRepositoryFactory artifactRepositoryFactory;

+

+    @Requirement

+    protected ArtifactMetadataSource metadataSource;

+

+    @Requirement

+    protected MavenProjectBuilder projectBuilder;

+

+    public DefaultRepositoryAssembler()

+    {

+        // used for plexus init.

+    }

+

+    public DefaultRepositoryAssembler( ArtifactFactory artifactFactory, ArtifactResolver artifactResolver,

+                                       ArtifactRepositoryLayout repositoryLayout,

+                                       ArtifactRepositoryFactory artifactRepositoryFactory,

+                                       ArtifactMetadataSource metadataSource, MavenProjectBuilder projectBuilder )

+    {

+        // used for testing, primarily.

+        this.artifactFactory = artifactFactory;

+        this.artifactResolver = artifactResolver;

+        this.repositoryLayout = repositoryLayout;

+        this.artifactRepositoryFactory = artifactRepositoryFactory;

+        this.metadataSource = metadataSource;

+        this.projectBuilder = projectBuilder;

+

+        enableLogging( new ConsoleLogger( Logger.LEVEL_DEBUG, getClass().getName() + "::Internal" ) );

+    }

+

+    public void buildRemoteRepository( File repositoryDirectory, RepositoryInfo repository,

+                                       RepositoryBuilderConfigSource configSource )

+        throws RepositoryAssemblyException

+    {

+        MavenProject project = configSource.getProject();

+        ArtifactRepository localRepository = configSource.getLocalRepository();

+

+        Map groupVersionAlignments = createGroupVersionAlignments( repository.getGroupVersionAlignments() );

+

+        ArtifactRepository targetRepository = createLocalRepository( repositoryDirectory );

+

+        ArtifactResolutionResult result = null;

+

+        Set dependencyArtifacts = project.getDependencyArtifacts();

+

+        if ( dependencyArtifacts == null )

+        {

+            Logger logger = getLogger();

+

+            if ( logger.isDebugEnabled() )

+            {

+                logger.debug( "dependency-artifact set for project: " + project.getId()

+                                  + " is null. Skipping repository processing." );

+            }

+

+            return;

+        }

+

+        try

+        {

+            // i have to get everything first as a filter or transformation here

+            // doesn't seem to work

+            // to align everything. If I use a filter to change the version on

+            // the fly then I get the

+            // I get JARs but no POMs, and in some directories POMs with no

+            // JARs.

+

+            // FIXME I'm not getting runtime dependencies here

+            result = artifactResolver.resolveTransitively( dependencyArtifacts, project.getArtifact(),

+                                                           getManagedVersionMap( project ), localRepository,

+                                                           project.getRemoteArtifactRepositories(), metadataSource );

+        }

+        catch ( ArtifactResolutionException e )

+        {

+            throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );

+        }

+        catch ( ArtifactNotFoundException e )

+        {

+            throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );

+        }

+        catch ( InvalidVersionSpecificationException e )

+        {

+            throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );

+        }

+

+        try

+        {

+            // Blow the cache in the project builder so that we get POMs again

+            // on this next download

+            invalidateProccessedProjectCache();

+        }

+        catch ( Exception e )

+        {

+            throw new RepositoryAssemblyException( "Error invalidating the processed project cache.", e );

+        }

+

+        ArtifactFilter filter = buildRepositoryFilter( repository, project );

+

+        assembleRepositoryArtifacts( result, filter, project, localRepository, targetRepository, repositoryDirectory,

+                                     groupVersionAlignments );

+

+        ArtifactRepository centralRepository = findCentralRepository( project );

+

+        if ( repository.isIncludeMetadata() )

+        {

+            assembleRepositoryMetadata( result, filter, centralRepository, targetRepository );

+        }

+

+        addPomWithAncestry( project.getArtifact(), project.getRemoteArtifactRepositories(), localRepository,

+                            targetRepository, groupVersionAlignments, project );

+    }

+

+    private ArtifactFilter buildRepositoryFilter( RepositoryInfo repository, MavenProject project )

+    {

+        AndArtifactFilter filter = new AndArtifactFilter();

+

+        ArtifactFilter scopeFilter = new ScopeArtifactFilter( repository.getScope() );

+        filter.add( scopeFilter );

+

+        // ----------------------------------------------------------------------------

+        // Includes

+        //

+        // We'll take everything if no includes are specified to try and make

+        // this

+        // process more maintainable. Don't want to have to update the assembly

+        // descriptor everytime the POM is updated.

+        // ----------------------------------------------------------------------------

+

+        List includes = repository.getIncludes();

+

+        if ( ( includes == null ) || includes.isEmpty() )

+        {

+            List<String> patterns = new ArrayList<String>();

+

+            Set projectArtifacts = project.getDependencyArtifacts();

+

+            if ( projectArtifacts != null )

+            {

+                for ( Object projectArtifact : projectArtifacts )

+                {

+                    Artifact artifact = (Artifact) projectArtifact;

+

+                    patterns.add( artifact.getDependencyConflictId() );

+                }

+            }

+

+            PatternIncludesArtifactFilter includeFilter = new PatternIncludesArtifactFilter( patterns, true );

+

+            filter.add( includeFilter );

+        }

+        else

+        {

+            filter.add( new PatternIncludesArtifactFilter( repository.getIncludes(), true ) );

+        }

+

+        // ----------------------------------------------------------------------------

+        // Excludes

+        //

+        // We still want to make it easy to exclude a few things even if we

+        // slurp

+        // up everything.

+        // ----------------------------------------------------------------------------

+

+        List excludes = repository.getExcludes();

+

+        if ( ( excludes != null ) && !excludes.isEmpty() )

+        {

+            filter.add( new PatternExcludesArtifactFilter( repository.getExcludes(), true ) );

+        }

+

+        return filter;

+    }

+

+    private void assembleRepositoryArtifacts( ArtifactResolutionResult result, ArtifactFilter filter,

+                                              MavenProject project, ArtifactRepository localRepository,

+                                              ArtifactRepository targetRepository, File repositoryDirectory,

+                                              Map groupVersionAlignments )

+        throws RepositoryAssemblyException

+    {

+        try

+        {

+            // Now that we have the graph, let's try to align it to versions

+            // that we want and remove

+            // the repository we previously populated.

+            FileUtils.deleteDirectory( repositoryDirectory );

+

+            FileUtils.mkdir( repositoryDirectory.getAbsolutePath() );

+

+            for ( Object o : result.getArtifacts() )

+            {

+                Artifact a = (Artifact) o;

+

+                if ( filter.include( a ) )

+                {

+                    getLogger().debug( "Re-resolving: " + a + " for repository assembly." );

+

+                    setAlignment( a, groupVersionAlignments );

+

+                    // We need to flip it back to not being resolved so we can

+                    // look for it again!

+                    a.setResolved( false );

+

+                    artifactResolver.resolve( a, project.getRemoteArtifactRepositories(), localRepository );

+

+                    a.setVersion( a.getBaseVersion() );

+

+                    File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( a ) );

+                    FileUtils.copyFile( a.getFile(), targetFile );

+

+                    writeChecksums( targetFile );

+

+                    addPomWithAncestry( a, project.getRemoteArtifactRepositories(), localRepository, targetRepository,

+                                        groupVersionAlignments, project );

+                }

+            }

+        }

+        catch ( ArtifactResolutionException e )

+        {

+            throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );

+        }

+        catch ( ArtifactNotFoundException e )

+        {

+            throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );

+        }

+        catch ( IOException e )

+        {

+            throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );

+        }

+    }

+

+    private void addPomWithAncestry( final Artifact artifact, List remoteArtifactRepositories,

+                                     ArtifactRepository localRepository, ArtifactRepository targetRepository,

+                                     Map groupVersionAlignments, MavenProject masterProject )

+        throws RepositoryAssemblyException

+    {

+        String type = artifact.getType();

+        Map refs = masterProject.getProjectReferences();

+

+        String projectKey = ArtifactUtils.versionlessKey( artifact );

+

+        MavenProject p;

+        if ( artifact == masterProject.getArtifact() )

+        {

+            p = masterProject;

+        }

+        else if ( refs.containsKey( projectKey ) )

+        {

+            p = (MavenProject) refs.get( projectKey );

+        }

+        else

+        {

+            try

+            {

+                artifact.isSnapshot();

+

+                Artifact pomArtifact =

+                    artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),

+                                                           artifact.getBaseVersion() );

+

+                getLogger().debug( "Building MavenProject instance for: " + pomArtifact

+                                       + ". NOTE: This SHOULD BE available in the Artifact API! ...but it's not." );

+                p = projectBuilder.buildFromRepository( pomArtifact, remoteArtifactRepositories, localRepository );

+            }

+            catch ( ProjectBuildingException e )

+            {

+                throw new RepositoryAssemblyException( "Error reading POM for: " + artifact.getId(), e );

+            }

+        }

+

+        // if we're dealing with a POM artifact, then we've already copied the POM itself; only process ancestry.

+        // NOTE: We need to preserve the original artifact for comparison here.

+        if ( "pom".equals( type ) )

+        {

+            p = p.getParent();

+        }

+

+        while ( p != null )

+        {

+            Artifact destArtifact =

+                artifactFactory.createProjectArtifact( p.getGroupId(), p.getArtifactId(), p.getVersion() );

+

+            setAlignment( destArtifact, groupVersionAlignments );

+

+            File sourceFile = p.getFile();

+

+            // try to use the POM file from the project instance itself first.

+            if ( ( sourceFile == null ) || !sourceFile.exists() )

+            {

+                // something that hasn't been realigned yet...we want to read from the original location.

+                Artifact srcArtifact =

+                    artifactFactory.createProjectArtifact( p.getGroupId(), p.getArtifactId(), p.getVersion() );

+

+                sourceFile = new File( localRepository.getBasedir(), localRepository.pathOf( srcArtifact ) );

+            }

+

+            if ( !sourceFile.exists() )

+            {

+                break;

+            }

+

+            File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( destArtifact ) );

+

+            try

+            {

+                FileUtils.copyFile( sourceFile, targetFile );

+            }

+            catch ( IOException e )

+            {

+                throw new RepositoryAssemblyException( "Error writing POM metdata: " + destArtifact.getId(), e );

+            }

+

+            try

+            {

+                writeChecksums( targetFile );

+            }

+            catch ( IOException e )

+            {

+                throw new RepositoryAssemblyException( "Error writing checksums for POM: " + destArtifact.getId(), e );

+            }

+

+            p = p.getParent();

+        }

+    }

+

+    private ArtifactRepository findCentralRepository( MavenProject project )

+    {

+        ArtifactRepository centralRepository = null;

+        for ( Object o : project.getRemoteArtifactRepositories() )

+        {

+            ArtifactRepository r = (ArtifactRepository) o;

+            if ( "central".equals( r.getId() ) )

+            {

+                centralRepository = r;

+            }

+        }

+

+        return centralRepository;

+    }

+

+    private void assembleRepositoryMetadata( ArtifactResolutionResult result, ArtifactFilter filter,

+                                             ArtifactRepository centralRepository, ArtifactRepository targetRepository )

+        throws RepositoryAssemblyException

+    {

+        for ( Object o : result.getArtifacts() )

+        {

+            Artifact a = (Artifact) o;

+

+            if ( filter.include( a ) )

+            {

+                Versioning v = new Versioning();

+

+                v.setRelease( a.getVersion() );

+

+                v.setLatest( a.getVersion() );

+

+                v.addVersion( a.getVersion() );

+

+                v.setLastUpdated( getUtcDateFormatter().format( new Date() ) );

+

+                ArtifactRepositoryMetadata metadata = new ArtifactRepositoryMetadata( a, v );

+                String path = targetRepository.pathOfLocalRepositoryMetadata( metadata, centralRepository );

+                File metadataFile = new File( targetRepository.getBasedir(), path );

+

+                MetadataXpp3Writer metadataWriter = new MetadataXpp3Writer();

+

+                Writer writer = null;

+                try

+                {

+                    writer = new FileWriter( metadataFile );

+

+                    metadataWriter.write( writer, metadata.getMetadata() );

+                }

+                catch ( IOException e )

+                {

+                    throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );

+                }

+                finally

+                {

+                    IOUtil.close( writer );

+                }

+

+                try

+                {

+                    writeChecksums( metadataFile );

+

+                    File metadataFileRemote = new File( targetRepository.getBasedir(),

+                                                        targetRepository.pathOfRemoteRepositoryMetadata( metadata ) );

+

+                    FileUtils.copyFile( metadataFile, metadataFileRemote );

+

+                    FileUtils.copyFile( new File( metadataFile.getParentFile(), metadataFile.getName() + ".sha1" ),

+                                        new File( metadataFileRemote.getParentFile(),

+                                                  metadataFileRemote.getName() + ".sha1" ) );

+

+                    FileUtils.copyFile( new File( metadataFile.getParentFile(), metadataFile.getName() + ".md5" ),

+                                        new File( metadataFileRemote.getParentFile(),

+                                                  metadataFileRemote.getName() + ".md5" ) );

+                }

+                catch ( IOException e )

+                {

+                    throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );

+                }

+            }

+        }

+    }

+

+    private void writeChecksums( File file )

+        throws IOException, RepositoryAssemblyException

+    {

+        FileInputStream data = new FileInputStream( file );

+        String md5 = md5Hex( data ).toUpperCase();

+        data.close();

+        FileInputStream data1 = new FileInputStream( file );

+        String sha1 = shaHex( data1 ).toUpperCase();

+        data1.close();

+

+        FileUtils.fileWrite( new File( file.getParentFile(), file.getName() + ".md5" ).getAbsolutePath(),

+                             md5.toLowerCase() );

+        FileUtils.fileWrite( new File( file.getParentFile(), file.getName() + ".sha1" ).getAbsolutePath(),

+                             sha1.toLowerCase() );

+    }

+

+    protected Map createGroupVersionAlignments( List versionAlignments )

+    {

+        Map groupVersionAlignments = new HashMap();

+

+        if ( versionAlignments != null )

+        {

+            for ( Object versionAlignment : versionAlignments )

+            {

+                GroupVersionAlignment alignment = (GroupVersionAlignment) versionAlignment;

+

+                groupVersionAlignments.put( alignment.getId(), alignment );

+            }

+        }

+

+        return groupVersionAlignments;

+    }

+

+    protected static DateFormat getUtcDateFormatter()

+    {

+        DateFormat utcDateFormatter = new SimpleDateFormat( UTC_TIMESTAMP_PATTERN );

+        utcDateFormatter.setTimeZone( UTC_TIME_ZONE );

+        return utcDateFormatter;

+    }

+

+    protected ArtifactRepository createLocalRepository( File directory )

+    {

+        String localRepositoryUrl = directory.getAbsolutePath();

+

+        if ( !localRepositoryUrl.startsWith( "file:" ) )

+        {

+            localRepositoryUrl = "file://" + localRepositoryUrl;

+        }

+

+        return createRepository( "local", localRepositoryUrl, false, true,

+                                 ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );

+    }

+

+    public ArtifactRepository createRepository( String repositoryId, String repositoryUrl, boolean offline,

+                                                boolean updateSnapshots, String globalChecksumPolicy )

+    {

+        ArtifactRepository localRepository =

+            new DefaultArtifactRepository( repositoryId, repositoryUrl, repositoryLayout );

+

+        boolean snapshotPolicySet = false;

+

+        if ( offline )

+        {

+            snapshotPolicySet = true;

+        }

+

+        if ( !snapshotPolicySet && updateSnapshots )

+        {

+            artifactRepositoryFactory.setGlobalUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS );

+        }

+

+        artifactRepositoryFactory.setGlobalChecksumPolicy( globalChecksumPolicy );

+

+        return localRepository;

+    }

+

+    private void invalidateProccessedProjectCache()

+        throws Exception

+    {

+        Class klass = DefaultMavenProjectBuilder.class;

+

+        try

+        {

+            Field field = klass.getDeclaredField( "processedProjectCache" );

+

+            field.setAccessible( true );

+

+            Object cache = field.get( projectBuilder );

+

+            cache.getClass().getDeclaredMethod( "clear", null ).invoke( cache, null );

+

+            field.setAccessible( false );

+        }

+        catch ( NoSuchFieldException e )

+        {

+            // fine... no field, no cache. we'll ignore it.

+        }

+    }

+

+    private void setAlignment( Artifact artifact, Map groupVersionAlignments )

+    {

+        GroupVersionAlignment alignment = (GroupVersionAlignment) groupVersionAlignments.get( artifact.getGroupId() );

+

+        if ( alignment != null )

+        {

+            if ( !alignment.getExcludes().contains( artifact.getArtifactId() ) )

+            {

+                artifact.setVersion( alignment.getVersion() );

+            }

+        }

+    }

+

+    // TODO: Remove this, once we can depend on Maven 2.0.7 or later...in which

+    // MavenProject.getManagedVersionMap() exists. This is from MNG-1577.

+    private Map getManagedVersionMap( MavenProject project )

+        throws InvalidVersionSpecificationException

+    {

+        DependencyManagement dependencyManagement = project.getModel().getDependencyManagement();

+

+        Map<String, Artifact> map;

+        List deps = ( dependencyManagement == null ) ? null : dependencyManagement.getDependencies();

+        if ( ( deps != null ) && ( deps.size() > 0 ) )

+        {

+            map = new HashMap<String, Artifact>();

+

+            if ( getLogger().isDebugEnabled() )

+            {

+                getLogger().debug( "Adding managed dependencies for " + project.getId() );

+            }

+

+            for ( Object o1 : dependencyManagement.getDependencies() )

+            {

+                Dependency d = (Dependency) o1;

+

+                VersionRange versionRange = VersionRange.createFromVersionSpec( d.getVersion() );

+                Artifact artifact =

+                    artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange,

+                                                              d.getType(), d.getClassifier(), d.getScope(),

+                                                              d.isOptional() );

+                if ( getLogger().isDebugEnabled() )

+                {

+                    getLogger().debug( "  " + artifact );

+                }

+

+                // If the dependencyManagement section listed exclusions,

+                // add them to the managed artifacts here so that transitive

+                // dependencies will be excluded if necessary.

+                if ( ( null != d.getExclusions() ) && !d.getExclusions().isEmpty() )

+                {

+                    List<String> exclusions = new ArrayList<String>();

+                    for ( Object o : d.getExclusions() )

+                    {

+                        Exclusion e = (Exclusion) o;

+                        exclusions.add( e.getGroupId() + ":" + e.getArtifactId() );

+                    }

+                    ExcludesArtifactFilter eaf = new ExcludesArtifactFilter( exclusions );

+                    artifact.setDependencyFilter( eaf );

+                }

+                else

+                {

+                    artifact.setDependencyFilter( null );

+                }

+                map.put( d.getManagementKey(), artifact );

+            }

+        }

+        else

+        {

+            map = Collections.emptyMap();

+        }

+        return map;

+    }

+

+    public void contextualize( Context context )

+        throws ContextException

+    {

+        PlexusContainer container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );

+

+        for ( String hint : PREFERRED_RESOLVER_HINTS )

+        {

+            try

+            {

+                artifactResolver = (ArtifactResolver) container.lookup( ArtifactResolver.ROLE, hint );

+                break;

+            }

+            catch ( ComponentLookupException e )

+            {

+                getLogger().debug( "No ArtifactResolver with hint " + hint );

+            }

+        }

+

+        if ( artifactResolver == null )

+        {

+            try

+            {

+                artifactResolver = (ArtifactResolver) container.lookup( ArtifactResolver.ROLE );

+            }

+            catch ( ComponentLookupException e )

+            {

+                getLogger().debug( "Cannot find ArtifactResolver with no hint.", e );

+            }

+        }

+

+        if ( artifactResolver == null )

+        {

+            throw new ContextException(

+                "Failed to lookup a valid ArtifactResolver implementation. Tried hints:\n" + Arrays.asList(

+                    PREFERRED_RESOLVER_HINTS ) );

+        }

+    }

+}

diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryAssembler.java b/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryAssembler.java
new file mode 100644
index 0000000..0188af1
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryAssembler.java
@@ -0,0 +1,34 @@
+package org.apache.maven.plugins.assembly.repository;

+

+/*

+ * 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 java.io.File;

+

+import org.apache.maven.plugins.assembly.repository.model.RepositoryInfo;

+

+/**

+ * @author Jason van Zyl

+ */

+public interface RepositoryAssembler

+{

+    void buildRemoteRepository( File repositoryDirectory, RepositoryInfo repository,

+                                RepositoryBuilderConfigSource configSource )

+        throws RepositoryAssemblyException;

+}

diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryAssemblyException.java b/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryAssemblyException.java
new file mode 100644
index 0000000..cc424c9
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryAssemblyException.java
@@ -0,0 +1,44 @@
+package org.apache.maven.plugins.assembly.repository;

+

+/*

+ * 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.

+ */

+

+/**

+ * @author Jason van Zyl

+ */

+public class RepositoryAssemblyException

+    extends Exception

+{

+    private static final long serialVersionUID = 1L;

+

+    public RepositoryAssemblyException( String string )

+    {

+        super( string );

+    }

+

+    public RepositoryAssemblyException( String string, Throwable throwable )

+    {

+        super( string, throwable );

+    }

+

+    public RepositoryAssemblyException( Throwable throwable )

+    {

+        super( throwable );

+    }

+}

diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryBuilderConfigSource.java b/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryBuilderConfigSource.java
new file mode 100644
index 0000000..0bf62c6
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/RepositoryBuilderConfigSource.java
@@ -0,0 +1,35 @@
+package org.apache.maven.plugins.assembly.repository;

+

+/*

+ * 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.artifact.repository.ArtifactRepository;

+import org.apache.maven.project.MavenProject;

+

+/**

+ * 

+ */

+public interface RepositoryBuilderConfigSource

+{

+

+    MavenProject getProject();

+

+    ArtifactRepository getLocalRepository();

+

+}

diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/model/DefaultRepositoryInfo.java b/src/main/java/org/apache/maven/plugins/assembly/repository/model/DefaultRepositoryInfo.java
new file mode 100644
index 0000000..b77ba6a
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/model/DefaultRepositoryInfo.java
@@ -0,0 +1,93 @@
+package org.apache.maven.plugins.assembly.repository.model;

+

+/*

+ * 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.artifact.Artifact;

+

+import java.util.List;

+

+/**

+ * 

+ */

+public class DefaultRepositoryInfo

+    implements RepositoryInfo

+{

+

+    private boolean includeMetadata;

+

+    private String scope = Artifact.SCOPE_COMPILE;

+

+    private List includes;

+

+    private List groupVersionAlignments;

+

+    private List excludes;

+

+    public List getExcludes()

+    {

+        return excludes;

+    }

+

+    public void setGroupVersionAlignments( List groupVersionAlignments )

+    {

+        this.groupVersionAlignments = groupVersionAlignments;

+    }

+

+    public void setIncludeMetadata( boolean includeMetadata )

+    {

+        this.includeMetadata = includeMetadata;

+    }

+

+    public void setIncludes( List includes )

+    {

+        this.includes = includes;

+    }

+

+    public void setScope( String scope )

+    {

+        this.scope = scope;

+    }

+

+    public List getGroupVersionAlignments()

+    {

+        return groupVersionAlignments;

+    }

+

+    public List getIncludes()

+    {

+        return includes;

+    }

+

+    public String getScope()

+    {

+        return scope;

+    }

+

+    public boolean isIncludeMetadata()

+    {

+        return includeMetadata;

+    }

+

+    public void setExcludes( List excludes )

+    {

+        this.excludes = excludes;

+    }

+

+}

diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/model/GroupVersionAlignment.java b/src/main/java/org/apache/maven/plugins/assembly/repository/model/GroupVersionAlignment.java
new file mode 100644
index 0000000..70cb50b
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/model/GroupVersionAlignment.java
@@ -0,0 +1,36 @@
+package org.apache.maven.plugins.assembly.repository.model;

+

+/*

+ * 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 java.util.List;

+

+/**

+ * 

+ */

+public interface GroupVersionAlignment

+{

+

+    String getId();

+

+    List getExcludes();

+

+    String getVersion();

+

+}

diff --git a/src/main/java/org/apache/maven/plugins/assembly/repository/model/RepositoryInfo.java b/src/main/java/org/apache/maven/plugins/assembly/repository/model/RepositoryInfo.java
new file mode 100644
index 0000000..d2f1e9d
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/assembly/repository/model/RepositoryInfo.java
@@ -0,0 +1,40 @@
+package org.apache.maven.plugins.assembly.repository.model;

+

+/*

+ * 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 java.util.List;

+

+/**

+ * 

+ */

+public interface RepositoryInfo

+{

+

+    List getGroupVersionAlignments();

+

+    boolean isIncludeMetadata();

+

+    String getScope();

+

+    List getIncludes();

+

+    List getExcludes();

+

+}

diff --git a/src/test/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhaseTest.java b/src/test/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhaseTest.java
index 3476333..5cc10b3 100644
--- a/src/test/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhaseTest.java
+++ b/src/test/java/org/apache/maven/plugins/assembly/archive/phase/RepositoryAssemblyPhaseTest.java
@@ -28,13 +28,13 @@
 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
 import org.apache.maven.plugins.assembly.model.Assembly;
 import org.apache.maven.plugins.assembly.model.Repository;
+import org.apache.maven.plugins.assembly.repository.RepositoryAssembler;
+import org.apache.maven.plugins.assembly.repository.RepositoryAssemblyException;
+import org.apache.maven.plugins.assembly.repository.RepositoryBuilderConfigSource;
+import org.apache.maven.plugins.assembly.repository.model.RepositoryInfo;
 import org.apache.maven.plugins.assembly.testutils.TestFileManager;
 import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
 import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.repository.RepositoryAssembler;
-import org.apache.maven.shared.repository.RepositoryAssemblyException;
-import org.apache.maven.shared.repository.RepositoryBuilderConfigSource;
-import org.apache.maven.shared.repository.model.RepositoryInfo;
 import org.codehaus.plexus.archiver.Archiver;
 import org.codehaus.plexus.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.FileSet;