From 08ab14db02d7975fda4992583dca7bf62d9b2916 Mon Sep 17 00:00:00 2001 From: James William Dumay Date: Wed, 13 Aug 2008 00:31:46 +0000 Subject: [PATCH] MRM-907 - Remove VersionedReference/ProjectReference/ArtifactReference from RepositoryProxyConnectors * Metadata proxy fetching has been refactored from two methods to one single method. * Artifacts, metadata and resources are now written to a temporary working area. Post download policies are run before the proxied data are put in the repository proper. git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/metadata-rejig-1.2@685399 13f79535-47bb-0310-9956-ffa450edef68 --- .../DefaultRepositoryProxyConnectors.java | 155 +------------- .../proxy/RepositoryProxyConnectors.java | 17 +- .../archiva/proxy/MetadataTransferTest.java | 8 +- .../repository/metadata/MetadataTools.java | 200 ++++++++++++++---- .../metadata/RepositoryMetadataMerge.java | 150 ++++++++++++- .../metadata/RepositoryMetadataWriter.java | 9 +- .../metadata/MetadataToolsTest.java | 11 +- .../webdav/ArchivaDavResourceFactory.java | 41 +--- .../RepositoryServletRepositoryGroupTest.java | 3 +- 9 files changed, 342 insertions(+), 252 deletions(-) diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java index 5e9978fa6..66f5ddf71 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java @@ -32,7 +32,6 @@ import java.util.Map.Entry; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.apache.maven.archiva.configuration.ArchivaConfiguration; import org.apache.maven.archiva.configuration.ConfigurationNames; @@ -40,9 +39,7 @@ import org.apache.maven.archiva.configuration.NetworkProxyConfiguration; import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration; import org.apache.maven.archiva.model.ArtifactReference; import org.apache.maven.archiva.model.Keys; -import org.apache.maven.archiva.model.ProjectReference; import org.apache.maven.archiva.model.RepositoryURL; -import org.apache.maven.archiva.model.VersionedReference; import org.apache.maven.archiva.policies.DownloadErrorPolicy; import org.apache.maven.archiva.policies.DownloadPolicy; import org.apache.maven.archiva.policies.PolicyConfigurationException; @@ -51,13 +48,11 @@ import org.apache.maven.archiva.policies.PostDownloadPolicy; import org.apache.maven.archiva.policies.PreDownloadPolicy; import org.apache.maven.archiva.policies.ProxyDownloadException; import org.apache.maven.archiva.policies.urlcache.UrlFailureCache; -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.RepositoryContentFactory; import org.apache.maven.archiva.repository.RepositoryException; import org.apache.maven.archiva.repository.RepositoryNotFoundException; -import org.apache.maven.archiva.repository.layout.LayoutException; import org.apache.maven.archiva.repository.metadata.MetadataTools; import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException; import org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers; @@ -269,13 +264,13 @@ public class DefaultRepositoryProxyConnectors return null; } - - public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata ) + + public File fetchMetatadaFromProxies(ManagedRepositoryContent repository, String logicalPath) { File workingDir = createWorkingDirectory(repository); try { - File localFile = toLocalFile( repository, metadata ); + File localFile = new File(repository.getRepoRoot(), logicalPath); Properties requestProperties = new Properties(); requestProperties.setProperty( "filetype", "metadata" ); @@ -286,14 +281,13 @@ public class DefaultRepositoryProxyConnectors for ( ProxyConnector connector : connectors ) { RemoteRepositoryContent targetRepository = connector.getTargetRepository(); - String targetPath = metadataTools.toPath( metadata ); - File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath ); + File localRepoFile = toLocalRepoFile( repository, targetRepository, logicalPath ); long originalMetadataTimestamp = getLastModified( localRepoFile ); try { - transferFile( connector, targetRepository, targetPath, repository, workingDir, localRepoFile, requestProperties, true ); + transferFile( connector, targetRepository, logicalPath, repository, workingDir, localRepoFile, requestProperties, true ); if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) ) { @@ -302,20 +296,20 @@ public class DefaultRepositoryProxyConnectors } catch ( NotFoundException e ) { - log.debug( "Versioned Metadata " + Keys.toKey( metadata ) + log.debug( "Metadata " + logicalPath + " not found on remote repository \"" - + targetRepository.getRepository().getId() + "\"." ); + + targetRepository.getRepository().getId() + "\".", e ); } catch ( NotModifiedException e ) { - log.debug( "Versioned Metadata " + Keys.toKey( metadata ) + log.debug( "Metadata " + logicalPath + " not updated on remote repository \"" - + targetRepository.getRepository().getId() + "\"." ); + + targetRepository.getRepository().getId() + "\".", e ); } catch ( ProxyException e ) { log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() + - "\" for versioned Metadata " + Keys.toKey( metadata ) + + "\" for versioned Metadata " + logicalPath + ", continuing to next repository. Error message: " + e.getMessage() ); log.debug( "Full stack trace", e ); } @@ -330,126 +324,11 @@ public class DefaultRepositoryProxyConnectors { try { - metadataTools.updateMetadata( repository, metadata ); - } - catch ( LayoutException e ) - { - log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage() ); - // TODO: add into repository report? + metadataTools.updateMetadata( repository, logicalPath ); } catch ( RepositoryMetadataException e ) { log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e ); - // TODO: add into repository report? - } - catch ( IOException e ) - { - log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e ); - // TODO: add into repository report? - } - catch ( ContentNotFoundException e ) - { - log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e ); - // TODO: add into repository report? - } - } - - if ( fileExists( localFile ) ) - { - return localFile; - } - } - finally - { - FileUtils.deleteQuietly(workingDir); - } - - return null; - } - - public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata ) - { - File workingDir = createWorkingDirectory(repository); - try - { - File localFile = toLocalFile( repository, metadata ); - - Properties requestProperties = new Properties(); - requestProperties.setProperty( "filetype", "metadata" ); - boolean metadataNeedsUpdating = false; - long originalTimestamp = getLastModified( localFile ); - - List connectors = getProxyConnectors( repository ); - for ( ProxyConnector connector : connectors ) - { - RemoteRepositoryContent targetRepository = connector.getTargetRepository(); - String targetPath = metadataTools.toPath( metadata ); - - File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath ); - long originalMetadataTimestamp = getLastModified( localRepoFile ); - try - { - transferFile( connector, targetRepository, targetPath, repository, workingDir, localRepoFile, requestProperties, true ); - - if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) ) - { - metadataNeedsUpdating = true; - } - } - catch ( NotFoundException e ) - { - log.debug( "Project Metadata " + Keys.toKey( metadata ) + " not found on remote repository \"" - + targetRepository.getRepository().getId() + "\"." ); - } - catch ( NotModifiedException e ) - { - log.debug( "Project Metadata " + Keys.toKey( metadata ) - + " not updated on remote repository \"" - + targetRepository.getRepository().getId() + "\"." ); - } - catch ( ProxyException e ) - { - log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() + - "\" for project metadata " + Keys.toKey( metadata ) + - ", continuing to next repository. Error message: " + e.getMessage() ); - log.debug( "Full stack trace", e ); - } - - } - - if ( hasBeenUpdated( localFile, originalTimestamp ) ) - { - metadataNeedsUpdating = true; - } - - if ( metadataNeedsUpdating ) - { - try - { - metadataTools.updateMetadata( repository, metadata ); - } - catch ( LayoutException e ) - { - log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage() ); - // TODO: add into repository report? - } - catch ( RepositoryMetadataException e ) - { - log - .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e ); - // TODO: add into repository report? - } - catch ( IOException e ) - { - log - .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e ); - // TODO: add into repository report? - } - catch ( ContentNotFoundException e ) - { - log - .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e ); - // TODO: add into repository report? } } @@ -510,18 +389,6 @@ public class DefaultRepositoryProxyConnectors return repository.toFile( artifact ); } - private File toLocalFile( ManagedRepositoryContent repository, ProjectReference metadata ) - { - String sourcePath = metadataTools.toPath( metadata ); - return new File( repository.getRepoRoot(), sourcePath ); - } - - private File toLocalFile( ManagedRepositoryContent repository, VersionedReference metadata ) - { - String sourcePath = metadataTools.toPath( metadata ); - return new File( repository.getRepoRoot(), sourcePath ); - } - /** * Simple method to test if the file exists on the local disk. * diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java index cf68c9509..26122b211 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/RepositoryProxyConnectors.java @@ -50,7 +50,7 @@ public interface RepositoryProxyConnectors */ public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact ) throws ProxyDownloadException; - + /** * Performs the metadata fetch operation against the target repositories * of the provided source repository. @@ -62,20 +62,7 @@ public interface RepositoryProxyConnectors * @param metadata the metadata to fetch. * @return the file that was obtained, or null if no content was obtained */ - public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata ); - - /** - * Performs the metadata fetch operation against the target repositories - * of the provided source repository. - * - * If the metadata is found, it is downloaded and placed into the source repository - * filesystem. - * - * @param repository the source repository to use. (must be a managed repository) - * @param metadata the metadata to fetch. - * @return the file that was obtained, or null if no content was obtained - */ - public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata ); + public File fetchMetatadaFromProxies( ManagedRepositoryContent repository, String logicalPath ); /** * Performs the fetch operation against the target repositories diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/MetadataTransferTest.java b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/MetadataTransferTest.java index 3cab9107b..8e7d20d68 100644 --- a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/MetadataTransferTest.java +++ b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/MetadataTransferTest.java @@ -905,7 +905,7 @@ public class MetadataTransferTest ProjectReference metadata = createProjectReference( requestedResource ); - File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, metadata ); + File downloadedFile = proxyHandler.fetchMetatadaFromProxies( managedDefaultRepository, managedDefaultRepository.toMetadataPath(metadata) ); assertNotNull( "Should have downloaded a file.", downloadedFile ); assertNoTempFiles( expectedFile ); @@ -929,7 +929,7 @@ public class MetadataTransferTest File expectedFile = new File( managedDefaultDir, requestedResource ); ProjectReference metadata = createProjectReference( requestedResource ); - File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, metadata ); + File downloadedFile = proxyHandler.fetchMetatadaFromProxies( managedDefaultRepository, managedDefaultRepository.toMetadataPath(metadata) ); assertNull( downloadedFile ); assertNoTempFiles( expectedFile ); @@ -948,7 +948,7 @@ public class MetadataTransferTest VersionedReference metadata = createVersionedReference( requestedResource ); - File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, metadata ); + File downloadedFile = proxyHandler.fetchMetatadaFromProxies( managedDefaultRepository, managedDefaultRepository.toMetadataPath(metadata) ); assertNotNull( "Should have downloaded a file.", downloadedFile ); assertNoTempFiles( expectedFile ); @@ -972,7 +972,7 @@ public class MetadataTransferTest File expectedFile = new File( managedDefaultDir, requestedResource ); VersionedReference metadata = createVersionedReference( requestedResource ); - File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, metadata ); + File downloadedFile = proxyHandler.fetchMetatadaFromProxies( managedDefaultRepository, managedDefaultRepository.toMetadataPath(metadata) ); assertNull( downloadedFile ); assertNoTempFiles( expectedFile ); diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java index 683a26790..38f871703 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/MetadataTools.java @@ -55,6 +55,7 @@ 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; @@ -65,6 +66,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; +import org.apache.commons.io.FileUtils; /** * MetadataTools @@ -369,6 +371,31 @@ public class MetadataTools 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 ) @@ -394,6 +421,100 @@ public class MetadataTools return null; } } + + public void updateMetadata( ManagedRepositoryContent managedRepository, String logicalResource) throws RepositoryMetadataException + { + ArchivaRepositoryMetadata metadata = null; + final File metadataFile = new File(managedRepository.getRepoRoot(), logicalResource); +// final long lastUpdated = getExistingLastUpdated( metadataFile ); + + //Gather and merge all metadata available + List metadatas = getMetadatasForManagedRepository(managedRepository, logicalResource); + for (ArchivaRepositoryMetadata proxiedMetadata : metadatas) + { + if (metadata == null) + { + metadata = proxiedMetadata; + continue; + } + metadata = RepositoryMetadataMerge.merge(metadata, proxiedMetadata); + } + + Set availableVersions = new HashSet(metadata.getAvailableVersions()); + availableVersions = findPossibleVersions(availableVersions, metadataFile.getParentFile()); + + if (availableVersions.size() > 0) + { + updateMetadataVersions(availableVersions, metadata); + } + +// if ( lastUpdated > 0 ) +// { +// metadata.setLastUpdatedTimestamp( toLastUpdatedDate( lastUpdated ) ); +// } + + RepositoryMetadataWriter.write(metadata, metadataFile); + } + + /** + * 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 findPossibleVersions(Set versions, File metadataParentDirectory) + { + Set result = new HashSet(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 getMetadatasForManagedRepository( ManagedRepositoryContent managedRepository, String logicalResource ) + { + List metadatas = new ArrayList(); + 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 @@ -404,6 +525,7 @@ public class MetadataTools * * 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 @@ -463,42 +585,7 @@ public class MetadataTools if ( !allVersions.isEmpty() ) { - // Sort the versions - List sortedVersions = new ArrayList( allVersions ); - Collections.sort( sortedVersions, VersionComparator.getInstance() ); - - // Split the versions into released and snapshots. - List releasedVersions = new ArrayList(); - List snapshotVersions = new ArrayList(); - - 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 ); + updateMetadataVersions( allVersions ,metadata ); } else { @@ -521,6 +608,46 @@ public class MetadataTools checksum.fixChecksums( algorithms ); } + private void updateMetadataVersions(Collection allVersions, ArchivaRepositoryMetadata metadata) + { + // Sort the versions + List sortedVersions = new ArrayList(allVersions); + Collections.sort(sortedVersions, VersionComparator.getInstance()); + + // Split the versions into released and snapshots. + List releasedVersions = new ArrayList(); + List snapshotVersions = new ArrayList(); + + 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 ); @@ -601,6 +728,7 @@ public class MetadataTools * 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 diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataMerge.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataMerge.java index 947b1508b..4b265b6e3 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataMerge.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataMerge.java @@ -19,12 +19,20 @@ package org.apache.maven.archiva.repository.metadata; * under the License. */ +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; import org.apache.maven.archiva.model.ArchivaModelCloner; import org.apache.maven.archiva.model.ArchivaRepositoryMetadata; import org.apache.maven.archiva.model.SnapshotVersion; import java.util.Iterator; import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.time.DateUtils; +import org.apache.maven.archiva.model.Plugin; /** * RepositoryMetadataMerge @@ -51,13 +59,20 @@ public class RepositoryMetadataMerge ArchivaRepositoryMetadata merged = new ArchivaRepositoryMetadata(); merged.setGroupId( merge( mainMetadata.getGroupId(), sourceMetadata.getGroupId() ) ); - + merged.setArtifactId( merge(mainMetadata.getArtifactId(), sourceMetadata.getArtifactId())); + merged.setVersion( merge(mainMetadata.getVersion(), sourceMetadata.getVersion()) ); merged.setReleasedVersion( merge( mainMetadata.getReleasedVersion(), sourceMetadata.getReleasedVersion() ) ); merged.setSnapshotVersion( merge( mainMetadata.getSnapshotVersion(), sourceMetadata.getSnapshotVersion() ) ); - merged.setLastUpdated( merge( mainMetadata.getLastUpdated(), sourceMetadata.getLastUpdated() ) ); - merged.setAvailableVersions( mergeAvailableVersions( mainMetadata.getAvailableVersions(), sourceMetadata - .getAvailableVersions() ) ); - + merged.setAvailableVersions( mergeAvailableVersions( mainMetadata.getAvailableVersions(), sourceMetadata.getAvailableVersions() ) ); + merged.setPlugins( mergePlugins( mainMetadata.getPlugins(), sourceMetadata.getPlugins() ) ); + + //Don't set if merge was not possible + long lastUpdated = mergeTimestamp( mainMetadata.getLastUpdated(), sourceMetadata.getLastUpdated()); + if (lastUpdated > -1) + { + merged.setLastUpdated( Long.toString(lastUpdated) ); + } + return merged; } @@ -70,6 +85,31 @@ public class RepositoryMetadataMerge return ( val.trim().length() <= 0 ); } + + private static long mergeTimestamp(String mainTimestamp, String sourceTimestamp) + { + if (sourceTimestamp == null && mainTimestamp != null) + { + return convertTimestampToLong(mainTimestamp); + } + + if (mainTimestamp == null && sourceTimestamp != null) + { + return convertTimestampToLong(sourceTimestamp); + } + + if (sourceTimestamp == null && mainTimestamp == null) + { + return -1; + } + + return mergeTimestamp(convertTimestampToLong(mainTimestamp), convertTimestampToLong(sourceTimestamp)); + } + + private static long mergeTimestamp(long mainTimestamp, long sourceTimestamp) + { + return Math.max( mainTimestamp, sourceTimestamp ); + } private static SnapshotVersion merge( SnapshotVersion mainSnapshotVersion, SnapshotVersion sourceSnapshotVersion ) { @@ -84,13 +124,47 @@ public class RepositoryMetadataMerge } SnapshotVersion merged = new SnapshotVersion(); - - merged.setTimestamp( merge( mainSnapshotVersion.getTimestamp(), sourceSnapshotVersion.getTimestamp() ) ); - merged - .setBuildNumber( Math.max( mainSnapshotVersion.getBuildNumber(), sourceSnapshotVersion.getBuildNumber() ) ); + + long mainSnapshotLastUpdated = convertTimestampToLong(mainSnapshotVersion.getTimestamp()); + long sourceSnapshotLastUpdated = convertTimestampToLong(sourceSnapshotVersion.getTimestamp()); + + long lastUpdated = mergeTimestamp(mainSnapshotLastUpdated, sourceSnapshotLastUpdated); + + if (lastUpdated == mainSnapshotLastUpdated) + { + merged.setTimestamp(mainSnapshotVersion.getTimestamp()); + merged.setBuildNumber(mainSnapshotVersion.getBuildNumber()); + } + else + { + merged.setTimestamp(sourceSnapshotVersion.getTimestamp()); + merged.setBuildNumber(sourceSnapshotVersion.getBuildNumber()); + } return merged; } + + private static long convertTimestampToLong(String timestamp) + { + if (timestamp == null) + { + return -1; + } + + return getLongFromTimestampSafely(StringUtils.replace(timestamp, ".", "")); + } + + private static long getLongFromTimestampSafely( String timestampString ) + { + try + { + return Long.parseLong(timestampString); + } + catch (NumberFormatException e) + { + return -1; + } + } private static String merge( String main, String source ) { @@ -101,6 +175,64 @@ public class RepositoryMetadataMerge return main; } + + private static List mergePlugins(List mainPlugins, List sourcePlugins) + { + if ( sourcePlugins == null ) + { + return mainPlugins; + } + + if ( mainPlugins == null ) + { + return clonePlugins( sourcePlugins ); + } + + List merged = clonePlugins( mainPlugins ); + + Iterator it = sourcePlugins.iterator(); + while ( it.hasNext() ) + { + Plugin plugin = (Plugin) it.next(); + if ( !merged.contains( plugin ) ) + { + merged.add( plugin ); + } + } + + return merged; + } + + /** + * Clones a list of plugins. + * + * This method exists because ArchivaModelCloner.clonePlugins() + * only works with artifact references. + * + * @param plugins + * @return list of cloned plugins + */ + private static List clonePlugins(List plugins) + { + if (plugins == null) + { + return null; + } + + ArrayList result = new ArrayList(); + + for (Plugin plugin : plugins) + { + Plugin clonedPlugin = new Plugin(); + clonedPlugin.setArtifactId(plugin.getArtifactId()); + clonedPlugin.setModelEncoding(plugin.getModelEncoding()); + clonedPlugin.setName(plugin.getName()); + clonedPlugin.setPrefix(plugin.getPrefix()); + result.add(plugin); + } + + return result; + } private static List mergeAvailableVersions( List mainAvailableVersions, List sourceAvailableVersions ) { diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataWriter.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataWriter.java index 9b0d1b283..ba4ae0e4f 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataWriter.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/metadata/RepositoryMetadataWriter.java @@ -36,6 +36,7 @@ import java.io.IOException; import java.io.Writer; import java.util.Iterator; import java.util.List; +import org.apache.commons.io.FileUtils; /** * RepositoryMetadataWriter @@ -48,6 +49,7 @@ public class RepositoryMetadataWriter public static void write( ArchivaRepositoryMetadata metadata, File outputFile ) throws RepositoryMetadataException { + boolean thrown = false; FileWriter writer = null; try { @@ -57,12 +59,17 @@ public class RepositoryMetadataWriter } catch ( IOException e ) { + thrown = true; throw new RepositoryMetadataException( "Unable to write metadata file: " + outputFile.getAbsolutePath() + " - " + e.getMessage(), e ); } finally { IOUtils.closeQuietly( writer ); + if (thrown) + { + FileUtils.deleteQuietly(outputFile); + } } } @@ -74,7 +81,7 @@ public class RepositoryMetadataWriter Element root = DocumentHelper.createElement( "metadata" ); doc.setRootElement( root ); - root.addElement( "groupId" ).setText( metadata.getGroupId() ); + addOptionalElementText( root, "groupId", metadata.getGroupId()); addOptionalElementText( root, "artifactId", metadata.getArtifactId() ); addOptionalElementText( root, "version", metadata.getVersion() ); diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/metadata/MetadataToolsTest.java b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/metadata/MetadataToolsTest.java index c539f52b5..46f53b7f0 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/metadata/MetadataToolsTest.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/metadata/MetadataToolsTest.java @@ -60,6 +60,15 @@ public class MetadataToolsTest private MetadataTools tools; protected MockConfiguration config; + + public void testToVersionedReferenceLog4J() throws RepositoryMetadataException + { + String path = "log4j/log4j/maven-metadata.xml"; + ProjectReference reference = tools.toProjectReference(path); + assertEquals("log4j", reference.getGroupId()); + assertEquals("log4j", reference.getArtifactId()); +// assertEquals("", reference.getVersion()); + } public void testGatherSnapshotVersionsA() throws Exception @@ -219,7 +228,7 @@ public class MetadataToolsTest assertEquals( "com/foo/foo-tool/maven-metadata.xml", tools.toPath( reference ) ); } - + public void testToProjectReferenceFooTools() throws RepositoryMetadataException { diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java index 0e8277359..da69aa7bc 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java @@ -514,7 +514,7 @@ public class ArchivaDavResourceFactory // Is it a Metadata resource? if ( repositoryRequest.isDefault( resource.getPath() ) && repositoryRequest.isMetadata( resource.getPath() ) ) { - return fetchMetadataFromProxies( managedRepository, request, resource ); + return connectors.fetchMetatadaFromProxies(managedRepository, resource.getPath()) != null; } // Not any of the above? Then it's gotta be an artifact reference. @@ -546,45 +546,6 @@ public class ArchivaDavResourceFactory return false; } - private boolean fetchMetadataFromProxies( ManagedRepositoryContent managedRepository, DavServletRequest request, - LogicalResource resource ) - throws DavException - { - ProjectReference project; - VersionedReference versioned; - - try - { - - versioned = metadataTools.toVersionedReference( resource.getPath() ); - if ( versioned != null ) - { - connectors.fetchFromProxies( managedRepository, versioned ); - return true; - } - } - catch ( RepositoryMetadataException e ) - { - /* eat it */ - } - - try - { - project = metadataTools.toProjectReference( resource.getPath() ); - if ( project != null ) - { - connectors.fetchFromProxies( managedRepository, project ); - return true; - } - } - catch ( RepositoryMetadataException e ) - { - /* eat it */ - } - - return false; - } - /** * A relocation capable client will request the POM prior to the artifact, and will then read meta-data and do * client side relocation. A simplier client (like maven 1) will only request the artifact and not use the diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java index 26ff32ee1..c78e0b742 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java @@ -244,8 +244,7 @@ public class RepositoryServletRepositoryGroupTest "1.52.020080709095554" + "", null ); - WebRequest request = - new GetMethodWebRequest( "http://machine.com/repository/" + REPO_GROUP_WITH_VALID_REPOS + "/dummy/" + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/" + REPO_GROUP_WITH_VALID_REPOS + "/dummy/" + "dummy-merged-metadata-resource/maven-metadata.xml" ); WebResponse response = sc.getResource( request );