From: Olivier Lamy Date: Mon, 29 Oct 2012 20:42:12 +0000 (+0000) Subject: [MRM-1704] Refactor to remove maven specific part from various repository/metadata... X-Git-Tag: archiva-1.4-M4~692 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a586d56df251be5950ce8cd59cd8b22a5a516882;p=archiva.git [MRM-1704] Refactor to remove maven specific part from various repository/metadata apis git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1403491 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/archiva-modules/metadata/metadata-model-maven2/pom.xml b/archiva-modules/metadata/metadata-model-maven2/pom.xml new file mode 100644 index 000000000..6c47c1a69 --- /dev/null +++ b/archiva-modules/metadata/metadata-model-maven2/pom.xml @@ -0,0 +1,63 @@ + + + + 4.0.0 + + metadata + org.apache.archiva + 1.4-M4-SNAPSHOT + + metadata-model-maven2 + bundle + Archiva Metadata :: Maven 2 Model + + + + org.apache.archiva + metadata-model + + + commons-lang + commons-lang + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.archiva.metadata.model + ${project.version} + + org.apache.archiva.metadata.model;version=${project.version};-split-package:=merge-first + + + javax.xml.bind.annotation, + org.apache.commons.lang + + + + + + + diff --git a/archiva-modules/metadata/metadata-model-maven2/src/main/java/org/apache/archiva/metadata/model/maven2/MavenArtifactFacet.java b/archiva-modules/metadata/metadata-model-maven2/src/main/java/org/apache/archiva/metadata/model/maven2/MavenArtifactFacet.java new file mode 100644 index 000000000..6a88d6540 --- /dev/null +++ b/archiva-modules/metadata/metadata-model-maven2/src/main/java/org/apache/archiva/metadata/model/maven2/MavenArtifactFacet.java @@ -0,0 +1,140 @@ +package org.apache.archiva.metadata.model.maven2; + +/* + * 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.metadata.model.MetadataFacet; +import org.apache.commons.lang.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class MavenArtifactFacet + implements MetadataFacet +{ + private String classifier; + + private String type; + + private String timestamp; + + private int buildNumber; + + public static final String FACET_ID = "org.apache.archiva.metadata.repository.storage.maven2.artifact"; + + public String getClassifier() + { + return classifier; + } + + public void setClassifier( String classifier ) + { + this.classifier = classifier; + } + + public String getType() + { + return type; + } + + public void setType( String type ) + { + this.type = type; + } + + public String getTimestamp() + { + return timestamp; + } + + public void setTimestamp( String timestamp ) + { + this.timestamp = timestamp; + } + + public int getBuildNumber() + { + return buildNumber; + } + + public void setBuildNumber( int buildNumber ) + { + this.buildNumber = buildNumber; + } + + public String getFacetId() + { + return FACET_ID; + } + + public String getName() + { + // TODO: not needed, perhaps artifact/version metadata facet should be separate interface? + return null; + } + + public Map toProperties() + { + Map properties = new HashMap(); + properties.put( "type", type ); + if ( classifier != null ) + { + properties.put( "classifier", classifier ); + } + if ( timestamp != null ) + { + properties.put( "timestamp", timestamp ); + } + if ( buildNumber > 0 ) + { + properties.put( "buildNumber", Integer.toString( buildNumber ) ); + } + return properties; + } + + public void fromProperties( Map properties ) + { + type = properties.get( "type" ); + classifier = properties.get( "classifier" ); + timestamp = properties.get( "timestamp" ); + String buildNumber = properties.get( "buildNumber" ); + if ( buildNumber != null ) + { + this.buildNumber = Integer.parseInt( buildNumber ); + } + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( !( o instanceof MavenArtifactFacet ) ) + { + return false; + } + + MavenArtifactFacet that = (MavenArtifactFacet) o; + + return StringUtils.equals( that.getClassifier(), this.classifier ); + } + +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/AbstractLegacyRepositoryContent.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/AbstractLegacyRepositoryContent.java new file mode 100644 index 000000000..8993be82f --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/AbstractLegacyRepositoryContent.java @@ -0,0 +1,129 @@ +package org.apache.archiva.repository.content.legacy; + +/* + * 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.model.ArchivaArtifact; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.content.PathParser; +import org.apache.archiva.repository.content.maven2.ArtifactExtensionMapping; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.commons.lang.StringUtils; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.HashMap; +import java.util.Map; + +/** + * AbstractLegacyRepositoryContent + * + * + */ +public abstract class AbstractLegacyRepositoryContent +{ + private static final String PATH_SEPARATOR = "/"; + + private static final Map typeToDirectoryMap; + + static + { + typeToDirectoryMap = new HashMap(); + typeToDirectoryMap.put( "ejb-client", "ejb" ); + typeToDirectoryMap.put( ArtifactExtensionMapping.MAVEN_ONE_PLUGIN, "plugin" ); + typeToDirectoryMap.put( "distribution-tgz", "distribution" ); + typeToDirectoryMap.put( "distribution-zip", "distribution" ); + typeToDirectoryMap.put( "javadoc", "javadoc.jar" ); + } + + /** + * + */ + @Inject + @Named( value = "pathParser#legacy" ) + private PathParser legacyPathParser; + + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + return legacyPathParser.toArtifactReference( path ); + } + + public String toPath( ArchivaArtifact reference ) + { + if ( reference == null ) + { + throw new IllegalArgumentException( "Artifact reference cannot be null" ); + } + + return toPath( reference.getGroupId(), reference.getArtifactId(), reference.getVersion(), + reference.getClassifier(), reference.getType() ); + } + + public String toPath( ArtifactReference reference ) + { + if ( reference == null ) + { + throw new IllegalArgumentException( "Artifact reference cannot be null" ); + } + + return toPath( reference.getGroupId(), reference.getArtifactId(), reference.getVersion(), + reference.getClassifier(), reference.getType() ); + } + + private String toPath( String groupId, String artifactId, String version, String classifier, String type ) + { + StringBuilder path = new StringBuilder(); + + path.append( groupId ).append( PATH_SEPARATOR ); + path.append( getDirectory( type ) ).append( PATH_SEPARATOR ); + + if ( version != null ) + { + path.append( artifactId ).append( '-' ).append( version ); + + if ( StringUtils.isNotBlank( classifier ) ) + { + path.append( '-' ).append( classifier ); + } + + path.append( '.' ).append( ArtifactExtensionMapping.getExtension( type ) ); + } + + return path.toString(); + } + + private String getDirectory( String type ) + { + String dirname = typeToDirectoryMap.get( type ); + + if ( dirname != null ) + { + return dirname + "s"; + } + + // Default process. + return type + "s"; + } + + public void setLegacyPathParser( PathParser parser ) + { + this.legacyPathParser = parser; + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/LegacyPathParser.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/LegacyPathParser.java new file mode 100644 index 000000000..407a9db8d --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/LegacyPathParser.java @@ -0,0 +1,215 @@ +package org.apache.archiva.repository.content.legacy; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.LegacyArtifactPath; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.content.ArtifactClassifierMapping; +import org.apache.archiva.repository.content.PathParser; +import org.apache.archiva.repository.content.maven2.ArtifactExtensionMapping; +import org.apache.archiva.repository.content.maven2.FilenameParser; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.commons.lang.StringUtils; + +import java.util.Collection; + +/** + * LegacyPathParser is a parser for maven 1 (legacy layout) paths to + * ArtifactReference. + * + * + */ +public class LegacyPathParser + implements PathParser +{ + private static final String INVALID_ARTIFACT_PATH = "Invalid path to Artifact: "; + + protected ArchivaConfiguration configuration; + + public LegacyPathParser( ArchivaConfiguration configuration ) + { + this.configuration = configuration; + } + + + /** + * {@inheritDoc} + * + * @see org.apache.archiva.repository.content.PathParser#toArtifactReference(String) + */ + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + ArtifactReference artifact = new ArtifactReference(); + + // First, look if a custom resolution rule has been set for this artifact + Collection legacy = configuration.getConfiguration().getLegacyArtifactPaths(); + for ( LegacyArtifactPath legacyPath : legacy ) + { + if ( legacyPath.match( path ) ) + { + artifact.setGroupId( legacyPath.getGroupId() ); + artifact.setArtifactId( legacyPath.getArtifactId() ); + artifact.setClassifier( legacyPath.getClassifier() ); + artifact.setVersion( legacyPath.getVersion() ); + artifact.setType( legacyPath.getType() ); + return artifact; + } + } + + String normalizedPath = StringUtils.replace( path, "\\", "/" ); + + String pathParts[] = StringUtils.split( normalizedPath, '/' ); + + /* Always 3 parts. (Never more or less) + * + * path = "commons-lang/jars/commons-lang-2.1.jar" + * path[0] = "commons-lang"; // The Group ID + * path[1] = "jars"; // The Directory Type + * path[2] = "commons-lang-2.1.jar"; // The Filename. + */ + + if ( pathParts.length != 3 ) + { + // Illegal Path Parts Length. + throw new LayoutException( INVALID_ARTIFACT_PATH + + "legacy paths should only have 3 parts [groupId]/[type]s/[artifactId]-[version].[type], found " + + pathParts.length + " instead." ); + } + + // The Group ID. + artifact.setGroupId( pathParts[0] ); + + // The Expected Type. + String expectedType = pathParts[1]; + + // Sanity Check: expectedType should end in "s". + if ( !expectedType.endsWith( "s" ) ) + { + throw new LayoutException( INVALID_ARTIFACT_PATH + + "legacy paths should have an expected type ending in [s] in the second part of the path." ); + } + + // The Filename. + String filename = pathParts[2]; + + FilenameParser parser = new FilenameParser( filename ); + + artifact.setArtifactId( parser.nextNonVersion() ); + + // Sanity Check: does it have an artifact id? + if ( StringUtils.isEmpty( artifact.getArtifactId() ) ) + { + // Special Case: The filename might start with a version id (like "test-arch-1.0.jar"). + int idx = filename.indexOf( '-' ); + if ( idx > 0 ) + { + parser.reset(); + // Take the first section regardless of content. + String artifactId = parser.next(); + + // Is there anything more that is considered not a version id? + String moreArtifactId = parser.nextNonVersion(); + if ( StringUtils.isNotBlank( moreArtifactId ) ) + { + artifact.setArtifactId( artifactId + "-" + moreArtifactId ); + } + else + { + artifact.setArtifactId( artifactId ); + } + } + + // Sanity Check: still no artifact id? + if ( StringUtils.isEmpty( artifact.getArtifactId() ) ) + { + throw new LayoutException( INVALID_ARTIFACT_PATH + "no artifact id present." ); + } + } + + artifact.setVersion( parser.remaining() ); + + // Sanity Check: does it have a version? + if ( StringUtils.isEmpty( artifact.getVersion() ) ) + { + // Special Case: use last section of artifactId as version. + String artifactId = artifact.getArtifactId(); + int idx = artifactId.lastIndexOf( '-' ); + if ( idx > 0 ) + { + artifact.setVersion( artifactId.substring( idx + 1 ) ); + artifact.setArtifactId( artifactId.substring( 0, idx ) ); + } + else + { + throw new LayoutException( INVALID_ARTIFACT_PATH + "no version found." ); + } + } + + String classifier = ArtifactClassifierMapping.getClassifier( expectedType ); + if ( classifier != null ) + { + String version = artifact.getVersion(); + if ( !version.endsWith( "-" + classifier ) ) + { + throw new LayoutException( + INVALID_ARTIFACT_PATH + expectedType + " artifacts must use the classifier " + classifier ); + } + version = version.substring( 0, version.length() - classifier.length() - 1 ); + artifact.setVersion( version ); + artifact.setClassifier( classifier ); + } + + String extension = parser.getExtension(); + + // Set Type + String defaultExtension = expectedType.substring( 0, expectedType.length() - 1 ); + artifact.setType( + ArtifactExtensionMapping.mapExtensionAndClassifierToType( classifier, extension, defaultExtension ) ); + + // Sanity Check: does it have an extension? + if ( StringUtils.isEmpty( artifact.getType() ) ) + { + throw new LayoutException( INVALID_ARTIFACT_PATH + "no extension found." ); + } + + // Special Case with Maven Plugins + if ( StringUtils.equals( "jar", extension ) && StringUtils.equals( "plugins", expectedType ) ) + { + artifact.setType( ArtifactExtensionMapping.MAVEN_ONE_PLUGIN ); + } + else + { + // Sanity Check: does extension match pathType on path? + String expectedExtension = ArtifactExtensionMapping.getExtension( artifact.getType() ); + + if ( !expectedExtension.equals( extension ) ) + { + throw new LayoutException( + INVALID_ARTIFACT_PATH + "mismatch on extension [" + extension + "] and layout specified type [" + + artifact.getType() + "] (which maps to extension: [" + expectedExtension + "]) on path [" + + path + "]" ); + } + } + + return artifact; + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/ManagedLegacyRepositoryContent.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/ManagedLegacyRepositoryContent.java new file mode 100644 index 000000000..80a784e8d --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/ManagedLegacyRepositoryContent.java @@ -0,0 +1,480 @@ +package org.apache.archiva.repository.content.legacy; + +/* + * 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.admin.model.beans.ManagedRepository; +import org.apache.archiva.common.utils.PathUtil; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.model.ArchivaArtifact; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.ProjectReference; +import org.apache.archiva.model.VersionedReference; +import org.apache.archiva.repository.ContentNotFoundException; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +/** + * ManagedLegacyRepositoryContent + * + * + * @todo no need to be a component when filetypes, legacy path parser is not + */ +@Service( "managedRepositoryContent#legacy" ) +@Scope( "prototype" ) +public class ManagedLegacyRepositoryContent + extends AbstractLegacyRepositoryContent + implements ManagedRepositoryContent +{ + /** + * + */ + @Inject + private FileTypes filetypes; + + private ManagedRepository repository; + + public void deleteVersion( VersionedReference reference ) + throws ContentNotFoundException + { + File groupDir = new File( repository.getLocation(), reference.getGroupId() ); + + if ( !groupDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() ); + } + + if ( !groupDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() ); + } + + // First gather up the versions found as artifacts in the managed repository. + File typeDirs[] = groupDir.listFiles(); + for ( File typeDir : typeDirs ) + { + if ( !typeDir.isDirectory() ) + { + // Skip it, we only care about directories. + continue; + } + + if ( !typeDir.getName().endsWith( "s" ) ) + { + // Skip it, we only care about directories that end in "s". + } + + deleteVersions( typeDir, reference ); + } + } + + private void deleteVersions( File typeDir, VersionedReference reference ) + { + File repoFiles[] = typeDir.listFiles(); + for ( File repoFile : repoFiles ) + { + if ( repoFile.isDirectory() ) + { + // Skip it. it's a directory. + continue; + } + + String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile ); + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + try + { + ArtifactReference artifact = toArtifactReference( relativePath ); + if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) + && StringUtils.equals( artifact.getVersion(), reference.getVersion() ) ) + { + repoFile.delete(); + deleteSupportFiles( repoFile ); + } + } + catch ( LayoutException e ) + { + /* don't fail the process if there is a bad artifact within the directory. */ + } + } + } + } + + public void deleteProject( String namespace, String projectId ) + throws RepositoryException + { + // TODO implements ?? + } + + private void deleteSupportFiles( File repoFile ) + { + deleteSupportFile( repoFile, ".sha1" ); + deleteSupportFile( repoFile, ".md5" ); + deleteSupportFile( repoFile, ".asc" ); + deleteSupportFile( repoFile, ".gpg" ); + } + + private void deleteSupportFile( File repoFile, String supportExtension ) + { + File supportFile = new File( repoFile.getAbsolutePath() + supportExtension ); + if ( supportFile.exists() && supportFile.isFile() ) + { + supportFile.delete(); + } + } + + public String getId() + { + return repository.getId(); + } + + public Set getRelatedArtifacts( ArtifactReference reference ) + throws ContentNotFoundException + { + File artifactFile = toFile( reference ); + File repoDir = artifactFile.getParentFile(); + + if ( !repoDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() ); + } + + if ( !repoDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() ); + } + + Set foundArtifacts = new HashSet(); + + // First gather up the versions found as artifacts in the managed repository. + File projectParentDir = repoDir.getParentFile(); + File typeDirs[] = projectParentDir.listFiles(); + for ( File typeDir : typeDirs ) + { + if ( !typeDir.isDirectory() ) + { + // Skip it, we only care about directories. + continue; + } + + if ( !typeDir.getName().endsWith( "s" ) ) + { + // Skip it, we only care about directories that end in "s". + } + + getRelatedArtifacts( typeDir, reference, foundArtifacts ); + } + + return foundArtifacts; + } + + public String getRepoRoot() + { + return repository.getLocation(); + } + + public ManagedRepository getRepository() + { + return repository; + } + + public Set getVersions( ProjectReference reference ) + throws ContentNotFoundException + { + File groupDir = new File( repository.getLocation(), reference.getGroupId() ); + + if ( !groupDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() ); + } + + if ( !groupDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() ); + } + + Set foundVersions = new HashSet(); + + // First gather up the versions found as artifacts in the managed repository. + File typeDirs[] = groupDir.listFiles(); + for ( File typeDir : typeDirs ) + { + if ( !typeDir.isDirectory() ) + { + // Skip it, we only care about directories. + continue; + } + + if ( !typeDir.getName().endsWith( "s" ) ) + { + // Skip it, we only care about directories that end in "s". + } + + getProjectVersions( typeDir, reference, foundVersions ); + } + + return foundVersions; + } + + public Set getVersions( VersionedReference reference ) + throws ContentNotFoundException + { + File groupDir = new File( repository.getLocation(), reference.getGroupId() ); + + if ( !groupDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() ); + } + + if ( !groupDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() ); + } + + Set foundVersions = new HashSet(); + + // First gather up the versions found as artifacts in the managed repository. + File typeDirs[] = groupDir.listFiles(); + for ( File typeDir : typeDirs ) + { + if ( !typeDir.isDirectory() ) + { + // Skip it, we only care about directories. + continue; + } + + if ( !typeDir.getName().endsWith( "s" ) ) + { + // Skip it, we only care about directories that end in "s". + } + + getVersionedVersions( typeDir, reference, foundVersions ); + } + + return foundVersions; + } + + public boolean hasContent( ArtifactReference reference ) + { + File artifactFile = toFile( reference ); + return artifactFile.exists() && artifactFile.isFile(); + } + + public boolean hasContent( ProjectReference reference ) + { + try + { + Set versions = getVersions( reference ); + return CollectionUtils.isNotEmpty( versions ); + } + catch ( ContentNotFoundException e ) + { + return false; + } + } + + public boolean hasContent( VersionedReference reference ) + { + try + { + Set versions = getVersions( reference ); + return CollectionUtils.isNotEmpty( versions ); + } + catch ( ContentNotFoundException e ) + { + return false; + } + } + + public void setRepository( ManagedRepository repository ) + { + this.repository = repository; + } + + /** + * Convert a path to an artifact reference. + * + * @param path the path to convert. (relative or full location path) + * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference. + */ + @Override + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + if ( ( path != null ) && path.startsWith( repository.getLocation() ) ) + { + return super.toArtifactReference( path.substring( repository.getLocation().length() ) ); + } + + return super.toArtifactReference( path ); + } + + public File toFile( ArchivaArtifact reference ) + { + return new File( repository.getLocation(), toPath( reference ) ); + } + + public File toFile( ArtifactReference reference ) + { + return new File( repository.getLocation(), toPath( reference ) ); + } + + public String toMetadataPath( ProjectReference reference ) + { + // No metadata present in legacy repository. + return null; + } + + public String toMetadataPath( VersionedReference reference ) + { + // No metadata present in legacy repository. + return null; + } + + private void getProjectVersions( File typeDir, ProjectReference reference, Set foundVersions ) + { + File repoFiles[] = typeDir.listFiles(); + for ( File repoFile : repoFiles ) + { + if ( repoFile.isDirectory() ) + { + // Skip it. it's a directory. + continue; + } + + String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile ); + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + try + { + ArtifactReference artifact = toArtifactReference( relativePath ); + if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) ) + { + foundVersions.add( artifact.getVersion() ); + } + } + catch ( LayoutException e ) + { + /* don't fail the process if there is a bad artifact within the directory. */ + } + } + } + } + + private void getRelatedArtifacts( File typeDir, ArtifactReference reference, Set foundArtifacts ) + { + File repoFiles[] = typeDir.listFiles(); + for ( int i = 0; i < repoFiles.length; i++ ) + { + if ( repoFiles[i].isDirectory() ) + { + // Skip it. it's a directory. + continue; + } + + String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] ); + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + try + { + ArtifactReference artifact = toArtifactReference( relativePath ); + if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) + && artifact.getVersion().startsWith( reference.getVersion() ) ) + { + foundArtifacts.add( artifact ); + } + } + catch ( LayoutException e ) + { + /* don't fail the process if there is a bad artifact within the directory. */ + } + } + } + } + + private void getVersionedVersions( File typeDir, VersionedReference reference, Set foundVersions ) + { + File repoFiles[] = typeDir.listFiles(); + for ( int i = 0; i < repoFiles.length; i++ ) + { + if ( repoFiles[i].isDirectory() ) + { + // Skip it. it's a directory. + continue; + } + + String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] ); + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + try + { + ArtifactReference artifact = toArtifactReference( relativePath ); + if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) + && artifact.getVersion().startsWith( reference.getVersion() ) ) + { + foundVersions.add( artifact.getVersion() ); + } + } + catch ( LayoutException e ) + { + /* don't fail the process if there is a bad artifact within the directory. */ + } + } + } + } + + public void setFileTypes( FileTypes fileTypes ) + { + this.filetypes = fileTypes; + } + + public void deleteArtifact( ArtifactReference artifactReference ) + throws ContentNotFoundException + { + // TODO implements for legacy ?? + } + + public void deleteGroupId( String groupId ) + throws ContentNotFoundException + { + // TODO implements for legacy ?? + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/RemoteLegacyRepositoryContent.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/RemoteLegacyRepositoryContent.java new file mode 100644 index 000000000..0273e61af --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/legacy/RemoteLegacyRepositoryContent.java @@ -0,0 +1,88 @@ +package org.apache.archiva.repository.content.legacy; + +/* + * 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.admin.model.beans.RemoteRepository; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.RepositoryURL; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.content.legacy.AbstractLegacyRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +/** + * RemoteLegacyRepositoryContent + * + * + * @todo no need to be a component once legacy path parser is not + */ +@Service( "remoteRepositoryContent#legacy" ) +@Scope( "prototype" ) +public class RemoteLegacyRepositoryContent + extends AbstractLegacyRepositoryContent + implements RemoteRepositoryContent +{ + private RemoteRepository repository; + + public String getId() + { + return repository.getId(); + } + + public RemoteRepository getRepository() + { + return repository; + } + + public RepositoryURL getURL() + { + return new RepositoryURL( repository.getUrl() ); + } + + public void setRepository( RemoteRepository repository ) + { + this.repository = repository; + } + + /** + * Convert a path to an artifact reference. + * + * @param path the path to convert. (relative or full url path) + * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference. + */ + @Override + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + if ( path.startsWith( repository.getUrl() ) ) + { + return super.toArtifactReference( path.substring( repository.getUrl().length() ) ); + } + + return super.toArtifactReference( path ); + } + + public RepositoryURL toURL( ArtifactReference reference ) + { + String url = repository.getUrl() + toPath( reference ); + return new RepositoryURL( url ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java new file mode 100644 index 000000000..4f8b80cbd --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/AbstractDefaultRepositoryContent.java @@ -0,0 +1,183 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.common.utils.VersionUtil; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.maven2.Maven2RepositoryPathTranslator; +import org.apache.archiva.model.ArchivaArtifact; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.ProjectReference; +import org.apache.archiva.model.VersionedReference; +import org.apache.archiva.repository.content.PathParser; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.util.List; + +/** + * AbstractDefaultRepositoryContent - common methods for working with default (maven 2) layout. + */ +public abstract class AbstractDefaultRepositoryContent +{ + protected Logger log = LoggerFactory.getLogger( getClass() ); + + public static final String MAVEN_METADATA = "maven-metadata.xml"; + + protected static final char PATH_SEPARATOR = '/'; + + protected static final char GROUP_SEPARATOR = '.'; + + protected static final char ARTIFACT_SEPARATOR = '-'; + + private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator(); + + private PathParser defaultPathParser = new DefaultPathParser(); + + /** + * + */ + @Inject + protected List artifactMappingProviders; + + @PostConstruct + protected void initialize() + { + // no op + } + + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + return defaultPathParser.toArtifactReference( path ); + } + + public String toMetadataPath( ProjectReference reference ) + { + StringBuilder path = new StringBuilder(); + + path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR ); + path.append( reference.getArtifactId() ).append( PATH_SEPARATOR ); + path.append( MAVEN_METADATA ); + + return path.toString(); + } + + public String toMetadataPath( VersionedReference reference ) + { + StringBuilder path = new StringBuilder(); + + 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(); + } + + public String toPath( ArchivaArtifact reference ) + { + if ( reference == null ) + { + throw new IllegalArgumentException( "ArchivaArtifact cannot be null" ); + } + + String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() ); + return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(), + reference.getClassifier(), reference.getType() ); + } + + public String toPath( ArtifactReference reference ) + { + if ( reference == null ) + { + throw new IllegalArgumentException( "Artifact reference cannot be null" ); + } + if ( reference.getVersion() != null ) + { + String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() ); + return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(), + reference.getClassifier(), reference.getType() ); + } + return toPath( reference.getGroupId(), reference.getArtifactId(), null, null, + reference.getClassifier(), reference.getType() ); + } + + private String formatAsDirectory( String directory ) + { + return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR ); + } + + private String toPath( String groupId, String artifactId, String baseVersion, String version, String classifier, + String type ) + { + if ( baseVersion != null ) + { + return pathTranslator.toPath( groupId, artifactId, baseVersion, + constructId( artifactId, version, classifier, type ) ); + } + else + { + return pathTranslator.toPath( groupId, artifactId ); + } + } + + // TODO: move into the Maven Artifact facet when refactoring away the caller - the caller will need to have access + // to the facet or filename (for the original ID) + private String constructId( String artifactId, String version, String classifier, String type ) + { + String ext = null; + for ( ArtifactMappingProvider provider : artifactMappingProviders ) + { + ext = provider.mapTypeToExtension( type ); + if ( ext != null ) + { + break; + } + } + if ( ext == null ) + { + ext = type; + } + + StringBuilder id = new StringBuilder(); + if ( ( version != null ) && ( type != null ) ) + { + id.append( artifactId ).append( ARTIFACT_SEPARATOR ).append( version ); + + if ( StringUtils.isNotBlank( classifier ) ) + { + id.append( ARTIFACT_SEPARATOR ).append( classifier ); + } + + id.append( "." ).append( ext ); + } + return id.toString(); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/ArtifactExtensionMapping.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/ArtifactExtensionMapping.java new file mode 100644 index 000000000..d863a33a2 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/ArtifactExtensionMapping.java @@ -0,0 +1,78 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.metadata.repository.storage.maven2.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.maven2.DefaultArtifactMappingProvider; + +/** + * ArtifactExtensionMapping + * + * + */ +public class ArtifactExtensionMapping +{ + public static final String MAVEN_ONE_PLUGIN = "maven-one-plugin"; + + // TODO: now only used in Maven 1, we should be using M1 specific mappings + private static final ArtifactMappingProvider mapping = new DefaultArtifactMappingProvider(); + + public static String getExtension( String type ) + { + String ext = mapping.mapTypeToExtension( type ); + + if ( ext == null ) + { + ext = type; + } + + return ext; + } + + public static String mapExtensionAndClassifierToType( String classifier, String extension ) + { + return mapExtensionAndClassifierToType( classifier, extension, extension ); + } + + public static String mapExtensionAndClassifierToType( String classifier, String extension, + String defaultExtension ) + { + String value = mapping.mapClassifierAndExtensionToType( classifier, extension ); + if ( value == null ) + { + // TODO: Maven 1 plugin + String value1 = null; + if ( "tar.gz".equals( extension ) ) + { + value1 = "distribution-tgz"; + } + else if ( "tar.bz2".equals( extension ) ) + { + value1 = "distribution-bzip"; + } + else if ( "zip".equals( extension ) ) + { + value1 = "distribution-zip"; + } + value = value1; + } + return value != null ? value : defaultExtension; + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/DefaultPathParser.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/DefaultPathParser.java new file mode 100644 index 000000000..c90eda9da --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/DefaultPathParser.java @@ -0,0 +1,90 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.maven2.DefaultArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.maven2.Maven2RepositoryPathTranslator; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.content.PathParser; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Collections; + +/** + * DefaultPathParser is a parser for maven 2 (default layout) paths to ArtifactReference. + * + * TODO: remove in favour of path translator, this is just delegating for the most part, but won't accommodate other + * extensions like NPanday + * + * + */ +@Service( "pathParser#default" ) +public class DefaultPathParser + implements PathParser +{ + private static final String INVALID_ARTIFACT_PATH = "Invalid path to Artifact: "; + + private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator( + Collections.singletonList( new DefaultArtifactMappingProvider() ) ); + + /** + * {@inheritDoc} + * + * @see org.apache.archiva.repository.content.PathParser#toArtifactReference(String) + */ + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + if ( StringUtils.isBlank( path ) ) + { + throw new LayoutException( "Unable to convert blank path." ); + } + + ArtifactMetadata metadata; + try + { + metadata = pathTranslator.getArtifactForPath( null, path ); + } + catch ( IllegalArgumentException e ) + { + throw new LayoutException( e.getMessage(), e ); + } + + ArtifactReference artifact = new ArtifactReference(); + artifact.setGroupId( metadata.getNamespace() ); + artifact.setArtifactId( metadata.getProject() ); + artifact.setVersion( metadata.getVersion() ); + MavenArtifactFacet facet = (MavenArtifactFacet) metadata.getFacet( MavenArtifactFacet.FACET_ID ); + if ( facet != null ) + { + artifact.setClassifier( facet.getClassifier() ); + artifact.setType( facet.getType() ); + } + + return artifact; + } + +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/FilenameParser.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/FilenameParser.java new file mode 100644 index 000000000..e40887765 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/FilenameParser.java @@ -0,0 +1,259 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.common.utils.VersionUtil; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Generic Filename Parser for use with layout routines. + * + * + */ +public class FilenameParser +{ + private String name; + + private String extension; + + private int offset; + + private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" ); + + private static final Pattern extensionPattern = + Pattern.compile( "(\\.tar\\.gz$)|(\\.tar\\.bz2$)|(\\.[\\-a-z0-9]*$)", Pattern.CASE_INSENSITIVE ); + + private static final Pattern SNAPSHOT_PATTERN = Pattern.compile( "^([0-9]{8}\\.[0-9]{6}-[0-9]+)(.*)$" ); + + private static final Pattern section = Pattern.compile( "([^-]*)" ); + + private Matcher matcher; + + public FilenameParser( String filename ) + { + this.name = filename; + + Matcher mat = extensionPattern.matcher( name ); + if ( mat.find() ) + { + extension = filename.substring( mat.start() + 1 ); + name = name.substring( 0, name.length() - extension.length() - 1 ); + } + + matcher = section.matcher( name ); + + reset(); + } + + public void reset() + { + offset = 0; + } + + public String next() + { + // Past the end of the string. + if ( offset > name.length() ) + { + return null; + } + + // Return the next section. + if ( matcher.find( offset ) ) + { + // Return found section. + offset = matcher.end() + 1; + return matcher.group(); + } + + // Nothing to return. + return null; + } + + protected String expect( String expected ) + { + String value = null; + + if ( name.startsWith( expected, offset ) ) + { + value = expected; + } + else if ( VersionUtil.isGenericSnapshot( expected ) ) + { + String version = name.substring( offset ); + + // check it starts with the same version up to the snapshot part + int leadingLength = expected.length() - 9; + if ( leadingLength > 0 && version.startsWith( expected.substring( 0, leadingLength ) ) && + version.length() > leadingLength ) + { + // If we expect a non-generic snapshot - look for the timestamp + Matcher m = SNAPSHOT_PATTERN.matcher( version.substring( leadingLength + 1 ) ); + if ( m.matches() ) + { + value = version.substring( 0, leadingLength + 1 ) + m.group( 1 ); + } + } + } + + if ( value != null ) + { + // Potential hit. check for '.' or '-' at end of expected. + int seperatorOffset = offset + value.length(); + + // Test for "out of bounds" first. + if ( seperatorOffset >= name.length() ) + { + offset = name.length(); + return value; + } + + // Test for seperator char. + char seperatorChar = name.charAt( seperatorOffset ); + if ( ( seperatorChar == '-' ) || ( seperatorChar == '.' ) ) + { + offset = seperatorOffset + 1; + return value; + } + } + + return null; + } + + /** + * Get the current seperator character. + * + * @return the seperator character (either '.' or '-'), or 0 if no seperator character available. + */ + protected char seperator() + { + // Past the end of the string? + if ( offset >= name.length() ) + { + return 0; + } + + // Before the start of the string? + if ( offset <= 0 ) + { + return 0; + } + + return name.charAt( offset - 1 ); + } + + protected String getName() + { + return name; + } + + public String getExtension() + { + return extension; + } + + public String remaining() + { + if ( offset >= name.length() ) + { + return null; + } + + String end = name.substring( offset ); + offset = name.length(); + return end; + } + + public String nextNonVersion() + { + boolean done = false; + + StringBuilder ver = new StringBuilder(); + + // Any text upto the end of a special case is considered non-version. + Matcher specialMat = mavenPluginPattern.matcher( name ); + if ( specialMat.find() ) + { + ver.append( name.substring( offset, specialMat.end() ) ); + offset = specialMat.end() + 1; + } + + while ( !done ) + { + int initialOffset = offset; + String section = next(); + if ( section == null ) + { + done = true; + } + else if ( !VersionUtil.isVersion( section ) ) + { + if ( ver.length() > 0 ) + { + ver.append( '-' ); + } + ver.append( section ); + } + else + { + offset = initialOffset; + done = true; + } + } + + return ver.toString(); + } + + protected String nextVersion() + { + boolean done = false; + + StringBuilder ver = new StringBuilder(); + + while ( !done ) + { + int initialOffset = offset; + String section = next(); + if ( section == null ) + { + done = true; + } + else if ( VersionUtil.isVersion( section ) ) + { + if ( ver.length() > 0 ) + { + ver.append( '-' ); + } + ver.append( section ); + } + else + { + offset = initialOffset; + done = true; + } + } + + return ver.toString(); + } + + +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java new file mode 100644 index 000000000..e30a16712 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/ManagedDefaultRepositoryContent.java @@ -0,0 +1,496 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.admin.model.beans.ManagedRepository; +import org.apache.archiva.common.utils.PathUtil; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.metadata.repository.storage.maven2.DefaultArtifactMappingProvider; +import org.apache.archiva.model.ArchivaArtifact; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.ProjectReference; +import org.apache.archiva.model.VersionedReference; +import org.apache.archiva.repository.ContentNotFoundException; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RepositoryException; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * ManagedDefaultRepositoryContent + */ +@Service ("managedRepositoryContent#default") +@Scope ("prototype") +public class ManagedDefaultRepositoryContent + extends AbstractDefaultRepositoryContent + implements ManagedRepositoryContent +{ + @Inject + @Named (value = "fileTypes") + private FileTypes filetypes; + + private ManagedRepository repository; + + public ManagedDefaultRepositoryContent() + { + // default to use if there are none supplied as components + this.artifactMappingProviders = Collections.singletonList( new DefaultArtifactMappingProvider() ); + } + + public void deleteVersion( VersionedReference reference ) + { + String path = toMetadataPath( reference ); + File projectPath = new File( getRepoRoot(), path ); + + File projectDir = projectPath.getParentFile(); + if ( projectDir.exists() && projectDir.isDirectory() ) + { + FileUtils.deleteQuietly( projectDir ); + } + } + + public void deleteProject( String namespace, String projectId ) + throws RepositoryException, ContentNotFoundException + { + ArtifactReference artifactReference = new ArtifactReference(); + artifactReference.setGroupId( namespace ); + artifactReference.setArtifactId( projectId ); + String path = toPath( artifactReference ); + File directory = new File( getRepoRoot(), path ); + if ( !directory.exists() ) + { + throw new ContentNotFoundException( "cannot found project " + namespace + ":" + projectId ); + } + if ( directory.isDirectory() ) + { + try + { + FileUtils.deleteDirectory( directory ); + } + catch ( IOException e ) + { + throw new RepositoryException( e.getMessage(), e ); + } + } + else + { + log.warn( "project {}:{} is not a directory", namespace, projectId ); + } + + } + + public void deleteArtifact( ArtifactReference artifactReference ) + { + String path = toPath( artifactReference ); + File filePath = new File( getRepoRoot(), path ); + + if ( filePath.exists() ) + { + FileUtils.deleteQuietly( filePath ); + } + + File filePathmd5 = new File( getRepoRoot(), path + ".md5" ); + + if ( filePathmd5.exists() ) + { + FileUtils.deleteQuietly( filePathmd5 ); + } + + File filePathsha1 = new File( getRepoRoot(), path + ".sha1" ); + + if ( filePathsha1.exists() ) + { + FileUtils.deleteQuietly( filePathsha1 ); + } + } + + public void deleteGroupId( String groupId ) + throws ContentNotFoundException + { + + String path = StringUtils.replaceChars( groupId, '.', '/' ); + + File directory = new File( getRepoRoot(), path ); + + if ( directory.exists() ) + { + try + { + FileUtils.deleteDirectory( directory ); + } + catch ( IOException e ) + { + log.warn( "skip error deleting directory {}:", directory.getPath(), e ); + } + } + } + + public String getId() + { + return repository.getId(); + } + + public Set getRelatedArtifacts( ArtifactReference reference ) + throws ContentNotFoundException + { + File artifactFile = toFile( reference ); + File repoDir = artifactFile.getParentFile(); + + if ( !repoDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() ); + } + + if ( !repoDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() ); + } + + Set foundArtifacts = new HashSet(); + + // First gather up the versions found as artifacts in the managed repository. + 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( repository.getLocation(), repoFiles[i] ); + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + try + { + ArtifactReference artifact = toArtifactReference( relativePath ); + + // Test for related, groupId / artifactId / version must match. + if ( artifact.getGroupId().equals( reference.getGroupId() ) && artifact.getArtifactId().equals( + reference.getArtifactId() ) && artifact.getVersion().equals( reference.getVersion() ) ) + { + foundArtifacts.add( artifact ); + } + } + catch ( LayoutException e ) + { + log.debug( "Not processing file that is not an artifact: {}", e.getMessage() ); + } + } + } + + return foundArtifacts; + } + + public String getRepoRoot() + { + return repository.getLocation(); + } + + public ManagedRepository getRepository() + { + return repository; + } + + /** + * Gather the Available Versions (on disk) for a specific Project Reference, based on filesystem + * information. + * + * @return the Set of available versions, based on the project reference. + * @throws org.apache.archiva.repository.layout.LayoutException + * @throws org.apache.archiva.repository.layout.LayoutException + */ + public Set getVersions( ProjectReference reference ) + throws ContentNotFoundException, LayoutException + { + String path = toMetadataPath( reference ); + + int idx = path.lastIndexOf( '/' ); + if ( idx > 0 ) + { + path = path.substring( 0, idx ); + } + + File repoDir = new File( repository.getLocation(), path ); + + if ( !repoDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get Versions on a non-existant directory: " + repoDir.getAbsolutePath() ); + } + + if ( !repoDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get Versions on a non-directory: " + repoDir.getAbsolutePath() ); + } + + Set foundVersions = new HashSet(); + VersionedReference versionRef = new VersionedReference(); + versionRef.setGroupId( reference.getGroupId() ); + versionRef.setArtifactId( reference.getArtifactId() ); + + File repoFiles[] = repoDir.listFiles(); + for ( int i = 0; i < repoFiles.length; i++ ) + { + if ( !repoFiles[i].isDirectory() ) + { + // Skip it. not a directory. + continue; + } + + // Test if dir has an artifact, which proves to us that it is a valid version directory. + String version = repoFiles[i].getName(); + versionRef.setVersion( version ); + + if ( hasArtifact( versionRef ) ) + { + // Found an artifact, must be a valid version. + foundVersions.add( version ); + } + } + + return foundVersions; + } + + public Set getVersions( VersionedReference reference ) + throws ContentNotFoundException + { + String path = toMetadataPath( reference ); + + int idx = path.lastIndexOf( '/' ); + if ( idx > 0 ) + { + path = path.substring( 0, idx ); + } + + File repoDir = new File( repository.getLocation(), path ); + + if ( !repoDir.exists() ) + { + throw new ContentNotFoundException( + "Unable to get versions on a non-existant directory: " + repoDir.getAbsolutePath() ); + } + + if ( !repoDir.isDirectory() ) + { + throw new ContentNotFoundException( + "Unable to get versions on a non-directory: " + repoDir.getAbsolutePath() ); + } + + Set foundVersions = new HashSet(); + + // First gather up the versions found as artifacts in the managed repository. + 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( repository.getLocation(), repoFiles[i] ); + + if ( filetypes.matchesDefaultExclusions( relativePath ) ) + { + // Skip it, it's metadata or similar + continue; + } + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + try + { + ArtifactReference artifact = toArtifactReference( relativePath ); + + foundVersions.add( artifact.getVersion() ); + } + catch ( LayoutException e ) + { + log.debug( "Not processing file that is not an artifact: {}", e.getMessage() ); + } + } + } + + return foundVersions; + } + + public boolean hasContent( ArtifactReference reference ) + { + File artifactFile = toFile( reference ); + return artifactFile.exists() && artifactFile.isFile(); + } + + public boolean hasContent( ProjectReference reference ) + { + try + { + Set versions = getVersions( reference ); + return !versions.isEmpty(); + } + catch ( ContentNotFoundException e ) + { + return false; + } + catch ( LayoutException e ) + { + return false; + } + } + + public boolean hasContent( VersionedReference reference ) + { + try + { + return ( getFirstArtifact( reference ) != null ); + } + catch ( IOException e ) + { + return false; + } + catch ( LayoutException e ) + { + return false; + } + } + + public void setRepository( ManagedRepository repository ) + { + this.repository = repository; + } + + /** + * Convert a path to an artifact reference. + * + * @param path the path to convert. (relative or full location path) + * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference. + */ + @Override + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + if ( ( path != null ) && path.startsWith( repository.getLocation() ) && repository.getLocation().length() > 0 ) + { + return super.toArtifactReference( path.substring( repository.getLocation().length() + 1 ) ); + } + + return super.toArtifactReference( path ); + } + + public File toFile( ArtifactReference reference ) + { + return new File( repository.getLocation(), toPath( reference ) ); + } + + public File toFile( ArchivaArtifact reference ) + { + return new File( repository.getLocation(), toPath( reference ) ); + } + + /** + * Get the first Artifact found in the provided VersionedReference location. + * + * @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 java.io.IOException if the versioned reference is invalid (example: doesn't exist, or isn't a directory) + * @throws org.apache.archiva.repository.layout.LayoutException + */ + private ArtifactReference getFirstArtifact( VersionedReference reference ) + throws LayoutException, IOException + { + String path = toMetadataPath( reference ); + + int idx = path.lastIndexOf( '/' ); + if ( idx > 0 ) + { + path = path.substring( 0, idx ); + } + + File repoDir = new File( repository.getLocation(), 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( repository.getLocation(), repoFiles[i] ); + + if ( filetypes.matchesArtifactPattern( relativePath ) ) + { + ArtifactReference artifact = toArtifactReference( relativePath ); + + return artifact; + } + } + + // No artifact was found. + return null; + } + + private boolean hasArtifact( VersionedReference reference ) + throws LayoutException + { + try + { + return ( getFirstArtifact( reference ) != null ); + } + catch ( IOException e ) + { + return false; + } + } + + public void setFiletypes( FileTypes filetypes ) + { + this.filetypes = filetypes; + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/RemoteDefaultRepositoryContent.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/RemoteDefaultRepositoryContent.java new file mode 100644 index 000000000..9d0dfbe13 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/RemoteDefaultRepositoryContent.java @@ -0,0 +1,86 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.admin.model.beans.RemoteRepository; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.RepositoryURL; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +/** + * RemoteDefaultRepositoryContent + * + * + */ +@Service( "remoteRepositoryContent#default" ) +@Scope( "prototype" ) +public class RemoteDefaultRepositoryContent + extends AbstractDefaultRepositoryContent + implements RemoteRepositoryContent +{ + private RemoteRepository repository; + + public String getId() + { + return repository.getId(); + } + + public RemoteRepository getRepository() + { + return repository; + } + + public RepositoryURL getURL() + { + return new RepositoryURL( repository.getUrl() ); + } + + public void setRepository( RemoteRepository repository ) + { + this.repository = repository; + } + + /** + * Convert a path to an artifact reference. + * + * @param path the path to convert. (relative or full url path) + * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference. + */ + @Override + public ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + if ( ( path != null ) && path.startsWith( repository.getUrl() ) ) + { + return super.toArtifactReference( path.substring( repository.getUrl().length() ) ); + } + + return super.toArtifactReference( path ); + } + + public RepositoryURL toURL( ArtifactReference reference ) + { + String url = repository.getUrl() + toPath( reference ); + return new RepositoryURL( url ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/RepositoryRequest.java b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/RepositoryRequest.java new file mode 100644 index 000000000..e678f2d59 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/repository/content/maven2/RepositoryRequest.java @@ -0,0 +1,287 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.model.ArtifactReference; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.content.PathParser; +import org.apache.archiva.repository.content.legacy.LegacyPathParser; +import org.apache.archiva.repository.content.legacy.ManagedLegacyRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.repository.metadata.MetadataTools; +import org.apache.commons.lang.StringUtils; + +/** + * RepositoryRequest is used to determine the type of request that is incoming, and convert it to an appropriate + * ArtifactReference. + *

+ *

+ *

+ */ +public class RepositoryRequest +{ + private PathParser defaultPathParser = new DefaultPathParser(); + + private PathParser legacyPathParser; + + public RepositoryRequest( LegacyPathParser legacyPathParser ) + { + this.legacyPathParser = legacyPathParser; + } + + /** + * Takes an incoming requested path (in "/" format) and gleans the layout + * and ArtifactReference appropriate for that content. + * + * @param requestedPath the relative path to the content. + * @return the ArtifactReference for the requestedPath. + * @throws org.apache.archiva.repository.layout.LayoutException if the request path is not layout valid. + */ + public ArtifactReference toArtifactReference( String requestedPath ) + throws LayoutException + { + if ( StringUtils.isBlank( requestedPath ) ) + { + throw new LayoutException( "Blank request path is not a valid." ); + } + + String path = requestedPath; + while ( path.startsWith( "/" ) ) + { + path = path.substring( 1 ); + + // Only slash? that's bad, mmm-kay? + if ( "/".equals( path ) ) + { + throw new LayoutException( "Invalid request path: Slash only." ); + } + } + + if ( isDefault( path ) ) + { + return defaultPathParser.toArtifactReference( path ); + } + else if ( isLegacy( path ) ) + { + return legacyPathParser.toArtifactReference( path ); + } + else + { + throw new LayoutException( "Not a valid request path layout, too short." ); + } + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a metadata request. + *

+ *

+ * NOTE: This does a cursory check on the path's last element. A result of true + * from this method is not a guarantee that the metadata is in a valid format, or + * that it even contains data. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely a metadata request. + */ + public boolean isMetadata( String requestedPath ) + { + return requestedPath.endsWith( "/" + MetadataTools.MAVEN_METADATA ); + } + + /** + * @param requestedPath + * @return true if the requestedPath is likely an archetype catalog request. + */ + public boolean isArchetypeCatalog( String requestedPath ) + { + return requestedPath.endsWith( "/" + MetadataTools.MAVEN_ARCHETYPE_CATALOG ); + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a support file request. + *

+ *

+ * Tests for .sha1, .md5, .asc, and .php. + *

+ *

+ * NOTE: This does a cursory check on the path's extension only. A result of true + * from this method is not a guarantee that the support resource is in a valid format, or + * that it even contains data. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely that of a support file request. + */ + public boolean isSupportFile( String requestedPath ) + { + int idx = requestedPath.lastIndexOf( '.' ); + if ( idx <= 0 ) + { + return false; + } + + String ext = requestedPath.substring( idx ); + return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) ); + } + + public boolean isMetadataSupportFile( String requestedPath ) + { + if ( isSupportFile( requestedPath ) ) + { + String basefilePath = StringUtils.substring( requestedPath, 0, requestedPath.lastIndexOf( '.' ) ); + if ( isMetadata( basefilePath ) ) + { + return true; + } + } + + return false; + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a default layout request. + *

+ *

+ * NOTE: This does a cursory check on the count of path elements only. A result of + * true from this method is not a guarantee that the path sections are valid and + * can be resolved to an artifact reference. use {@link #toArtifactReference(String)} + * if you want a more complete analysis of the validity of the path. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely that of a default layout request. + */ + public boolean isDefault( String requestedPath ) + { + if ( StringUtils.isBlank( requestedPath ) ) + { + return false; + } + + String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' ); + if ( pathParts.length > 3 ) + { + return true; + } + else if ( pathParts.length == 3 ) + { + // check if artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml) + if ( isMetadata( requestedPath ) ) + { + return true; + } + else + { + // check if checksum of artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml.sha1) + int idx = requestedPath.lastIndexOf( '.' ); + if ( idx > 0 ) + { + String base = requestedPath.substring( 0, idx ); + if ( isMetadata( base ) && isSupportFile( requestedPath ) ) + { + return true; + } + } + + return false; + } + } + else + { + return false; + } + } + + /** + *

+ * Tests the path to see if it conforms to the expectations of a legacy layout request. + *

+ *

+ * NOTE: This does a cursory check on the count of path elements only. A result of + * true from this method is not a guarantee that the path sections are valid and + * can be resolved to an artifact reference. use {@link #toArtifactReference(String)} + * if you want a more complete analysis of the validity of the path. + *

+ * + * @param requestedPath the path to test. + * @return true if the requestedPath is likely that of a legacy layout request. + */ + public boolean isLegacy( String requestedPath ) + { + if ( StringUtils.isBlank( requestedPath ) ) + { + return false; + } + + String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' ); + return pathParts.length == 3; + } + + /** + * Adjust the requestedPath to conform to the native layout of the provided {@link org.apache.archiva.repository.ManagedRepositoryContent}. + * + * @param requestedPath the incoming requested path. + * @param repository the repository to adjust to. + * @return the adjusted (to native) path. + * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be parsed. + */ + public String toNativePath( String requestedPath, ManagedRepositoryContent repository ) + throws LayoutException + { + if ( StringUtils.isBlank( requestedPath ) ) + { + throw new LayoutException( "Request Path is blank." ); + } + + String referencedResource = requestedPath; + // No checksum by default. + String supportfile = ""; + + // Figure out support file, and actual referencedResource. + if ( isSupportFile( requestedPath ) ) + { + int idx = requestedPath.lastIndexOf( '.' ); + referencedResource = requestedPath.substring( 0, idx ); + supportfile = requestedPath.substring( idx ); + } + + if ( isMetadata( referencedResource ) ) + { + if ( repository instanceof ManagedLegacyRepositoryContent ) + { + throw new LayoutException( "Cannot translate metadata request to legacy layout." ); + } + + /* Nothing to translate. + * Default layout is the only layout that can contain maven-metadata.xml files, and + * if the managedRepository is layout legacy, this request would never occur. + */ + return requestedPath; + } + + // Treat as an artifact reference. + ArtifactReference ref = toArtifactReference( referencedResource ); + String adjustedPath = repository.toPath( ref ); + return adjustedPath + supportfile; + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractDefaultRepositoryContentTestCase.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractDefaultRepositoryContentTestCase.java new file mode 100644 index 000000000..5f6eb669b --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractDefaultRepositoryContentTestCase.java @@ -0,0 +1,482 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.model.ArtifactReference; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.lang.StringUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.Assert.*; + +/** + * AbstractDefaultRepositoryContentTestCase + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public abstract class AbstractDefaultRepositoryContentTestCase +{ + @Test + public void testBadPathMissingType() + { + assertBadPath( "invalid/invalid/1/invalid-1", "missing type" ); + } + + @Test + public void testBadPathReleaseInSnapshotDir() + { + assertBadPath( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", "non snapshot artifact inside of a snapshot dir" ); + } + + @Test + public void testBadPathTimestampedSnapshotNotInSnapshotDir() + { + assertBadPath( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", + "Timestamped Snapshot artifact not inside of an Snapshot dir" ); + } + + @Test + public void testBadPathTooShort() + { + assertBadPath( "invalid/invalid-1.0.jar", "path is too short" ); + } + + @Test + public void testBadPathVersionMismatchA() + { + assertBadPath( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" ); + } + + @Test + public void testBadPathVersionMismatchB() + { + assertBadPath( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" ); + } + + @Test + public void testBadPathWrongArtifactId() + { + assertBadPath( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar", + "wrong artifact id" ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecGanymedSsh2() + throws LayoutException + { + String groupId = "ch.ethz.ganymed"; + String artifactId = "ganymed-ssh2"; + String version = "build210"; + String classifier = null; + String type = "jar"; + String path = "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxComm() + throws LayoutException + { + String groupId = "javax"; + String artifactId = "comm"; + String version = "3.0-u1"; + String classifier = null; + String type = "jar"; + String path = "javax/comm/3.0-u1/comm-3.0-u1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the ejb-client type spec. + * Type specs are not a 1 to 1 map to the extension. + * This tests that effect. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + /* TODO: Re-enabled in the future. + public void testGoodFooEjbClient() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-client"; + String version = "1.0"; + String classifier = null; + String type = "ejb-client"; // oddball type-spec (should result in jar extension) + String path = "com/foo/foo-client/1.0/foo-client-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + */ + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxPersistence() + throws LayoutException + { + String groupId = "javax.persistence"; + String artifactId = "ejb"; + String version = "3.0-public_review"; + String classifier = null; + String type = "jar"; + String path = "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar"; + + /* + * The version id of "public_review" can cause problems. is it part of + * the version spec? or the classifier? + * Since the path spec below shows it in the path, then it is really + * part of the version spec. + */ + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodComFooTool() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-tool"; + String version = "1.0"; + String classifier = null; + String type = "jar"; + String path = "com/foo/foo-tool/1.0/foo-tool-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodCommonsLang() + throws LayoutException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String classifier = null; + String type = "jar"; + String path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-486] Can not deploy artifact test.maven-arch:test-arch due to "No ArtifactID Detected" + */ + @Test + public void testGoodDashedArtifactId() + throws LayoutException + { + String groupId = "test.maven-arch"; + String artifactId = "test-arch"; + String version = "2.0.3-SNAPSHOT"; + String classifier = null; + String type = "pom"; + String path = "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * It may seem odd, but this is a valid artifact. + */ + @Test + public void testGoodDotNotationArtifactId() + throws LayoutException + { + String groupId = "com.company.department"; + String artifactId = "com.company.department"; + String version = "0.2"; + String classifier = null; + String type = "pom"; + String path = "com/company/department/com.company.department/0.2/com.company.department-0.2.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * It may seem odd, but this is a valid artifact. + */ + @Test + public void testGoodDotNotationSameGroupIdAndArtifactId() + throws LayoutException + { + String groupId = "com.company.department"; + String artifactId = "com.company.department.project"; + String version = "0.3"; + String classifier = null; + String type = "pom"; + String path = "com/company/department/com.company.department.project/0.3/com.company.department.project-0.3.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the classifier, and java-source type spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibSources() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String classifier = "sources"; + String type = "java-source"; // oddball type-spec (should result in jar extension) + String path = "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodSnapshotMavenTest() + throws LayoutException + { + String groupId = "org.apache.archiva.test"; + String artifactId = "redonkulous"; + String version = "3.1-beta-1-20050831.101112-42"; + String classifier = null; + String type = "jar"; + String path = "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-519] version identifiers within filename cause misidentification of version. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodVersionKeywordInArtifactId() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String classifier = null; + String type = "pom"; + String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodDetectMavenTestPlugin() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String classifier = null; + String type = "maven-plugin"; + String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectCoberturaMavenPlugin() + throws LayoutException + { + String groupId = "org.codehaus.mojo"; + String artifactId = "cobertura-maven-plugin"; + String version = "2.1"; + String classifier = null; + String type = "maven-plugin"; + String path = "org/codehaus/mojo/cobertura-maven-plugin/2.1/cobertura-maven-plugin-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testToArtifactOnEmptyPath() + { + try + { + toArtifactReference( "" ); + fail( "Should have failed due to empty path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactOnNullPath() + { + try + { + toArtifactReference( null ); + fail( "Should have failed due to null path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactReferenceOnEmptyPath() + { + try + { + toArtifactReference( "" ); + fail( "Should have failed due to empty path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactReferenceOnNullPath() + { + try + { + toArtifactReference( null ); + fail( "Should have failed due to null path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToPathOnNullArtifactReference() + + { + try + { + ArtifactReference reference = null; + toPath( reference ); + fail( "Should have failed due to null artifact reference." ); + } + catch ( IllegalArgumentException e ) + { + /* expected path */ + } + } + + private void assertArtifactReference( ArtifactReference actualReference, String groupId, String artifactId, + String version, String classifier, String type ) + { + String expectedId = "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + + ":" + type; + + assertNotNull( expectedId + " - Should not be null.", actualReference ); + + assertEquals( expectedId + " - Group ID", groupId, actualReference.getGroupId() ); + assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); + if ( StringUtils.isNotBlank( classifier ) ) + { + assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() ); + } + assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); + assertEquals( expectedId + " - Type", type, actualReference.getType() ); + } + + private void assertBadPath( String path, String reason ) + { + try + { + toArtifactReference( path ); + fail( "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + /** + * Perform a roundtrip through the layout routines to determine success. + */ + private void assertLayout( String path, String groupId, String artifactId, String version, String classifier, + String type ) + throws LayoutException + { + ArtifactReference expectedArtifact = createArtifact( groupId, artifactId, version, classifier, type ); + + // --- Artifact Tests. + + // Artifact to Path + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); + + // --- Artifact Reference Tests + + // Path to Artifact Reference. + ArtifactReference testReference = toArtifactReference( path ); + assertArtifactReference( testReference, groupId, artifactId, version, classifier, type ); + + // And back again, using test Reference from previous step. + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); + } + + private ArtifactReference createArtifact( String groupId, String artifactId, String version, String classifier, + String type ) + { + ArtifactReference artifact = new ArtifactReference(); + artifact.setGroupId( groupId ); + artifact.setArtifactId( artifactId ); + artifact.setVersion( version ); + artifact.setClassifier( classifier ); + artifact.setType( type ); + assertNotNull( artifact ); + return artifact; + } + + protected abstract ArtifactReference toArtifactReference( String path ) + throws LayoutException; + + protected abstract String toPath( ArtifactReference reference ); +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractLegacyRepositoryContentTestCase.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractLegacyRepositoryContentTestCase.java new file mode 100644 index 000000000..5f308fa13 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractLegacyRepositoryContentTestCase.java @@ -0,0 +1,436 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.model.ArtifactReference; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.Assert.*; + +/** + * AbstractLegacyRepositoryContentTestCase + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public abstract class AbstractLegacyRepositoryContentTestCase +{ + @Test + public void testBadPathArtifactIdMissingA() + { + assertBadPath( "groupId/jars/-1.0.jar", "artifactId is missing" ); + } + + @Test + public void testBadPathArtifactIdMissingB() + { + assertBadPath( "groupId/jars/1.0.jar", "artifactId is missing" ); + } + + @Test + public void testBadPathMissingType() + { + assertBadPath( "invalid/invalid/1/invalid-1", "missing type" ); + } + + @Test + public void testBadPathTooShort() + { + // NEW + assertBadPath( "invalid/invalid-1.0.jar", "path is too short" ); + } + + @Test + public void testBadPathWrongPackageExtension() + { + assertBadPath( "org.apache.maven.test/jars/artifactId-1.0.war", "wrong package extension" ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecGanymedSsh2() + throws LayoutException + { + String groupId = "ch.ethz.ganymed"; + String artifactId = "ganymed-ssh2"; + String version = "build210"; + String type = "jar"; + String path = "ch.ethz.ganymed/jars/ganymed-ssh2-build210.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxComm() + throws LayoutException + { + String groupId = "javax"; + String artifactId = "comm"; + String version = "3.0-u1"; + String type = "jar"; + String path = "javax/jars/comm-3.0-u1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxPersistence() + throws LayoutException + { + String groupId = "javax.persistence"; + String artifactId = "ejb"; + String version = "3.0-public_review"; + String type = "jar"; + String path = "javax.persistence/jars/ejb-3.0-public_review.jar"; + + /* + * The version id of "public_review" can cause problems. is it part of + * the version spec? or the classifier? + */ + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodCommonsLang() + throws LayoutException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String type = "jar"; + String path = "commons-lang/jars/commons-lang-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodDerby() + throws LayoutException + { + String groupId = "org.apache.derby"; + String artifactId = "derby"; + String version = "10.2.2.0"; + String type = "jar"; + String path = "org.apache.derby/jars/derby-10.2.2.0.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * Test the ejb-client type spec. + * Type specs are not a 1 to 1 map to the extension. + * This tests that effect. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + /* TODO: Re-enabled in the future. + public void testGoodFooEjbClient() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-client"; + String version = "1.0"; + String type = "ejb"; // oddball type-spec (should result in jar extension) + String path = "com.foo/ejbs/foo-client-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + */ + + /** + * Test the classifier. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibJavadoc() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String type = "javadoc"; + String classifier = "javadoc"; + String path = "com.foo.lib/javadoc.jars/foo-lib-2.1-alpha-1-javadoc.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the classifier, and java-source type spec. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibSources() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String type = "java-source"; // oddball type-spec (should result in jar extension) + String classifier = "sources"; + String path = "com.foo.lib/java-sources/foo-lib-2.1-alpha-1-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodFooTool() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-tool"; + String version = "1.0"; + String type = "jar"; + String path = "com.foo/jars/foo-tool-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodGeronimoEjbSpec() + throws LayoutException + { + String groupId = "org.apache.geronimo.specs"; + String artifactId = "geronimo-ejb_2.1_spec"; + String version = "1.0.1"; + String type = "jar"; + String path = "org.apache.geronimo.specs/jars/geronimo-ejb_2.1_spec-1.0.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodLdapClientsPom() + throws LayoutException + { + String groupId = "directory-clients"; + String artifactId = "ldap-clients"; + String version = "0.9.1-SNAPSHOT"; + String type = "pom"; + String path = "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodSnapshotMavenTest() + throws LayoutException + { + String groupId = "org.apache.archiva.test"; + String artifactId = "redonkulous"; + String version = "3.1-beta-1-20050831.101112-42"; + String type = "jar"; + String path = "org.apache.archiva.test/jars/redonkulous-3.1-beta-1-20050831.101112-42.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-519] version identifiers within filename cause misidentification of version. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodVersionKeywordInArtifactId() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String type = "pom"; + + String path = "maven/poms/maven-test-plugin-1.8.2.pom"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodDetectPluginMavenTest() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String type = "maven-one-plugin"; + String path = "maven/plugins/maven-test-plugin-1.8.2.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectPluginAvalonMeta() + throws LayoutException + { + String groupId = "avalon-meta"; + String artifactId = "avalon-meta-plugin"; + String version = "1.1"; + String type = "maven-one-plugin"; + String path = "avalon-meta/plugins/avalon-meta-plugin-1.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectPluginCactusMaven() + throws LayoutException + { + String groupId = "cactus"; + String artifactId = "cactus-maven"; + String version = "1.7dev-20040815"; + String type = "maven-one-plugin"; + String path = "cactus/plugins/cactus-maven-1.7dev-20040815.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectPluginGeronimoPackaging() + throws LayoutException + { + String groupId = "geronimo"; + String artifactId = "geronimo-packaging-plugin"; + String version = "1.0.1"; + String type = "maven-one-plugin"; + String path = "geronimo/plugins/geronimo-packaging-plugin-1.0.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-768] Artifact type "maven-plugin" does not distinguish maven1 and maven2 plugins. + * This produces conflicts when m2 plugins are stored in legacy-layout repository + */ + @Test + public void testMaven1Maven2PluginTypeDistinc() + throws Exception + { + String groupId = "com.sun.tools.xjc.maven2"; + String artifactId = "maven-jaxb-plugin"; + String version = "1.1"; + String type = "maven-plugin"; + String path = "com.sun.tools.xjc.maven2/maven-plugins/maven-jaxb-plugin-1.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * Perform a roundtrip through the layout routines to determine success. + * @param classifier TODO + */ + private void assertLayout( String path, String groupId, String artifactId, String version, String classifier, String type ) + throws LayoutException + { + ArtifactReference expectedArtifact = createArtifact( groupId, artifactId, version, classifier, type ); + + // --- Artifact Tests. + // Artifact to Path + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( expectedArtifact ) ); + + // --- Artifact Reference Tests + + // Path to Artifact Reference. + ArtifactReference testReference = toArtifactReference( path ); + assertArtifactReference( testReference, groupId, artifactId, version, classifier, type ); + + // And back again, using test Reference from previous step. + assertEquals( "Artifact <" + expectedArtifact + "> to path:", path, toPath( testReference ) ); + } + + private void assertArtifactReference( ArtifactReference actualReference, String groupId, String artifactId, + String version, String classifier, String type ) + { + String expectedId = "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + type; + + assertNotNull( expectedId + " - Should not be null.", actualReference ); + + assertEquals( expectedId + " - Group ID", groupId, actualReference.getGroupId() ); + assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); + assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); + assertEquals( expectedId + " - classifier", classifier, actualReference.getClassifier() ); + assertEquals( expectedId + " - Type", type, actualReference.getType() ); + } + + protected ArtifactReference createArtifact( String groupId, String artifactId, String version, String classifier, String type ) + { + ArtifactReference artifact = new ArtifactReference(); + artifact.setGroupId( groupId ); + artifact.setArtifactId( artifactId ); + artifact.setVersion( version ); + artifact.setClassifier( classifier ); + artifact.setType( type ); + assertNotNull( artifact ); + return artifact; + } + + private void assertBadPath( String path, String reason ) + { + try + { + toArtifactReference( path ); + fail( "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + + protected abstract ArtifactReference toArtifactReference( String path ) + throws LayoutException; + + protected abstract String toPath( ArtifactReference reference ); + +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractRepositoryLayerTestCase.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractRepositoryLayerTestCase.java new file mode 100644 index 000000000..ea1ea8450 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/AbstractRepositoryLayerTestCase.java @@ -0,0 +1,101 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.admin.model.beans.ManagedRepository; +import org.apache.archiva.admin.model.beans.RemoteRepository; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import java.io.File; + +/** + * AbstractRepositoryLayerTestCase + * + * + */ +@RunWith( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public abstract class AbstractRepositoryLayerTestCase +{ + @Rule + public TestName name = new TestName(); + + @Inject + protected ApplicationContext applicationContext; + + protected ManagedRepository createRepository( String id, String name, File location ) + { + ManagedRepository repo = new ManagedRepository(); + repo.setId( id ); + repo.setName( name ); + repo.setLocation( location.getAbsolutePath() ); + return repo; + } + + protected RemoteRepository createRemoteRepository( String id, String name, String url ) + { + RemoteRepository repo = new RemoteRepository(); + repo.setId( id ); + repo.setName( name ); + repo.setUrl( url ); + return repo; + } + + protected ManagedRepositoryContent createManagedRepositoryContent( String id, String name, File location, + String layout ) + throws Exception + { + ManagedRepository repo = new ManagedRepository(); + repo.setId( id ); + repo.setName( name ); + repo.setLocation( location.getAbsolutePath() ); + repo.setLayout( layout ); + + ManagedRepositoryContent repoContent = + applicationContext.getBean( "managedRepositoryContent#" + layout, ManagedRepositoryContent.class ); + repoContent.setRepository( repo ); + + return repoContent; + } + + protected RemoteRepositoryContent createRemoteRepositoryContent( String id, String name, String url, String layout ) + throws Exception + { + RemoteRepository repo = new RemoteRepository(); + repo.setId( id ); + repo.setName( name ); + repo.setUrl( url ); + repo.setLayout( layout ); + + RemoteRepositoryContent repoContent = + applicationContext.getBean( "remoteRepositoryContent#" + layout, RemoteRepositoryContent.class ); + repoContent.setRepository( repo ); + + return repoContent; + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/ManagedDefaultRepositoryContentTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/ManagedDefaultRepositoryContentTest.java new file mode 100644 index 000000000..2e742fbe2 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/ManagedDefaultRepositoryContentTest.java @@ -0,0 +1,247 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.admin.model.beans.ManagedRepository; +import org.apache.archiva.common.utils.VersionComparator; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.FileType; +import org.apache.archiva.configuration.FileTypes; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.ProjectReference; +import org.apache.archiva.model.VersionedReference; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * ManagedDefaultRepositoryContentTest + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class ManagedDefaultRepositoryContentTest + extends AbstractRepositoryLayerTestCase +{ + @Inject + @Named( value = "managedRepositoryContent#default" ) + private ManagedRepositoryContent repoContent; + + @Inject + FileTypes fileTypes; + + @Inject @Named(value = "archivaConfiguration#default") + ArchivaConfiguration archivaConfiguration; + + @Before + public void setUp() + throws Exception + { + File repoDir = new File( "src/test/repositories/default-repository" ); + + ManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", repoDir ); + + + FileType fileType = + (FileType) archivaConfiguration.getConfiguration().getRepositoryScanning().getFileTypes().get( 0 ); + fileType.addPattern( "**/*.xml" ); + assertEquals( FileTypes.ARTIFACTS, fileType.getId() ); + + fileTypes.afterConfigurationChange( null, "fileType", null ); + + //repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "default" ); + repoContent.setRepository( repository ); + } + + @Test + public void testGetVersionsBadArtifact() + throws Exception + { + assertGetVersions( "bad_artifact", Collections.emptyList() ); + } + + @Test + public void testGetVersionsMissingMultipleVersions() + throws Exception + { + assertGetVersions( "missing_metadata_b", Arrays.asList( "1.0", "1.0.1", "2.0", "2.0.1", "2.0-20070821-dev" ) ); + } + + @Test + public void testGetVersionsSimple() + throws Exception + { + assertVersions( "proxied_multi", "2.1", new String[]{ "2.1" } ); + } + + @Test + public void testGetVersionsSimpleYetIncomplete() + throws Exception + { + assertGetVersions( "incomplete_metadata_a", Collections.singletonList( "1.0" ) ); + } + + @Test + public void testGetVersionsSimpleYetMissing() + throws Exception + { + assertGetVersions( "missing_metadata_a", Collections.singletonList( "1.0" ) ); + } + + @Test + public void testGetVersionsSnapshotA() + throws Exception + { + assertVersions( "snap_shots_a", "1.0-alpha-11-SNAPSHOT", + new String[]{ "1.0-alpha-11-SNAPSHOT", "1.0-alpha-11-20070221.194724-2", + "1.0-alpha-11-20070302.212723-3", "1.0-alpha-11-20070303.152828-4", + "1.0-alpha-11-20070305.215149-5", "1.0-alpha-11-20070307.170909-6", + "1.0-alpha-11-20070314.211405-9", "1.0-alpha-11-20070316.175232-11" } ); + } + + @Test + public void testToMetadataPathFromProjectReference() + { + ProjectReference reference = new ProjectReference(); + reference.setGroupId( "com.foo" ); + reference.setArtifactId( "foo-tool" ); + + assertEquals( "com/foo/foo-tool/maven-metadata.xml", repoContent.toMetadataPath( reference ) ); + } + + @Test + public void testToMetadataPathFromVersionReference() + { + VersionedReference reference = new VersionedReference(); + reference.setGroupId( "com.foo" ); + reference.setArtifactId( "foo-tool" ); + reference.setVersion( "1.0" ); + + assertEquals( "com/foo/foo-tool/1.0/maven-metadata.xml", repoContent.toMetadataPath( reference ) ); + } + + @Test + public void testToPathOnNullArtifactReference() + { + try + { + ArtifactReference reference = null; + repoContent.toPath( reference ); + fail( "Should have failed due to null artifact reference." ); + } + catch ( IllegalArgumentException e ) + { + /* expected path */ + } + } + + @Test + public void testExcludeMetadataFile() + throws Exception + { + assertVersions( "include_xml", "1.0", new String[]{ "1.0" } ); + } + + private void assertGetVersions( String artifactId, List expectedVersions ) + throws Exception + { + ProjectReference reference = new ProjectReference(); + reference.setGroupId( "org.apache.archiva.metadata.tests" ); + reference.setArtifactId( artifactId ); + + // Use the test metadata-repository, which is already setup for + // These kind of version tests. + File repoDir = new File( "src/test/repositories/metadata-repository" ); + repoContent.getRepository().setLocation( repoDir.getAbsolutePath() ); + + // Request the versions. + Set testedVersionSet = repoContent.getVersions( reference ); + + // Sort the list (for asserts) + List testedVersions = new ArrayList(); + testedVersions.addAll( testedVersionSet ); + Collections.sort( testedVersions, new VersionComparator() ); + + // Test the expected array of versions, to the actual tested versions + assertEquals( "available versions", expectedVersions, testedVersions ); + } + + private void assertVersions( String artifactId, String version, String[] expectedVersions ) + throws Exception + { + VersionedReference reference = new VersionedReference(); + reference.setGroupId( "org.apache.archiva.metadata.tests" ); + reference.setArtifactId( artifactId ); + reference.setVersion( version ); + + // Use the test metadata-repository, which is already setup for + // These kind of version tests. + File repoDir = new File( "src/test/repositories/metadata-repository" ); + repoContent.getRepository().setLocation( repoDir.getAbsolutePath() ); + + // Request the versions. + Set testedVersionSet = repoContent.getVersions( reference ); + + // Sort the list (for asserts later) + List testedVersions = new ArrayList(); + testedVersions.addAll( testedVersionSet ); + Collections.sort( testedVersions, new VersionComparator() ); + + // Test the expected array of versions, to the actual tested versions + assertEquals( "Assert Versions: length/size", expectedVersions.length, testedVersions.size() ); + + for ( int i = 0; i < expectedVersions.length; i++ ) + { + String actualVersion = testedVersions.get( i ); + assertEquals( "Versions[" + i + "]", expectedVersions[i], actualVersion ); + } + } + + + @Override + protected ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + return repoContent.toArtifactReference( path ); + } + + @Override + protected String toPath( ArtifactReference reference ) + { + return repoContent.toPath( reference ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/ManagedLegacyRepositoryContentTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/ManagedLegacyRepositoryContentTest.java new file mode 100644 index 000000000..6cfc9a150 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/ManagedLegacyRepositoryContentTest.java @@ -0,0 +1,201 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.admin.model.beans.ManagedRepository; +import org.apache.archiva.common.utils.VersionComparator; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.ProjectReference; +import org.apache.archiva.model.VersionedReference; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.*; + +/** + * ManagedLegacyRepositoryContentTest + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class ManagedLegacyRepositoryContentTest + extends AbstractRepositoryLayerTestCase +{ + @Inject + @Named( value = "managedRepositoryContent#legacy" ) + private ManagedRepositoryContent repoContent; + + @Before + public void setUp() + throws Exception + { + File repoDir = new File( "src/test/repositories/legacy-repository" ); + + ManagedRepository repository = createRepository( "testRepo", "Unit Test Repo", repoDir ); + repository.setLayout( "legacy" ); + + //repoContent = (ManagedRepositoryContent) lookup( ManagedRepositoryContent.class, "legacy" ); + repoContent.setRepository( repository ); + } + + @Test + public void testGetVersionsFromProjectReference() + throws Exception + { + assertVersions( "org.apache.maven", "testing", new String[]{ "UNKNOWN", +// "1.0-javadoc", +// "1.0-sources", + "1.0", "1.0-20050611.112233-1" } ); + } + + @Test + public void testGetVersionsFromVersionedReference() + throws Exception + { + assertVersions( "org.apache.maven", "testing", "1.0", new String[]{ +// "1.0-javadoc", +// "1.0-sources", + "1.0", "1.0-20050611.112233-1" } ); + } + + private void assertVersions( String groupId, String artifactId, String[] expectedVersions ) + throws Exception + { + ProjectReference reference = new ProjectReference(); + reference.setGroupId( groupId ); + reference.setArtifactId( artifactId ); + + // Request the versions. + Set testedVersionSet = repoContent.getVersions( reference ); + + // Sort the list (for asserts later) + List testedVersions = new ArrayList(); + testedVersions.addAll( testedVersionSet ); + Collections.sort( testedVersions, new VersionComparator() ); + + // Test the expected array of versions, to the actual tested versions + assertEquals( "Assert (Project) Versions: length/size", expectedVersions.length, testedVersions.size() ); + + for ( int i = 0; i < expectedVersions.length; i++ ) + { + String actualVersion = testedVersions.get( i ); + assertEquals( "(Project) Versions[" + i + "]", expectedVersions[i], actualVersion ); + } + } + + private void assertVersions( String groupId, String artifactId, String version, String[] expectedVersions ) + throws Exception + { + VersionedReference reference = new VersionedReference(); + reference.setGroupId( groupId ); + reference.setArtifactId( artifactId ); + reference.setVersion( version ); + + // Request the versions. + Set testedVersionSet = repoContent.getVersions( reference ); + + // Sort the list (for asserts later) + List testedVersions = new ArrayList(); + testedVersions.addAll( testedVersionSet ); + Collections.sort( testedVersions, new VersionComparator() ); + + // Test the expected array of versions, to the actual tested versions + assertEquals( "Assert (Project) Versions: length/size", expectedVersions.length, testedVersions.size() ); + + for ( int i = 0; i < expectedVersions.length; i++ ) + { + String actualVersion = testedVersions.get( i ); + assertEquals( "(Project) Versions[" + i + "]", expectedVersions[i], actualVersion ); + } + } + + @Test + public void testGetRelatedArtifacts() + throws Exception + { + ArtifactReference reference = createArtifact( "org.apache.maven", "testing", "1.0", null, "jar" ); + + Set related = repoContent.getRelatedArtifacts( reference ); + assertNotNull( related ); + + String expected[] = new String[]{ "org.apache.maven/jars/testing-1.0.jar", + "org.apache.maven/java-sources/testing-1.0-sources.jar", + "org.apache.maven/jars/testing-1.0-20050611.112233-1.jar", "org.apache.maven/poms/testing-1.0.pom", + "org.apache.maven/distributions/testing-1.0.tar.gz", "org.apache.maven/distributions/testing-1.0.zip", + "org.apache.maven/javadoc.jars/testing-1.0-javadoc.jar" }; + + StringBuilder relatedDebugString = new StringBuilder(); + relatedDebugString.append( "[" ); + for ( ArtifactReference ref : related ) + { + String actualPath = repoContent.toPath( ref ); + relatedDebugString.append( actualPath ).append( ":" ); + } + relatedDebugString.append( "]" ); + + for ( String expectedPath : expected ) + { + boolean found = false; + for ( ArtifactReference actualRef : related ) + { + String actualPath = repoContent.toPath( actualRef ); + if ( actualPath.endsWith( expectedPath ) ) + { + found = true; + break; + } + } + if ( !found ) + { + fail( "Unable to find expected artifact [" + expectedPath + "] in list of related artifacts. " + + "Related <" + relatedDebugString + ">" ); + } + } + assertEquals( "Related <" + relatedDebugString + ">:", expected.length, related.size() ); + } + + + @Override + protected ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + return repoContent.toArtifactReference( path ); + } + + @Override + protected String toPath( ArtifactReference reference ) + { + return repoContent.toPath( reference ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/RemoteDefaultRepositoryContentTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/RemoteDefaultRepositoryContentTest.java new file mode 100644 index 000000000..935e3ae59 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/RemoteDefaultRepositoryContentTest.java @@ -0,0 +1,69 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.admin.model.beans.RemoteRepository; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; + +/** + * RemoteDefaultRepositoryContentTest + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class RemoteDefaultRepositoryContentTest + extends AbstractRepositoryLayerTestCase +{ + @Inject + @Named ( value = "remoteRepositoryContent#default" ) + private RemoteRepositoryContent repoContent; + + @Before + public void setUp() + throws Exception + { + RemoteRepository repository = + createRemoteRepository( "testRemoteRepo", "Unit Test Remote Repo", "http://repo1.maven.org/maven2/" ); + + //repoContent = (RemoteRepositoryContent) lookup( RemoteRepositoryContent.class, "default" ); + repoContent.setRepository( repository ); + } + + @Override + protected ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + return repoContent.toArtifactReference( path ); + } + + @Override + protected String toPath( ArtifactReference reference ) + { + return repoContent.toPath( reference ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/RemoteLegacyRepositoryContentTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/RemoteLegacyRepositoryContentTest.java new file mode 100644 index 000000000..8cd826b05 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/RemoteLegacyRepositoryContentTest.java @@ -0,0 +1,68 @@ +package org.apache.archiva.metadata.repository.storage.maven2; + +/* + * 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.admin.model.beans.RemoteRepository; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.RemoteRepositoryContent; +import org.apache.archiva.repository.layout.LayoutException; +import org.junit.Before; + +import javax.inject.Inject; +import javax.inject.Named; + +/** + * RemoteLegacyRepositoryContentTest + * + * + */ +public class RemoteLegacyRepositoryContentTest + extends AbstractLegacyRepositoryContentTestCase +{ + @Inject + @Named( value = "remoteRepositoryContent#legacy" ) + private RemoteRepositoryContent repoContent; + + @Before + public void setUp() + throws Exception + { + RemoteRepository repository = + createRemoteRepository( "testRemoteLegacyRepo", "Unit Test Remote Legacy Repo", + "http://repo1.maven.org/maven/" ); + repository.setLayout( "legacy" ); + + //repoContent = (RemoteRepositoryContent) lookup( RemoteRepositoryContent.class, "legacy" ); + repoContent.setRepository( repository ); + } + + @Override + protected ArtifactReference toArtifactReference( String path ) + throws LayoutException + { + return repoContent.toArtifactReference( path ); + } + + @Override + protected String toPath( ArtifactReference reference ) + { + return repoContent.toPath( reference ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/legacy/LegacyPathParserTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/legacy/LegacyPathParserTest.java new file mode 100644 index 000000000..4f4e3bee9 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/legacy/LegacyPathParserTest.java @@ -0,0 +1,497 @@ +package org.apache.archiva.repository.content.legacy; + +/* + * 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.configuration.ArchivaConfiguration; +import org.apache.archiva.configuration.LegacyArtifactPath; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; + +import static org.junit.Assert.*; + +/** + * LegacyPathParserTest + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class LegacyPathParserTest +{ + private LegacyPathParser parser; + + @Inject + @Named( value = "archivaConfiguration#default" ) + ArchivaConfiguration config; + + /** + * Configure the ArchivaConfiguration + * {@inheritDoc} + */ + @Before + public void setUp() + throws Exception + { + parser = new LegacyPathParser( config ); + LegacyArtifactPath jaxen = new LegacyArtifactPath(); + jaxen.setPath( "jaxen/jars/jaxen-1.0-FCS-full.jar" ); + jaxen.setArtifact( "jaxen:jaxen:1.0-FCS:full:jar" ); + config.getConfiguration().addLegacyArtifactPath( jaxen ); + parser.configuration = config; + } + + @Test + public void testBadPathArtifactIdMissingA() + { + assertBadPath( "groupId/jars/-1.0.jar", "artifactId is missing" ); + } + + @Test + public void testBadPathArtifactIdMissingB() + { + assertBadPath( "groupId/jars/1.0.jar", "artifactId is missing" ); + } + + @Test + public void testBadPathMissingType() + { + assertBadPath( "invalid/invalid/1/invalid-1", "missing type" ); + } + + @Test + public void testBadPathTooShort() + { + // NEW + assertBadPath( "invalid/invalid-1.0.jar", "path is too short" ); + } + + @Test + public void testBadPathWrongPackageExtension() + { + assertBadPath( "org.apache.maven.test/jars/artifactId-1.0.war", "wrong package extension" ); + } + + /** + * [MRM-481] Artifact requests with a .xml.zip extension fail with a 404 Error + */ + @Test + public void testGoodButDualExtensions() + throws LayoutException + { + String groupId = "org.project"; + String artifactId = "example-presentation"; + String version = "3.2.xml"; + String type = "distribution-zip"; + String path = "org.project/zips/example-presentation-3.2.xml.zip"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecGanymedSsh2() + throws LayoutException + { + String groupId = "ch.ethz.ganymed"; + String artifactId = "ganymed-ssh2"; + String version = "build210"; + String type = "jar"; + String path = "ch.ethz.ganymed/jars/ganymed-ssh2-build210.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxComm() + throws LayoutException + { + String groupId = "javax"; + String artifactId = "comm"; + String version = "3.0-u1"; + String type = "jar"; + String path = "javax/jars/comm-3.0-u1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxPersistence() + throws LayoutException + { + String groupId = "javax.persistence"; + String artifactId = "ejb"; + String version = "3.0-public_review"; + String type = "jar"; + String path = "javax.persistence/jars/ejb-3.0-public_review.jar"; + + /* + * The version id of "public_review" can cause problems. is it part of + * the version spec? or the classifier? + */ + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodCommonsLang() + throws LayoutException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String type = "jar"; + String path = "commons-lang/jars/commons-lang-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodDerby() + throws LayoutException + { + String groupId = "org.apache.derby"; + String artifactId = "derby"; + String version = "10.2.2.0"; + String type = "jar"; + String path = "org.apache.derby/jars/derby-10.2.2.0.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * Test the ejb-client type spec. + * Type specs are not a 1 to 1 map to the extension. + * This tests that effect. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + /* TODO: Re-enabled in the future. + public void testGoodFooEjbClient() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-client"; + String version = "1.0"; + String type = "ejb"; // oddball type-spec (should result in jar extension) + String path = "com.foo/ejbs/foo-client-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + */ + + /** + * Test the classifier. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibJavadoc() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String type = "javadoc"; + String classifier = "javadoc"; + String path = "com.foo.lib/javadoc.jars/foo-lib-2.1-alpha-1-javadoc.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + + assertLayout( "com.foo.lib/javadocs/foo-lib-2.1-alpha-1-javadoc.jar", "com.foo.lib", "foo-lib", "2.1-alpha-1", + "javadoc", "javadoc" ); + } + + /** + * Test the classifier, and java-source type spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibSources() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String type = "java-source"; // oddball type-spec (should result in jar extension) + String classifier = "sources"; + String path = "com.foo.lib/java-sources/foo-lib-2.1-alpha-1-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the classifier, and java-source type spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testBadClassifierFooLibSources() + throws LayoutException + { + assertBadPath( "com.foo.lib/java-sources/foo-lib-2.1-alpha-1.jar", "missing required classifier" ); + assertBadPath( "com.foo.lib/java-sources/foo-lib-2.1-alpha-1-javadoc.jar", "incorrect classifier" ); + assertBadPath( "com.foo.lib/java-sources/foo-lib-2.1-alpha-1-other.jar", "incorrect classifier" ); + } + + /** + * Test the classifier, and java-source type spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibTestSources() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1-test-sources"; + String type = "jar"; + String classifier = null; // we can't parse this type of classifier in legacy format + String path = "com.foo.lib/jars/foo-lib-2.1-alpha-1-test-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodFooTool() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-tool"; + String version = "1.0"; + String type = "jar"; + String path = "com.foo/jars/foo-tool-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodGeronimoEjbSpec() + throws LayoutException + { + String groupId = "org.apache.geronimo.specs"; + String artifactId = "geronimo-ejb_2.1_spec"; + String version = "1.0.1"; + String type = "jar"; + String path = "org.apache.geronimo.specs/jars/geronimo-ejb_2.1_spec-1.0.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + @Test + public void testGoodLdapClientsPom() + throws LayoutException + { + String groupId = "directory-clients"; + String artifactId = "ldap-clients"; + String version = "0.9.1-SNAPSHOT"; + String type = "pom"; + String path = "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodSnapshotMavenTest() + throws LayoutException + { + String groupId = "org.apache.archiva.test"; + String artifactId = "redonkulous"; + String version = "3.1-beta-1-20050831.101112-42"; + String type = "jar"; + String path = "org.apache.archiva.test/jars/redonkulous-3.1-beta-1-20050831.101112-42.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-519] version identifiers within filename cause misidentification of version. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodVersionKeywordInArtifactId() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String type = "pom"; + + String path = "maven/poms/maven-test-plugin-1.8.2.pom"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodDetectPluginMavenTest() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String type = "maven-one-plugin"; + String path = "maven/plugins/maven-test-plugin-1.8.2.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectPluginAvalonMeta() + throws LayoutException + { + String groupId = "avalon-meta"; + String artifactId = "avalon-meta-plugin"; + String version = "1.1"; + String type = "maven-one-plugin"; + String path = "avalon-meta/plugins/avalon-meta-plugin-1.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectPluginCactusMaven() + throws LayoutException + { + String groupId = "cactus"; + String artifactId = "cactus-maven"; + String version = "1.7dev-20040815"; + String type = "maven-one-plugin"; + String path = "cactus/plugins/cactus-maven-1.7dev-20040815.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectPluginGeronimoPackaging() + throws LayoutException + { + String groupId = "geronimo"; + String artifactId = "geronimo-packaging-plugin"; + String version = "1.0.1"; + String type = "maven-one-plugin"; + String path = "geronimo/plugins/geronimo-packaging-plugin-1.0.1.jar"; + + assertLayout( path, groupId, artifactId, version, null, type ); + } + + /** + * [MRM-594] add some hook in LegacyPathParser to allow exceptions in artifact resolution + * + * @since 1.1 + */ + @Test + public void testCustomExceptionsInArtifactResolution() + throws LayoutException + { + String groupId = "jaxen"; + String artifactId = "jaxen"; + String version = "1.0-FCS"; + String type = "jar"; + String classifier = "full"; + String path = "jaxen/jars/jaxen-1.0-FCS-full.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Perform a path to artifact reference lookup, and verify the results. + */ + private void assertLayout( String path, String groupId, String artifactId, String version, String classifier, + String type ) + throws LayoutException + { + // Path to Artifact Reference. + ArtifactReference testReference = parser.toArtifactReference( path ); + assertArtifactReference( testReference, groupId, artifactId, version, classifier, type ); + } + + private void assertArtifactReference( ArtifactReference actualReference, String groupId, String artifactId, + String version, String classifier, String type ) + { + String expectedId = + "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type; + + assertNotNull( expectedId + " - Should not be null.", actualReference ); + + assertEquals( expectedId + " - Group ID", groupId, actualReference.getGroupId() ); + assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); + assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); + assertEquals( expectedId + " - classifier", classifier, actualReference.getClassifier() ); + assertEquals( expectedId + " - Type", type, actualReference.getType() ); + } + + protected void assertBadPath( String path, String reason ) + { + try + { + parser.toArtifactReference( path ); + fail( + "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/ArtifactExtensionMappingTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/ArtifactExtensionMappingTest.java new file mode 100644 index 000000000..c854da048 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/ArtifactExtensionMappingTest.java @@ -0,0 +1,83 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet; +import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator; +import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMappingProvider; +import org.apache.archiva.metadata.repository.storage.maven2.Maven2RepositoryPathTranslator; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * ArtifactExtensionMappingTest + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class ArtifactExtensionMappingTest +{ + private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator( + Collections.emptyList() ); + + @Test + public void testIsMavenPlugin() + { + assertMavenPlugin( "maven-test-plugin" ); + assertMavenPlugin( "maven-clean-plugin" ); + assertMavenPlugin( "cobertura-maven-plugin" ); + assertMavenPlugin( "maven-project-info-reports-plugin" ); + assertMavenPlugin( "silly-name-for-a-maven-plugin" ); + + assertNotMavenPlugin( "maven-plugin-api" ); + assertNotMavenPlugin( "foo-lib" ); + assertNotMavenPlugin( "another-maven-plugin-api" ); + assertNotMavenPlugin( "secret-maven-plugin-2" ); + } + + private void assertMavenPlugin( String artifactId ) + { + assertEquals( "Should be detected as maven plugin: <" + artifactId + ">", "maven-plugin", getTypeFromArtifactId( + artifactId ) ); + } + + private String getTypeFromArtifactId( String artifactId ) + { + ArtifactMetadata artifact = pathTranslator.getArtifactFromId( null, "groupId", artifactId, "1.0", + artifactId + "-1.0.jar" ); + MavenArtifactFacet facet = (MavenArtifactFacet) artifact.getFacet( MavenArtifactFacet.FACET_ID ); + return facet.getType(); + } + + private void assertNotMavenPlugin( String artifactId ) + { + assertFalse( "Should NOT be detected as maven plugin: <" + artifactId + ">", "maven-plugin".equals( + getTypeFromArtifactId( artifactId ) ) ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/DefaultPathParserTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/DefaultPathParserTest.java new file mode 100644 index 000000000..b376c0b91 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/DefaultPathParserTest.java @@ -0,0 +1,572 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.model.ArtifactReference; +import org.apache.archiva.repository.content.PathParser; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.lang.StringUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.Assert.*; + +/** + * DefaultPathParserTest + * + * TODO: move to path translator tests + * + * + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } ) +public class DefaultPathParserTest +{ + private PathParser parser = new DefaultPathParser(); + + @Test + public void testBadPathMissingType() + { + // TODO: should we allow this instead? + assertBadPath( "invalid/invalid/1/invalid-1", "missing type" ); + } + + @Test + public void testBadPathReleaseInSnapshotDir() + { + assertBadPath( "invalid/invalid/1.0-SNAPSHOT/invalid-1.0.jar", + "non snapshot artifact inside of a snapshot dir" ); + } + + @Test + public void testBadPathTimestampedSnapshotNotInSnapshotDir() + { + assertBadPath( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar", + "Timestamped Snapshot artifact not inside of an Snapshot dir" ); + } + + @Test + public void testBadPathTooShort() + { + assertBadPath( "invalid/invalid-1.0.jar", "path is too short" ); + } + + @Test + public void testBadPathVersionMismatchA() + { + assertBadPath( "invalid/invalid/1.0/invalid-2.0.jar", "version mismatch between path and artifact" ); + } + + @Test + public void testBadPathVersionMismatchB() + { + assertBadPath( "invalid/invalid/1.0/invalid-1.0b.jar", "version mismatch between path and artifact" ); + } + + @Test + public void testBadPathWrongArtifactId() + { + assertBadPath( "org/apache/maven/test/1.0-SNAPSHOT/wrong-artifactId-1.0-20050611.112233-1.jar", + "wrong artifact id" ); + } + + /** + * [MRM-481] Artifact requests with a .xml.zip extension fail with a 404 Error + */ + @Test + public void testGoodButDualExtensions() + throws LayoutException + { + String groupId = "org.project"; + String artifactId = "example-presentation"; + String version = "3.2"; + String classifier = null; + String type = "xml.zip"; + String path = "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodButDualExtensionsWithClassifier() + throws LayoutException + { + String groupId = "org.project"; + String artifactId = "example-presentation"; + String version = "3.2"; + String classifier = "extras"; + String type = "xml.zip"; + String path = "org/project/example-presentation/3.2/example-presentation-3.2-extras.xml.zip"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodButDualExtensionsTarGz() + throws LayoutException + { + String groupId = "org.project"; + String artifactId = "example-distribution"; + String version = "1.3"; + String classifier = null; + String type = "tar.gz"; // no longer using distribution-tgz / distribution-zip in maven 2 + String path = "org/project/example-distribution/1.3/example-distribution-1.3.tar.gz"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodButDualExtensionsTarGzAndClassifier() + throws LayoutException + { + String groupId = "org.project"; + String artifactId = "example-distribution"; + String version = "1.3"; + String classifier = "bin"; + String type = "tar.gz"; // no longer using distribution-tgz / distribution-zip in maven 2 + String path = "org/project/example-distribution/1.3/example-distribution-1.3-bin.tar.gz"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecGanymedSsh2() + throws LayoutException + { + String groupId = "ch.ethz.ganymed"; + String artifactId = "ganymed-ssh2"; + String version = "build210"; + String classifier = null; + String type = "jar"; + String path = "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxComm() + throws LayoutException + { + String groupId = "javax"; + String artifactId = "comm"; + String version = "3.0-u1"; + String classifier = null; + String type = "jar"; + String path = "javax/comm/3.0-u1/comm-3.0-u1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the ejb-client type spec. + * Type specs are not a 1 to 1 map to the extension. + * This tests that effect. + * @throws org.apache.archiva.repository.layout.LayoutException + */ + /* TODO: Re-enabled in the future. + public void testGoodFooEjbClient() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-client"; + String version = "1.0"; + String classifier = null; + String type = "ejb-client"; // oddball type-spec (should result in jar extension) + String path = "com/foo/foo-client/1.0/foo-client-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + */ + + /** + * [MRM-432] Oddball version spec. + * Example of an oddball / unusual version spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodButOddVersionSpecJavaxPersistence() + throws LayoutException + { + String groupId = "javax.persistence"; + String artifactId = "ejb"; + String version = "3.0-public_review"; + String classifier = null; + String type = "jar"; + String path = "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar"; + + /* + * The version id of "public_review" can cause problems. is it part of + * the version spec? or the classifier? + * Since the path spec below shows it in the path, then it is really + * part of the version spec. + */ + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodComFooTool() + throws LayoutException + { + String groupId = "com.foo"; + String artifactId = "foo-tool"; + String version = "1.0"; + String classifier = null; + String type = "jar"; + String path = "com/foo/foo-tool/1.0/foo-tool-1.0.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testGoodCommonsLang() + throws LayoutException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String classifier = null; + String type = "jar"; + String path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testWindowsPathSeparator() + throws LayoutException + { + String groupId = "commons-lang"; + String artifactId = "commons-lang"; + String version = "2.1"; + String classifier = null; + String type = "jar"; + String path = "commons-lang\\commons-lang/2.1\\commons-lang-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-486] Can not deploy artifact test.maven-arch:test-arch due to "No ArtifactID Detected" + */ + @Test + public void testGoodDashedArtifactId() + throws LayoutException + { + String groupId = "test.maven-arch"; + String artifactId = "test-arch"; + String version = "2.0.3-SNAPSHOT"; + String classifier = null; + String type = "pom"; + String path = "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * It may seem odd, but this is a valid artifact. + */ + @Test + public void testGoodDotNotationArtifactId() + throws LayoutException + { + String groupId = "com.company.department"; + String artifactId = "com.company.department"; + String version = "0.2"; + String classifier = null; + String type = "pom"; + String path = "com/company/department/com.company.department/0.2/com.company.department-0.2.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * It may seem odd, but this is a valid artifact. + */ + @Test + public void testGoodDotNotationSameGroupIdAndArtifactId() + throws LayoutException + { + String groupId = "com.company.department"; + String artifactId = "com.company.department.project"; + String version = "0.3"; + String classifier = null; + String type = "pom"; + String path = + "com/company/department/com.company.department.project/0.3/com.company.department.project-0.3.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * Test the classifier, and java-source type spec. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodFooLibSources() + throws LayoutException + { + String groupId = "com.foo.lib"; + String artifactId = "foo-lib"; + String version = "2.1-alpha-1"; + String classifier = "sources"; + String type = "java-source"; // oddball type-spec (should result in jar extension) + String path = "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodSnapshotMavenTest() + throws LayoutException + { + String groupId = "org.apache.archiva.test"; + String artifactId = "redonkulous"; + String version = "3.1-beta-1-20050831.101112-42"; + String classifier = null; + String type = "jar"; + String path = + "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testGoodLongSnapshotMavenTest() + throws LayoutException + { + String groupId = "a.group.id"; + String artifactId = "artifact-id"; + String version = "1.0-abc-1.1-20080221.062205-9"; + String classifier = null; + String type = "pom"; + String path = "a/group/id/artifact-id/1.0-abc-1.1-SNAPSHOT/artifact-id-1.0-abc-1.1-20080221.062205-9.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * A timestamped versioned artifact but without release version part. Like on axiom trunk. + */ + @Test + public void testBadSnapshotWithoutReleasePart() + { + assertBadPath( "org/apache/ws/commons/axiom/axiom/SNAPSHOT/axiom-20070912.093446-2.pom", + "snapshot version without release part" ); + } + + /** + * A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory. + * + * @throws org.apache.archiva.repository.layout.LayoutException + */ + @Test + public void testClassifiedSnapshotMavenTest() + throws LayoutException + { + String groupId = "a.group.id"; + String artifactId = "artifact-id"; + String version = "1.0-20070219.171202-34"; + String classifier = "test-sources"; + String type = "jar"; + String path = "a/group/id/artifact-id/1.0-SNAPSHOT/artifact-id-1.0-20070219.171202-34-test-sources.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-519] version identifiers within filename cause misidentification of version. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodVersionKeywordInArtifactId() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String classifier = null; + String type = "pom"; + String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + * Example uses "test" in artifact Id, which is also part of the versionKeyword list. + */ + @Test + public void testGoodDetectMavenTestPlugin() + throws LayoutException + { + String groupId = "maven"; + String artifactId = "maven-test-plugin"; + String version = "1.8.2"; + String classifier = null; + String type = "maven-plugin"; + String path = "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + /** + * [MRM-562] Artifact type "maven-plugin" is not detected correctly in .toArtifactReference() methods. + */ + @Test + public void testGoodDetectCoberturaMavenPlugin() + throws LayoutException + { + String groupId = "org.codehaus.mojo"; + String artifactId = "cobertura-maven-plugin"; + String version = "2.1"; + String classifier = null; + String type = "maven-plugin"; + String path = "org/codehaus/mojo/cobertura-maven-plugin/2.1/cobertura-maven-plugin-2.1.jar"; + + assertLayout( path, groupId, artifactId, version, classifier, type ); + } + + @Test + public void testToArtifactOnEmptyPath() + { + try + { + parser.toArtifactReference( "" ); + fail( "Should have failed due to empty path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactOnNullPath() + { + try + { + parser.toArtifactReference( null ); + fail( "Should have failed due to null path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactReferenceOnEmptyPath() + { + try + { + parser.toArtifactReference( "" ); + fail( "Should have failed due to empty path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + @Test + public void testToArtifactReferenceOnNullPath() + { + try + { + parser.toArtifactReference( null ); + fail( "Should have failed due to null path." ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + /** + * Perform a path to artifact reference lookup, and verify the results. + */ + private void assertLayout( String path, String groupId, String artifactId, String version, String classifier, + String type ) + throws LayoutException + { + // Path to Artifact Reference. + ArtifactReference testReference = parser.toArtifactReference( path ); + assertArtifactReference( testReference, groupId, artifactId, version, classifier, type ); + } + + private void assertArtifactReference( ArtifactReference actualReference, String groupId, String artifactId, + String version, String classifier, String type ) + { + String expectedId = + "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type; + + assertNotNull( expectedId + " - Should not be null.", actualReference ); + + assertEquals( expectedId + " - Group ID", groupId, actualReference.getGroupId() ); + assertEquals( expectedId + " - Artifact ID", artifactId, actualReference.getArtifactId() ); + if ( StringUtils.isNotBlank( classifier ) ) + { + assertEquals( expectedId + " - Classifier", classifier, actualReference.getClassifier() ); + } + assertEquals( expectedId + " - Version ID", version, actualReference.getVersion() ); + assertEquals( expectedId + " - Type", type, actualReference.getType() ); + } + + private void assertBadPath( String path, String reason ) + { + try + { + parser.toArtifactReference( path ); + fail( + "Should have thrown a LayoutException on the invalid path [" + path + "] because of [" + reason + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/FilenameParserTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/FilenameParserTest.java new file mode 100644 index 000000000..cec3df826 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/FilenameParserTest.java @@ -0,0 +1,217 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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 junit.framework.TestCase; +import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * FilenameParserTest + * + * + */ +@RunWith( ArchivaBlockJUnit4ClassRunner.class ) +public class FilenameParserTest + extends TestCase +{ + @Test + public void testNameExtensionJar() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + } + + @Test + public void testNameExtensionTarGz() + { + FilenameParser parser = new FilenameParser( "archiva-1.0-beta-2-bin.tar.gz" ); + + assertEquals( "archiva-1.0-beta-2-bin", parser.getName() ); + assertEquals( "tar.gz", parser.getExtension() ); + } + + @Test + public void testNameExtensionTarBz2() + { + FilenameParser parser = new FilenameParser( "archiva-1.0-SNAPSHOT-src.tar.bz2" ); + + assertEquals( "archiva-1.0-SNAPSHOT-src", parser.getName() ); + assertEquals( "tar.bz2", parser.getExtension() ); + } + + @Test + public void testNameExtensionCapitolizedTarGz() + { + FilenameParser parser = new FilenameParser( "ARCHIVA-1.0-BETA-2-BIN.TAR.GZ" ); + + assertEquals( "ARCHIVA-1.0-BETA-2-BIN", parser.getName() ); + assertEquals( "TAR.GZ", parser.getExtension() ); + } + + @Test + public void testNext() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + + assertEquals( "maven", parser.next() ); + assertEquals( "test", parser.next() ); + assertEquals( "plugin", parser.next() ); + assertEquals( "1.8.3", parser.next() ); + assertNull( parser.next() ); + } + + @Test + public void testExpect() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin-1.8.3", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + + assertEquals( "maven-test-plugin", parser.expect( "maven-test-plugin" ) ); + assertEquals( "1.8.3", parser.expect( "1.8.3" ) ); + assertNull( parser.expect( "jar" ) ); + } + + @Test + public void testExpectWithRemaining() + { + FilenameParser parser = new FilenameParser( "ganymede-ssh2-build250-sources.jar" ); + + assertEquals( "ganymede-ssh2-build250-sources", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + + assertEquals( "ganymede-ssh2", parser.expect( "ganymede-ssh2" ) ); + assertEquals( "build250", parser.expect( "build250" ) ); + assertEquals( '-', parser.seperator() ); + assertEquals( "sources", parser.remaining() ); + + assertNull( parser.expect( "jar" ) ); + } + + @Test + public void testExpectWithRemainingDualExtensions() + { + FilenameParser parser = new FilenameParser( "example-presentation-3.2.xml.zip" ); + + assertEquals( "example-presentation-3.2.xml", parser.getName() ); + assertEquals( "zip", parser.getExtension() ); + + assertEquals( "example-presentation", parser.expect( "example-presentation" ) ); + assertEquals( "3.2", parser.expect( "3.2" ) ); + assertEquals( '.', parser.seperator() ); + assertEquals( "xml", parser.remaining() ); + + } + + @Test + public void testNextNonVersion() + { + FilenameParser parser = new FilenameParser( "maven-test-plugin-1.8.3.jar" ); + + assertEquals( "maven-test-plugin", parser.nextNonVersion() ); + assertEquals( "1.8.3", parser.remaining() ); + } + + @Test + public void testNextArbitraryNonVersion() + { + FilenameParser parser = new FilenameParser( "maven-jdk-1.4-plugin-1.0-20070828.123456-42.jar" ); + + assertEquals( "maven-jdk-1.4-plugin", parser.nextNonVersion() ); + assertEquals( "1.0-20070828.123456-42", parser.remaining() ); + } + + @Test + public void testNextJython() + { + FilenameParser parser = new FilenameParser( "jython-20020827-no-oro.jar" ); + + assertEquals( "jython", parser.nextNonVersion() ); + assertEquals( "20020827", parser.nextVersion() ); + assertEquals( "no-oro", parser.remaining() ); + } + + @Test + public void testLongExtension() + { + FilenameParser parser = new FilenameParser( "libfobs4jmf-0.4.1.4-20080217.211715-4.jnilib" ); + + assertEquals( "libfobs4jmf-0.4.1.4-20080217.211715-4", parser.getName() ); + assertEquals( "jnilib", parser.getExtension() ); + } + + @Test + public void testInterveningVersion() + { + FilenameParser parser = new FilenameParser( "artifact-id-1.0-abc-1.1-20080221.062205-9.pom" ); + + assertEquals( "artifact-id", parser.nextNonVersion() ); + assertEquals( "1.0-abc-1.1-20080221.062205-9", parser.expect( "1.0-abc-1.1-SNAPSHOT" ) ); + assertNull( null, parser.remaining() ); + assertEquals( "artifact-id-1.0-abc-1.1-20080221.062205-9", parser.getName() ); + assertEquals( "pom", parser.getExtension() ); + } + + @Test + public void testExpectWrongSnapshot() + { + FilenameParser parser = new FilenameParser( "artifact-id-1.0-20080221.062205-9.pom" ); + + assertEquals( "artifact-id", parser.nextNonVersion() ); + assertNull( parser.expect( "2.0-SNAPSHOT" ) ); + } + + @Test + public void testExpectWrongSnapshot2() + { + // tests parsing axiom snapshots without exceptions + FilenameParser parser = new FilenameParser( "axiom-20080221.062205-9.pom" ); + + assertEquals( "axiom", parser.nextNonVersion() ); + assertNull( parser.expect( "SNAPSHOT" ) ); + } + + @Test + public void testClassifier() + { + FilenameParser parser = new FilenameParser( "artifact-id-1.0-20070219.171202-34-test-sources.jar" ); + + assertEquals( "artifact-id", parser.nextNonVersion() ); + assertEquals( "1.0-20070219.171202-34", parser.nextVersion() ); + assertEquals( "test-sources", parser.remaining() ); + assertEquals( "artifact-id-1.0-20070219.171202-34-test-sources", parser.getName() ); + assertEquals( "jar", parser.getExtension() ); + } + + @Test + public void testNoExtension() + { + FilenameParser parser = new FilenameParser( "foo_bar" ); + assertNull( parser.getExtension() ); + } +} diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/RepositoryRequestTest.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/RepositoryRequestTest.java new file mode 100644 index 000000000..2206b9f80 --- /dev/null +++ b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/repository/content/maven2/RepositoryRequestTest.java @@ -0,0 +1,659 @@ +package org.apache.archiva.repository.content.maven2; + +/* + * 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.admin.model.beans.ManagedRepository; +import org.apache.archiva.common.utils.FileUtil; +import org.apache.archiva.configuration.ArchivaConfiguration; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.repository.ManagedRepositoryContent; +import org.apache.archiva.repository.content.legacy.LegacyPathParser; +import org.apache.archiva.repository.layout.LayoutException; +import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; +import org.apache.commons.lang.StringUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; + +import static org.junit.Assert.*; + +/** + * RepositoryRequestTest + */ +@RunWith ( ArchivaSpringJUnit4ClassRunner.class ) +@ContextConfiguration ( + locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context-repo-request-test.xml" } ) +public class RepositoryRequestTest +{ + + @Inject + protected ApplicationContext applicationContext; + + @Inject + @Named ( value = "archivaConfiguration#repo-request-test" ) + private ArchivaConfiguration archivaConfiguration; + + private RepositoryRequest repoRequest; + + @Before + public void setUp() + throws Exception + { + LegacyPathParser legacyPathParser = new LegacyPathParser( archivaConfiguration ); + repoRequest = new RepositoryRequest( legacyPathParser ); + } + + @Test + public void testInvalidRequestEmptyPath() + { + assertInvalidRequest( "" ); + } + + @Test + public void testInvalidRequestSlashOnly() + { + assertInvalidRequest( "//" ); + } + + @Test + public void testInvalidRequestNoArtifactId() + { + assertInvalidRequest( "groupId/jars/-1.0.jar" ); + } + + @Test + public void testInvalidLegacyRequestBadLocation() + { + assertInvalidRequest( "org.apache.maven.test/jars/artifactId-1.0.war" ); + } + + @Test + public void testInvalidRequestTooShort() + { + assertInvalidRequest( "org.apache.maven.test/artifactId-2.0.jar" ); + } + + @Test + public void testInvalidDefaultRequestBadLocation() + { + assertInvalidRequest( "invalid/invalid/1.0-20050611.123456-1/invalid-1.0-20050611.123456-1.jar" ); + } + + @Test + public void testValidLegacyGanymed() + throws Exception + { + assertValid( "ch.ethz.ganymed/jars/ganymed-ssh2-build210.jar", "ch.ethz.ganymed", "ganymed-ssh2", "build210", + null, "jar" ); + } + + @Test + public void testValidDefaultGanymed() + throws Exception + { + assertValid( "ch/ethz/ganymed/ganymed-ssh2/build210/ganymed-ssh2-build210.jar", "ch.ethz.ganymed", + "ganymed-ssh2", "build210", null, "jar" ); + } + + @Test + public void testValidLegacyJavaxComm() + throws Exception + { + assertValid( "javax/jars/comm-3.0-u1.jar", "javax", "comm", "3.0-u1", null, "jar" ); + } + + @Test + public void testValidDefaultJavaxComm() + throws Exception + { + assertValid( "javax/comm/3.0-u1/comm-3.0-u1.jar", "javax", "comm", "3.0-u1", null, "jar" ); + } + + @Test + public void testValidLegacyJavaxPersistence() + throws Exception + { + assertValid( "javax.persistence/jars/ejb-3.0-public_review.jar", "javax.persistence", "ejb", + "3.0-public_review", null, "jar" ); + } + + @Test + public void testValidDefaultJavaxPersistence() + throws Exception + { + assertValid( "javax/persistence/ejb/3.0-public_review/ejb-3.0-public_review.jar", "javax.persistence", "ejb", + "3.0-public_review", null, "jar" ); + } + + @Test + public void testValidLegacyMavenTestPlugin() + throws Exception + { + assertValid( "maven/jars/maven-test-plugin-1.8.2.jar", "maven", "maven-test-plugin", "1.8.2", null, "jar" ); + } + + @Test + public void testValidDefaultMavenTestPlugin() + throws Exception + { + assertValid( "maven/maven-test-plugin/1.8.2/maven-test-plugin-1.8.2.pom", "maven", "maven-test-plugin", "1.8.2", + null, "pom" ); + } + + @Test + public void testValidLegacyCommonsLangJavadoc() + throws Exception + { + assertValid( "commons-lang/javadoc.jars/commons-lang-2.1-javadoc.jar", "commons-lang", "commons-lang", "2.1", + "javadoc", "javadoc" ); + } + + @Test + public void testValidDefaultCommonsLangJavadoc() + throws Exception + { + assertValid( "commons-lang/commons-lang/2.1/commons-lang-2.1-javadoc.jar", "commons-lang", "commons-lang", + "2.1", "javadoc", "javadoc" ); + } + + @Test + public void testValidLegacyDerbyPom() + throws Exception + { + assertValid( "org.apache.derby/poms/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", null, "pom" ); + // Starting slash should not prevent detection. + assertValid( "/org.apache.derby/poms/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", null, + "pom" ); + } + + @Test + public void testValidDefaultDerbyPom() + throws Exception + { + assertValid( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.pom", "org.apache.derby", "derby", "10.2.2.0", + null, "pom" ); + } + + @Test + public void testValidLegacyGeronimoEjbSpec() + throws Exception + { + assertValid( "org.apache.geronimo.specs/jars/geronimo-ejb_2.1_spec-1.0.1.jar", "org.apache.geronimo.specs", + "geronimo-ejb_2.1_spec", "1.0.1", null, "jar" ); + } + + @Test + public void testValidDefaultGeronimoEjbSpec() + throws Exception + { + assertValid( "org/apache/geronimo/specs/geronimo-ejb_2.1_spec/1.0.1/geronimo-ejb_2.1_spec-1.0.1.jar", + "org.apache.geronimo.specs", "geronimo-ejb_2.1_spec", "1.0.1", null, "jar" ); + } + + @Test + public void testValidLegacyLdapSnapshot() + throws Exception + { + assertValid( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom", "directory-clients", "ldap-clients", + "0.9.1-SNAPSHOT", null, "pom" ); + } + + @Test + public void testValidDefaultLdapSnapshot() + throws Exception + { + assertValid( "directory-clients/ldap-clients/0.9.1-SNAPSHOT/ldap-clients-0.9.1-SNAPSHOT.pom", + "directory-clients", "ldap-clients", "0.9.1-SNAPSHOT", null, "pom" ); + } + + @Test + public void testValidLegacyTestArchSnapshot() + throws Exception + { + assertValid( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom", "test.maven-arch", "test-arch", + "2.0.3-SNAPSHOT", null, "pom" ); + } + + @Test + public void testValidDefaultTestArchSnapshot() + throws Exception + { + assertValid( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.pom", "test.maven-arch", + "test-arch", "2.0.3-SNAPSHOT", null, "pom" ); + } + + @Test + public void testValidLegacyOddDottedArtifactId() + throws Exception + { + assertValid( "com.company.department/poms/com.company.department.project-0.2.pom", "com.company.department", + "com.company.department.project", "0.2", null, "pom" ); + } + + @Test + public void testValidDefaultOddDottedArtifactId() + throws Exception + { + assertValid( "com/company/department/com.company.department.project/0.2/com.company.department.project-0.2.pom", + "com.company.department", "com.company.department.project", "0.2", null, "pom" ); + } + + @Test + public void testValidLegacyTimestampedSnapshot() + throws Exception + { + assertValid( "org.apache.archiva.test/jars/redonkulous-3.1-beta-1-20050831.101112-42.jar", + "org.apache.archiva.test", "redonkulous", "3.1-beta-1-20050831.101112-42", null, "jar" ); + } + + @Test + public void testValidDefaultTimestampedSnapshot() + throws Exception + { + assertValid( + "org/apache/archiva/test/redonkulous/3.1-beta-1-SNAPSHOT/redonkulous-3.1-beta-1-20050831.101112-42.jar", + "org.apache.archiva.test", "redonkulous", "3.1-beta-1-20050831.101112-42", null, "jar" ); + } + + @Test + public void testIsSupportFile() + { + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.sha1" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.md5" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.asc" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) ); + + assertFalse( repoRequest.isSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( + repoRequest.isSupportFile( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); + assertFalse( repoRequest.isSupportFile( "org/apache/derby/derby/maven-metadata.xml" ) ); + } + + @Test + public void testIsMetadata() + { + assertTrue( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); + assertTrue( repoRequest.isMetadata( "org/apache/derby/derby/maven-metadata.xml" ) ); + + assertFalse( repoRequest.isMetadata( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( + repoRequest.isMetadata( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + } + + @Test + public void testIsMetadataSupportFile() + { + assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ) ); + assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.md5" ) ); + + assertFalse( repoRequest.isMetadataSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( repoRequest.isMetadataSupportFile( + "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( + repoRequest.isMetadataSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( + repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) ); + } + + @Test + public void testIsDefault() + { + assertFalse( repoRequest.isDefault( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertFalse( repoRequest.isDefault( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" ) ); + assertFalse( repoRequest.isDefault( "commons-lang/jars/commons-lang-2.1-javadoc.jar" ) ); + + assertTrue( repoRequest.isDefault( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertTrue( repoRequest.isDefault( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertTrue( repoRequest.isDefault( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertTrue( repoRequest.isDefault( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertTrue( repoRequest.isDefault( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isDefault( "eclipse/jdtcore/maven-metadata.xml" ) ); + assertTrue( repoRequest.isDefault( "eclipse/jdtcore/maven-metadata.xml.sha1" ) ); + assertTrue( repoRequest.isDefault( "eclipse/jdtcore/maven-metadata.xml.md5" ) ); + + assertFalse( repoRequest.isDefault( null ) ); + assertFalse( repoRequest.isDefault( "" ) ); + assertFalse( repoRequest.isDefault( "foo" ) ); + assertFalse( repoRequest.isDefault( "some.short/path" ) ); + } + + @Test + public void testIsLegacy() + { + assertTrue( repoRequest.isLegacy( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) ); + assertTrue( repoRequest.isLegacy( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" ) ); + assertTrue( repoRequest.isLegacy( "commons-lang/jars/commons-lang-2.1-javadoc.jar" ) ); + + assertFalse( repoRequest.isLegacy( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) ); + assertFalse( repoRequest.isLegacy( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) ); + assertFalse( repoRequest.isLegacy( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) ); + assertFalse( repoRequest.isLegacy( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); + assertFalse( repoRequest.isLegacy( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); + + assertFalse( repoRequest.isLegacy( null ) ); + assertFalse( repoRequest.isLegacy( "" ) ); + assertFalse( repoRequest.isLegacy( "some.short/path" ) ); + } + + private ManagedRepositoryContent createManagedRepo( String layout ) + throws Exception + { + File repoRoot = new File( FileUtil.getBasedir() + "/target/test-repo" ); + return createManagedRepositoryContent( "test-internal", "Internal Test Repo", repoRoot, layout ); + } + + /** + * [MRM-481] Artifact requests with a .xml.zip extension fail with a 404 Error + */ + @Test + public void testToNativePathArtifactDefaultToDefaultDualExtension() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (artifact) default to default - dual extension + assertEquals( "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip", + repoRequest.toNativePath( "org/project/example-presentation/3.2/example-presentation-3.2.xml.zip", + repository ) ); + } + + /** + * [MRM-481] Artifact requests with a .xml.zip extension fail with a 404 Error + */ + @Test + public void testToNativePathArtifactLegacyToDefaultDualExtension() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // TODO: this is a good test case for maven 1 -> maven 2 link, since m2 doesn't support the distribution-zip type + + // Test (artifact) legacy to default - dual extension + // NOTE: The detection of a dual extension is flawed. + assertEquals( "org/project/example-presentation/3.2.xml/example-presentation-3.2.xml.zip", + repoRequest.toNativePath( "org.project/zips/example-presentation-3.2.xml.zip", repository ) ); + } + + @Test + public void testToNativePathMetadataDefaultToDefault() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (metadata) default to default + assertEquals( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1", + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1", + repository ) ); + } + + @Test + public void testNativePathPomLegacyToDefault() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (pom) legacy to default + assertEquals( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.pom", + repoRequest.toNativePath( "org.apache.derby/poms/derby-10.2.2.0.pom", repository ) ); + } + + @Test + public void testNativePathPomLegacyToLegacy() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "legacy" ); + + // Test (pom) legacy to default + assertEquals( "org.apache.derby/poms/derby-10.2.2.0.pom", + repoRequest.toNativePath( "org.apache.derby/poms/derby-10.2.2.0.pom", repository ) ); + } + + @Test + public void testNativePathPomLegacyToDefaultEjb() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (pom) legacy to default + String result = repoRequest.toNativePath( "mygroup/ejbs/myejb-1.0.jar", repository ); + assertEquals( "mygroup/myejb/1.0/myejb-1.0.jar", result ); + } + + @Test + public void testNativePathPomLegacyToLegacyEjb() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "legacy" ); + + // Test (pom) legacy to default + assertEquals( "mygroup/ejbs/myejb-1.0.jar", + repoRequest.toNativePath( "mygroup/ejbs/myejb-1.0.jar", repository ) ); + } + + @Test + public void testNativePathPomLegacyToLegacyStrutsModule() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "legacy" ); + + // Test (pom) legacy to default + assertEquals( "WebPortal/struts-modules/eventsDB-1.2.3.struts-module", + repoRequest.toNativePath( "WebPortal/struts-modules/eventsDB-1.2.3.struts-module", repository ) ); + } + + @Test + public void testNativePathSupportFileLegacyToDefault() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test (supportfile) legacy to default + assertEquals( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.jar.sha1", + repoRequest.toNativePath( "org.apache.derby/jars/derby-10.2.2.0.jar.sha1", repository ) ); + } + + @Test + public void testNativePathBadRequestTooShort() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( "org.apache.derby/license.txt", repository ); + fail( "Should have thrown an exception about a too short path." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathBadRequestBlank() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( "", repository ); + fail( "Should have thrown an exception about an blank request." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathBadRequestNull() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( null, repository ); + fail( "Should have thrown an exception about an null request." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathBadRequestUnknownType() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "default" ); + + // Test bad request path (too short) + try + { + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/license.txt", repository ); + fail( "Should have thrown an exception about an invalid type." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testToNativePathLegacyMetadataDefaultToLegacy() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "legacy" ); + + // Test (metadata) default to legacy + + // Special Case: This direction is not supported, should throw a LayoutException. + try + { + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml", repository ); + fail( "Should have thrown a LayoutException, can't translate a maven-metadata.xml to a legacy layout." ); + } + catch ( LayoutException e ) + { + // expected path. + } + } + + @Test + public void testNativePathPomDefaultToLegacy() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "legacy" ); + + // Test (pom) default to legacy + assertEquals( "org.apache.derby/poms/derby-10.2.2.0.pom", + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.pom", repository ) ); + } + + @Test + public void testNativePathSupportFileDefaultToLegacy() + throws Exception + { + ManagedRepositoryContent repository = createManagedRepo( "legacy" ); + + // Test (supportfile) default to legacy + assertEquals( "org.apache.derby/jars/derby-10.2.2.0.jar.sha1", + repoRequest.toNativePath( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.jar.sha1", + repository ) ); + } + + private void assertValid( String path, String groupId, String artifactId, String version, String classifier, + String type ) + throws Exception + { + String expectedId = + "ArtifactReference - " + groupId + ":" + artifactId + ":" + version + ":" + ( classifier != null ? + classifier + ":" : "" ) + type; + + ArtifactReference reference = repoRequest.toArtifactReference( path ); + + assertNotNull( expectedId + " - Should not be null.", reference ); + + assertEquals( expectedId + " - Group ID", groupId, reference.getGroupId() ); + assertEquals( expectedId + " - Artifact ID", artifactId, reference.getArtifactId() ); + if ( StringUtils.isNotBlank( classifier ) ) + { + assertEquals( expectedId + " - Classifier", classifier, reference.getClassifier() ); + } + assertEquals( expectedId + " - Version ID", version, reference.getVersion() ); + assertEquals( expectedId + " - Type", type, reference.getType() ); + } + + private void assertInvalidRequest( String path ) + { + try + { + repoRequest.toArtifactReference( path ); + fail( "Expected a LayoutException on an invalid path [" + path + "]" ); + } + catch ( LayoutException e ) + { + /* expected path */ + } + } + + protected ManagedRepositoryContent createManagedRepositoryContent( String id, String name, File location, + String layout ) + throws Exception + { + ManagedRepository repo = new ManagedRepository(); + repo.setId( id ); + repo.setName( name ); + repo.setLocation( location.getAbsolutePath() ); + repo.setLayout( layout ); + + ManagedRepositoryContent repoContent = + applicationContext.getBean( "managedRepositoryContent#" + layout, ManagedRepositoryContent.class ); + repoContent.setRepository( repo ); + + return repoContent; + } + +}