blob: 5e61fd5e82997717e85838eb2e4215ae309d6de0 [file] [log] [blame]
package org.apache.archiva.repository.assembly;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.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.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.AndArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
/**
* @author Jason van Zyl
* @plexus.component role="org.apache.maven.archiva.RepositoryAssembler" role-hint="default"
*/
// todo will need to pop the processed project cache using reflection
public class DefaultRepositoryAssembler
extends AbstractLogEnabled
implements RepositoryAssembler
{
protected static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
protected static final String UTC_TIMESTAMP_PATTERN = "yyyyMMddHHmmss";
/**
* @plexus.requirement
*/
protected ArtifactFactory artifactFactory;
/**
* @plexus.requirement
*/
protected ArtifactResolver artifactResolver;
/**
* @plexus.requirement
*/
protected ArtifactRepositoryLayout repositoryLayout;
/**
* @plexus.requirement
*/
protected ArtifactRepositoryFactory artifactRepositoryFactory;
/**
* @plexus.requirement
*/
protected ArtifactMetadataSource metadataSource;
public void assemble( Set artifacts,
File localRepository,
Set remoteRepositories,
ArtifactRepositoryLayout layout,
File repositoryDirectory )
throws RepositoryAssemblyException
{
}
public void assemble( Set artifacts,
File localRepository,
Set remoteRepositories,
ArtifactFilter artifactFilter,
ArtifactRepositoryLayout layout,
File repositoryDirectory )
throws RepositoryAssemblyException
{
ArtifactRepository targetRepository = createLocalRepository( repositoryDirectory );
ArtifactResolutionResult result = null;
Artifact originatingArtifact = null;
ArtifactRepository localRepo = createLocalRepository( localRepository );
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( artifacts, originatingArtifact,
new ArrayList( remoteRepositories ),
localRepo, 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 );
}
assembleRepositoryArtifacts( result, artifactFilter, localRepo, targetRepository, repositoryDirectory );
ArtifactRepository centralRepository = findCentralRepository( project );
assembleRepositoryMetadata( result, artifactFilter, centralRepository, targetRepository );
}
private void assembleRepositoryArtifacts( ArtifactResolutionResult result,
ArtifactFilter filter,
List remoteRepositories,
ArtifactRepository localRepository,
ArtifactRepository targetRepository,
File repositoryDirectory )
throws RepositoryAssemblyException
{
try
{
// Now that we have the graph, let's try to align it to versions
// that we want and remove
// the assembly we previously populated.
FileUtils.deleteDirectory( repositoryDirectory );
repositoryDirectory.mkdirs();
for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
{
Artifact a = (Artifact) i.next();
if ( filter.include( a ) )
{
// We need to flip it back to not being resolved so we can
// look for it again!
a.setResolved( false );
artifactResolver.resolve( a, remoteRepositories, localRepository );
File targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( a ) );
FileUtils.copyFile( a.getFile(), targetFile );
writeChecksums( targetFile );
if ( !"pom".equals( a.getType() ) )
{
a = artifactFactory.createProjectArtifact( a.getGroupId(), a.getArtifactId(), a.getVersion() );
MavenProject p = projectBuilder.buildFromRepository( a, project.getRemoteArtifactRepositories(),
localRepository );
do
{
a = artifactFactory.createProjectArtifact( p.getGroupId(), p.getArtifactId(), p
.getVersion() );
setAlignment( a, groupVersionAlignments );
File sourceFile = new File( localRepository.getBasedir(), localRepository.pathOf( a ) );
if ( !sourceFile.exists() )
{
break;
}
targetFile = new File( targetRepository.getBasedir(), targetRepository.pathOf( a ) );
FileUtils.copyFile( sourceFile, targetFile );
writeChecksums( targetFile );
p = p.getParent();
}
while ( p != null );
}
}
}
}
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 assembleRepositoryMetadata( ArtifactResolutionResult result,
ArtifactFilter filter,
ArtifactRepository centralRepository,
ArtifactRepository targetRepository )
throws RepositoryAssemblyException
{
for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
{
Artifact a = (Artifact) i.next();
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
{
IOUtils.closeQuietly( 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
{
try
{
String md5 = DigestUtils.createChecksum( file, "MD5" );
String sha1 = DigestUtils.createChecksum( file, "SHA-1" );
FileUtils.writeStringToFile( new File( file.getParentFile(), file.getName() + ".md5" ),
md5.toLowerCase(), null );
FileUtils.writeStringToFile( new File( file.getParentFile(), file.getName() + ".sha1" ),
sha1.toLowerCase(), null );
}
catch ( NoSuchAlgorithmException e )
{
throw new RepositoryAssemblyException( "Unable to get write checksums: " + e.getMessage(), e );
}
}
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;
}
}