blob: ce29b991d11e1b9b0888aa13c5aca318eb795f21 [file] [log] [blame]
package org.apache.maven.archiva.repository.metadata;
/*
* 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.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.maven.archiva.common.utils.PathUtil;
import org.apache.maven.archiva.common.utils.VersionComparator;
import org.apache.maven.archiva.common.utils.VersionUtil;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ConfigurationNames;
import org.apache.maven.archiva.configuration.FileTypes;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Plugin;
import org.apache.maven.archiva.model.ProjectReference;
import org.apache.maven.archiva.model.SnapshotVersion;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.ContentNotFoundException;
import org.apache.maven.archiva.repository.ManagedRepositoryContent;
import org.apache.maven.archiva.repository.RemoteRepositoryContent;
import org.apache.maven.archiva.repository.layout.LayoutException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.registry.Registry;
import org.codehaus.plexus.registry.RegistryListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import org.apache.commons.io.FileUtils;
/**
* MetadataTools
*
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.maven.archiva.repository.metadata.MetadataTools"
*/
public class MetadataTools
implements RegistryListener, Initializable
{
private static Logger log = LoggerFactory.getLogger( MetadataTools.class );
public static final String MAVEN_METADATA = "maven-metadata.xml";
private static final char PATH_SEPARATOR = '/';
private static final char GROUP_SEPARATOR = '.';
/**
* @plexus.requirement
*/
private ArchivaConfiguration configuration;
/**
* @plexus.requirement
*/
private FileTypes filetypes;
private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[] { ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };
private List<String> artifactPatterns;
private Map<String, Set<String>> proxies;
private static final char NUMS[] = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private SimpleDateFormat lastUpdatedFormat;
public MetadataTools()
{
lastUpdatedFormat = new SimpleDateFormat( "yyyyMMddHHmmss" );
lastUpdatedFormat.setTimeZone( DateUtils.UTC_TIME_ZONE );
}
public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
if ( ConfigurationNames.isProxyConnector( propertyName ) )
{
initConfigVariables();
}
}
public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
/* nothing to do */
}
/**
* Gather the set of snapshot versions found in a particular versioned reference.
*
* @return the Set of snapshot artifact versions found.
* @throws LayoutException
* @throws ContentNotFoundException
*/
public Set<String> gatherSnapshotVersions( ManagedRepositoryContent managedRepository, VersionedReference reference )
throws LayoutException, IOException, ContentNotFoundException
{
Set<String> foundVersions = managedRepository.getVersions( reference );
// Next gather up the referenced 'latest' versions found in any proxied repositories
// maven-metadata-${proxyId}.xml files that may be present.
// Does this repository have a set of remote proxied repositories?
Set<String> proxiedRepoIds = this.proxies.get( managedRepository.getId() );
if ( CollectionUtils.isNotEmpty( proxiedRepoIds ) )
{
String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
baseVersion = baseVersion.substring( 0, baseVersion.indexOf( VersionUtil.SNAPSHOT ) - 1 );
// Add in the proxied repo version ids too.
Iterator<String> it = proxiedRepoIds.iterator();
while ( it.hasNext() )
{
String proxyId = it.next();
ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata( managedRepository, reference, proxyId );
if ( proxyMetadata == null )
{
// There is no proxy metadata, skip it.
continue;
}
// Is there some snapshot info?
SnapshotVersion snapshot = proxyMetadata.getSnapshotVersion();
if ( snapshot != null )
{
String timestamp = snapshot.getTimestamp();
int buildNumber = snapshot.getBuildNumber();
// Only interested in the timestamp + buildnumber.
if ( StringUtils.isNotBlank( timestamp ) && ( buildNumber > 0 ) )
{
foundVersions.add( baseVersion + "-" + timestamp + "-" + buildNumber );
}
}
}
}
return foundVersions;
}
/**
* Take a path to a maven-metadata.xml, and attempt to translate it to a VersionedReference.
*
* @param path
* @return
*/
public VersionedReference toVersionedReference( String path )
throws RepositoryMetadataException
{
if ( !path.endsWith( "/" + MAVEN_METADATA ) )
{
throw new RepositoryMetadataException( "Cannot convert to versioned reference, not a metadata file. " );
}
VersionedReference reference = new VersionedReference();
String normalizedPath = StringUtils.replace( path, "\\", "/" );
String pathParts[] = StringUtils.split( normalizedPath, '/' );
int versionOffset = pathParts.length - 2;
int artifactIdOffset = versionOffset - 1;
int groupIdEnd = artifactIdOffset - 1;
reference.setVersion( pathParts[versionOffset] );
if ( !hasNumberAnywhere( reference.getVersion() ) )
{
// Scary check, but without it, all paths are version references;
throw new RepositoryMetadataException(
"Not a versioned reference, as version id on path has no number in it." );
}
reference.setArtifactId( pathParts[artifactIdOffset] );
StringBuffer gid = new StringBuffer();
for ( int i = 0; i <= groupIdEnd; i++ )
{
if ( i > 0 )
{
gid.append( "." );
}
gid.append( pathParts[i] );
}
reference.setGroupId( gid.toString() );
return reference;
}
private boolean hasNumberAnywhere( String version )
{
return StringUtils.indexOfAny( version, NUMS ) != ( -1 );
}
public ProjectReference toProjectReference( String path )
throws RepositoryMetadataException
{
if ( !path.endsWith( "/" + MAVEN_METADATA ) )
{
throw new RepositoryMetadataException( "Cannot convert to versioned reference, not a metadata file. " );
}
ProjectReference reference = new ProjectReference();
String normalizedPath = StringUtils.replace( path, "\\", "/" );
String pathParts[] = StringUtils.split( normalizedPath, '/' );
// Assume last part of the path is the version.
int artifactIdOffset = pathParts.length - 2;
int groupIdEnd = artifactIdOffset - 1;
reference.setArtifactId( pathParts[artifactIdOffset] );
StringBuffer gid = new StringBuffer();
for ( int i = 0; i <= groupIdEnd; i++ )
{
if ( i > 0 )
{
gid.append( "." );
}
gid.append( pathParts[i] );
}
reference.setGroupId( gid.toString() );
return reference;
}
public String toPath( ProjectReference reference )
{
StringBuffer path = new StringBuffer();
path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
path.append( MAVEN_METADATA );
return path.toString();
}
public String toPath( VersionedReference reference )
{
StringBuffer path = new StringBuffer();
path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
if ( reference.getVersion() != null )
{
// add the version only if it is present
path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
}
path.append( MAVEN_METADATA );
return path.toString();
}
private String formatAsDirectory( String directory )
{
return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
}
/**
* Adjusts a path for a metadata.xml file to its repository specific path.
*
* @param repository the repository to base new path off of.
* @param path the path to the metadata.xml file to adjust the name of.
* @return the newly adjusted path reference to the repository specific metadata path.
*/
public String getRepositorySpecificName( RemoteRepositoryContent repository, String path )
{
return getRepositorySpecificName( repository.getId(), path );
}
/**
* Adjusts a path for a metadata.xml file to its repository specific path.
*
* @param proxyId the repository id to base new path off of.
* @param path the path to the metadata.xml file to adjust the name of.
* @return the newly adjusted path reference to the repository specific metadata path.
*/
public String getRepositorySpecificName( String proxyId, String path )
{
StringBuffer ret = new StringBuffer();
int idx = path.lastIndexOf( "/" );
if ( idx > 0 )
{
ret.append( path.substring( 0, idx + 1 ) );
}
// TODO: need to filter out 'bad' characters from the proxy id.
ret.append( "maven-metadata-" ).append( proxyId ).append( ".xml" );
return ret.toString();
}
public void initialize()
throws InitializationException
{
this.artifactPatterns = new ArrayList<String>();
this.proxies = new HashMap<String, Set<String>>();
initConfigVariables();
configuration.addChangeListener( this );
}
public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
ProjectReference reference, String proxyId )
{
String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
File metadataFile = new File( managedRepository.getRepoRoot(), metadataPath );
if ( !metadataFile.exists() || !metadataFile.isFile() )
{
// Nothing to do. return null.
return null;
}
try
{
return RepositoryMetadataReader.read( metadataFile );
}
catch ( RepositoryMetadataException e )
{
// TODO: [monitor] consider a monitor for this event.
// TODO: consider a read-redo on monitor return code?
log.warn( "Unable to read metadata: " + metadataFile.getAbsolutePath(), e );
return null;
}
}
public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
String logicalResource, String proxyId )
{
String metadataPath = getRepositorySpecificName( proxyId, logicalResource );
File metadataFile = new File( managedRepository.getRepoRoot(), metadataPath );
if ( !metadataFile.exists() || !metadataFile.isFile() )
{
// Nothing to do. return null.
return null;
}
try
{
return RepositoryMetadataReader.read( metadataFile );
}
catch ( RepositoryMetadataException e )
{
// TODO: [monitor] consider a monitor for this event.
// TODO: consider a read-redo on monitor return code?
log.warn( "Unable to read metadata: " + metadataFile.getAbsolutePath(), e );
return null;
}
}
public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
VersionedReference reference, String proxyId )
{
String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
File metadataFile = new File( managedRepository.getRepoRoot(), metadataPath );
if ( !metadataFile.exists() || !metadataFile.isFile() )
{
// Nothing to do. return null.
return null;
}
try
{
return RepositoryMetadataReader.read( metadataFile );
}
catch ( RepositoryMetadataException e )
{
// TODO: [monitor] consider a monitor for this event.
// TODO: consider a read-redo on monitor return code?
log.warn( "Unable to read metadata: " + metadataFile.getAbsolutePath(), e );
return null;
}
}
public void updateMetadata( ManagedRepositoryContent managedRepository, String logicalResource) throws RepositoryMetadataException
{
final File metadataFile = new File(managedRepository.getRepoRoot(), logicalResource);
ArchivaRepositoryMetadata metadata = null;
//Gather and merge all metadata available
List<ArchivaRepositoryMetadata> metadatas = getMetadatasForManagedRepository(managedRepository, logicalResource);
for (ArchivaRepositoryMetadata proxiedMetadata : metadatas)
{
if (metadata == null)
{
metadata = proxiedMetadata;
continue;
}
metadata = RepositoryMetadataMerge.merge(metadata, proxiedMetadata);
}
Set<String> availableVersions = new HashSet<String>(metadata.getAvailableVersions());
availableVersions = findPossibleVersions(availableVersions, metadataFile.getParentFile());
if (availableVersions.size() > 0)
{
updateMetadataVersions(availableVersions, metadata);
}
RepositoryMetadataWriter.write(metadata, metadataFile);
ChecksummedFile checksum = new ChecksummedFile( metadataFile );
checksum.fixChecksums( algorithms );
}
/**
* Skims the parent directory of a metadata in vain hope of finding
* subdirectories that contain poms.
*
* @param metadataParentDirectory
* @return origional set plus newley found versions
*/
private Set<String> findPossibleVersions(Set<String> versions, File metadataParentDirectory)
{
Set<String> result = new HashSet<String>(versions);
for (File directory : metadataParentDirectory.listFiles())
{
if (directory.isDirectory())
{
for (File possiblePom : directory.listFiles())
{
if (possiblePom.getName().endsWith(".pom"))
{
result.add(directory.getName());
}
}
}
}
return result;
}
private List<ArchivaRepositoryMetadata> getMetadatasForManagedRepository( ManagedRepositoryContent managedRepository, String logicalResource )
{
List<ArchivaRepositoryMetadata> metadatas = new ArrayList<ArchivaRepositoryMetadata>();
File file = new File(managedRepository.getRepoRoot(), logicalResource);
if (file.exists())
{
try
{
ArchivaRepositoryMetadata existingMetadata = RepositoryMetadataReader.read(file);
if (existingMetadata != null)
{
metadatas.add(existingMetadata);
}
}
catch (RepositoryMetadataException e)
{
log.debug("Could not read metadata at " + file.getAbsolutePath() + ". Metadata will be removed.");
FileUtils.deleteQuietly(file);
}
}
for (String proxyId : proxies.get(managedRepository.getId()))
{
ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata( managedRepository, logicalResource, proxyId );
if (proxyMetadata != null)
{
metadatas.add(proxyMetadata);
}
}
return metadatas;
}
/**
* Update the metadata to represent the all versions/plugins of
* the provided groupId:artifactId project or group reference,
* based off of information present in the repository,
* the maven-metadata.xml files, and the proxy/repository specific
* metadata file contents.
*
* We must treat this as a group or a project metadata file as there is no way to know in advance
*
* @deprecated
* @param managedRepository the managed repository where the metadata is kept.
* @param reference the reference to update.
* @throws LayoutException
* @throws RepositoryMetadataException
* @throws IOException
* @throws ContentNotFoundException
*/
public void updateMetadata( ManagedRepositoryContent managedRepository, ProjectReference reference )
throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException
{
File metadataFile = new File( managedRepository.getRepoRoot(), toPath( reference ) );
long lastUpdated = getExistingLastUpdated( metadataFile );
ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
metadata.setGroupId( reference.getGroupId() );
metadata.setArtifactId( reference.getArtifactId() );
// Gather up all versions found in the managed repository.
Set<String> allVersions = managedRepository.getVersions( reference );
// Gather up all plugins found in the managed repository.
// TODO: do we know this information instead?
// Set<Plugin> allPlugins = managedRepository.getPlugins( reference );
Set<Plugin> allPlugins;
if ( metadataFile.exists() )
{
allPlugins = new LinkedHashSet<Plugin>( RepositoryMetadataReader.read( metadataFile ).getPlugins() );
}
else
{
allPlugins = new LinkedHashSet<Plugin>();
}
// Does this repository have a set of remote proxied repositories?
Set<String> proxiedRepoIds = this.proxies.get( managedRepository.getId() );
if ( CollectionUtils.isNotEmpty( proxiedRepoIds ) )
{
// Add in the proxied repo version ids too.
Iterator<String> it = proxiedRepoIds.iterator();
while ( it.hasNext() )
{
String proxyId = it.next();
ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata( managedRepository, reference, proxyId );
if ( proxyMetadata != null )
{
allVersions.addAll( proxyMetadata.getAvailableVersions() );
allPlugins.addAll( proxyMetadata.getPlugins() );
long proxyLastUpdated = getLastUpdated( proxyMetadata );
lastUpdated = Math.max( lastUpdated, proxyLastUpdated );
}
}
}
if ( !allVersions.isEmpty() )
{
updateMetadataVersions( allVersions ,metadata );
}
else
{
// Add the plugins to the metadata model.
metadata.setPlugins( new ArrayList<Plugin>( allPlugins ) );
// artifact ID was actually the last part of the group
metadata.setGroupId( metadata.getGroupId() + "." + metadata.getArtifactId() );
metadata.setArtifactId( null );
}
if ( lastUpdated > 0 )
{
metadata.setLastUpdatedTimestamp( toLastUpdatedDate( lastUpdated ) );
}
// Save the metadata model to disk.
RepositoryMetadataWriter.write( metadata, metadataFile );
ChecksummedFile checksum = new ChecksummedFile( metadataFile );
checksum.fixChecksums( algorithms );
}
private void updateMetadataVersions(Collection<String> allVersions, ArchivaRepositoryMetadata metadata)
{
// Sort the versions
List<String> sortedVersions = new ArrayList<String>(allVersions);
Collections.sort(sortedVersions, VersionComparator.getInstance());
// Split the versions into released and snapshots.
List<String> releasedVersions = new ArrayList<String>();
List<String> snapshotVersions = new ArrayList<String>();
for (String version : sortedVersions)
{
if (VersionUtil.isSnapshot(version))
{
snapshotVersions.add(version);
}
else
{
releasedVersions.add(version);
}
}
Collections.sort(releasedVersions, VersionComparator.getInstance());
Collections.sort(snapshotVersions, VersionComparator.getInstance());
String latestVersion = sortedVersions.get(sortedVersions.size() - 1);
String releaseVersion = null;
if (CollectionUtils.isNotEmpty(releasedVersions))
{
releaseVersion = releasedVersions.get(releasedVersions.size() - 1);
}
// Add the versions to the metadata model.
metadata.setAvailableVersions(sortedVersions);
metadata.setLatestVersion(latestVersion);
metadata.setReleasedVersion(releaseVersion);
}
private Date toLastUpdatedDate( long lastUpdated )
{
Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
cal.setTimeInMillis( lastUpdated );
return cal.getTime();
}
private long toLastUpdatedLong( String timestampString )
{
try
{
Date date = lastUpdatedFormat.parse( timestampString );
Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
cal.setTime( date );
return cal.getTimeInMillis();
}
catch ( ParseException e )
{
return 0;
}
}
private long getLastUpdated( ArchivaRepositoryMetadata metadata )
{
if ( metadata == null )
{
// Doesn't exist.
return 0;
}
try
{
String lastUpdated = metadata.getLastUpdated();
if ( StringUtils.isBlank( lastUpdated ) )
{
// Not set.
return 0;
}
Date lastUpdatedDate = lastUpdatedFormat.parse( lastUpdated );
return lastUpdatedDate.getTime();
}
catch ( ParseException e )
{
// Bad format on the last updated string.
return 0;
}
}
private long getExistingLastUpdated( File metadataFile )
{
if ( !metadataFile.exists() )
{
// Doesn't exist.
return 0;
}
try
{
ArchivaRepositoryMetadata metadata = RepositoryMetadataReader.read( metadataFile );
return getLastUpdated( metadata );
}
catch ( RepositoryMetadataException e )
{
// Error.
return 0;
}
}
/**
* Update the metadata based on the following rules.
* <p/>
* 1) If this is a SNAPSHOT reference, then utilize the proxy/repository specific
* metadata files to represent the current / latest SNAPSHOT available.
* 2) If this is a RELEASE reference, and the metadata file does not exist, then
* create the metadata file with contents required of the VersionedReference
*
* @deprecated
* @param managedRepository the managed repository where the metadata is kept.
* @param reference the versioned reference to update
* @throws LayoutException
* @throws RepositoryMetadataException
* @throws IOException
* @throws ContentNotFoundException
*/
public void updateMetadata( ManagedRepositoryContent managedRepository, VersionedReference reference )
throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException
{
File metadataFile = new File( managedRepository.getRepoRoot(), toPath( reference ) );
long lastUpdated = getExistingLastUpdated( metadataFile );
ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
metadata.setGroupId( reference.getGroupId() );
metadata.setArtifactId( reference.getArtifactId() );
if ( VersionUtil.isSnapshot( reference.getVersion() ) )
{
// Do SNAPSHOT handling.
metadata.setVersion( VersionUtil.getBaseVersion( reference.getVersion() ) );
// Gather up all of the versions found in the reference dir, and any
// proxied maven-metadata.xml files.
Set<String> snapshotVersions = gatherSnapshotVersions( managedRepository, reference );
if ( snapshotVersions.isEmpty() )
{
throw new ContentNotFoundException( "No snapshot versions found on reference ["
+ VersionedReference.toKey( reference ) + "]." );
}
// sort the list to determine to aide in determining the Latest version.
List<String> sortedVersions = new ArrayList<String>();
sortedVersions.addAll( snapshotVersions );
Collections.sort( sortedVersions, new VersionComparator() );
String latestVersion = sortedVersions.get( sortedVersions.size() - 1 );
if ( VersionUtil.isUniqueSnapshot( latestVersion ) )
{
// The latestVersion will contain the full version string "1.0-alpha-5-20070821.213044-8"
// This needs to be broken down into ${base}-${timestamp}-${build_number}
Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher( latestVersion );
if ( m.matches() )
{
metadata.setSnapshotVersion( new SnapshotVersion() );
int buildNumber = NumberUtils.toInt( m.group( 3 ), -1 );
metadata.getSnapshotVersion().setBuildNumber( buildNumber );
Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher( m.group( 2 ) );
if ( mtimestamp.matches() )
{
String tsDate = mtimestamp.group( 1 );
String tsTime = mtimestamp.group( 2 );
long snapshotLastUpdated = toLastUpdatedLong( tsDate + tsTime );
lastUpdated = Math.max( lastUpdated, snapshotLastUpdated );
metadata.getSnapshotVersion().setTimestamp( m.group( 2 ) );
}
}
}
else if ( VersionUtil.isGenericSnapshot( latestVersion ) )
{
// The latestVersion ends with the generic version string.
// Example: 1.0-alpha-5-SNAPSHOT
metadata.setSnapshotVersion( new SnapshotVersion() );
/* Disabled due to decision in [MRM-535].
* Do not set metadata.lastUpdated to file.lastModified.
*
* Should this be the last updated timestamp of the file, or in the case of an
* archive, the most recent timestamp in the archive?
*
ArtifactReference artifact = getFirstArtifact( managedRepository, reference );
if ( artifact == null )
{
throw new IOException( "Not snapshot artifact found to reference in " + reference );
}
File artifactFile = managedRepository.toFile( artifact );
if ( artifactFile.exists() )
{
Date lastModified = new Date( artifactFile.lastModified() );
metadata.setLastUpdatedTimestamp( lastModified );
}
*/
}
else
{
throw new RepositoryMetadataException( "Unable to process snapshot version <" + latestVersion
+ "> reference <" + reference + ">" );
}
}
else
{
// Do RELEASE handling.
metadata.setVersion( reference.getVersion() );
}
// Set last updated
if ( lastUpdated > 0 )
{
metadata.setLastUpdatedTimestamp( toLastUpdatedDate( lastUpdated ) );
}
// Save the metadata model to disk.
RepositoryMetadataWriter.write( metadata, metadataFile );
ChecksummedFile checksum = new ChecksummedFile( metadataFile );
checksum.fixChecksums( algorithms );
}
private void initConfigVariables()
{
synchronized ( this.artifactPatterns )
{
this.artifactPatterns.clear();
this.artifactPatterns.addAll( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
}
synchronized ( proxies )
{
this.proxies.clear();
List<ProxyConnectorConfiguration> proxyConfigs = configuration.getConfiguration().getProxyConnectors();
for( ProxyConnectorConfiguration proxyConfig: proxyConfigs )
{
String key = proxyConfig.getSourceRepoId();
Set<String> remoteRepoIds = this.proxies.get( key );
if ( remoteRepoIds == null )
{
remoteRepoIds = new HashSet<String>();
}
remoteRepoIds.add( proxyConfig.getTargetRepoId() );
this.proxies.put( key, remoteRepoIds );
}
}
}
/**
* Get the first Artifact found in the provided VersionedReference location.
*
* @param managedRepository the repository to search within.
* @param reference the reference to the versioned reference to search within
* @return the ArtifactReference to the first artifact located within the versioned reference. or null if
* no artifact was found within the versioned reference.
* @throws IOException if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
* @throws LayoutException
*/
public ArtifactReference getFirstArtifact( ManagedRepositoryContent managedRepository, VersionedReference reference )
throws LayoutException, IOException
{
String path = toPath( reference );
int idx = path.lastIndexOf( '/' );
if ( idx > 0 )
{
path = path.substring( 0, idx );
}
File repoDir = new File( managedRepository.getRepoRoot(), path );
if ( !repoDir.exists() )
{
throw new IOException( "Unable to gather the list of snapshot versions on a non-existant directory: "
+ repoDir.getAbsolutePath() );
}
if ( !repoDir.isDirectory() )
{
throw new IOException( "Unable to gather the list of snapshot versions on a non-directory: "
+ repoDir.getAbsolutePath() );
}
File repoFiles[] = repoDir.listFiles();
for ( int i = 0; i < repoFiles.length; i++ )
{
if ( repoFiles[i].isDirectory() )
{
// Skip it. it's a directory.
continue;
}
String relativePath = PathUtil.getRelative( managedRepository.getRepoRoot(), repoFiles[i] );
if ( filetypes.matchesArtifactPattern( relativePath ) )
{
ArtifactReference artifact = managedRepository.toArtifactReference( relativePath );
return artifact;
}
}
// No artifact was found.
return null;
}
}