--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>metadata</artifactId>
+ <groupId>org.apache.archiva</groupId>
+ <version>1.4-M4-SNAPSHOT</version>
+ </parent>
+ <artifactId>metadata-model-maven2</artifactId>
+ <packaging>bundle</packaging>
+ <name>Archiva Metadata :: Maven 2 Model</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.archiva.metadata.model</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Export-Package>
+ org.apache.archiva.metadata.model;version=${project.version};-split-package:=merge-first
+ </Export-Package>
+ <Import-Package>
+ javax.xml.bind.annotation,
+ org.apache.commons.lang
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+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<String, String> toProperties()
+ {
+ Map<String, String> properties = new HashMap<String, String>();
+ 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<String, String> 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 );
+ }
+
+}
--- /dev/null
+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<String, String> typeToDirectoryMap;
+
+ static
+ {
+ typeToDirectoryMap = new HashMap<String, String>();
+ 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;
+ }
+}
--- /dev/null
+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<LegacyArtifactPath> 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;
+ }
+}
--- /dev/null
+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<ArtifactReference> 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<ArtifactReference> foundArtifacts = new HashSet<ArtifactReference>();
+
+ // 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<String> 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<String> foundVersions = new HashSet<String>();
+
+ // 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<String> 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<String> foundVersions = new HashSet<String>();
+
+ // 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<String> versions = getVersions( reference );
+ return CollectionUtils.isNotEmpty( versions );
+ }
+ catch ( ContentNotFoundException e )
+ {
+ return false;
+ }
+ }
+
+ public boolean hasContent( VersionedReference reference )
+ {
+ try
+ {
+ Set<String> 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<String> 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<ArtifactReference> 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<String> 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 ??
+ }
+}
--- /dev/null
+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 );
+ }
+}
--- /dev/null
+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<? extends ArtifactMappingProvider> 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();
+ }
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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.<ArtifactMappingProvider>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;
+ }
+
+}
--- /dev/null
+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();
+ }
+
+
+}
--- /dev/null
+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<ArtifactReference> 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<ArtifactReference> foundArtifacts = new HashSet<ArtifactReference>();
+
+ // 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<String> 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<String> foundVersions = new HashSet<String>();
+ 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<String> 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<String> foundVersions = new HashSet<String>();
+
+ // 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<String> 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;
+ }
+}
--- /dev/null
+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 );
+ }
+}
--- /dev/null
+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.
+ * <p/>
+ * <p/>
+ * <p/>
+ */
+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." );
+ }
+ }
+
+ /**
+ * <p>
+ * Tests the path to see if it conforms to the expectations of a metadata request.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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 );
+ }
+
+ /**
+ * <p>
+ * Tests the path to see if it conforms to the expectations of a support file request.
+ * </p>
+ * <p>
+ * Tests for <code>.sha1</code>, <code>.md5</code>, <code>.asc</code>, and <code>.php</code>.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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;
+ }
+
+ /**
+ * <p>
+ * Tests the path to see if it conforms to the expectations of a default layout request.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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;
+ }
+ }
+
+ /**
+ * <p>
+ * Tests the path to see if it conforms to the expectations of a legacy layout request.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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;
+ }
+}
--- /dev/null
+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 );
+}
--- /dev/null
+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 );
+
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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.<String>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<String> 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<String> testedVersionSet = repoContent.getVersions( reference );
+
+ // Sort the list (for asserts)
+ List<String> testedVersions = new ArrayList<String>();
+ 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<String> testedVersionSet = repoContent.getVersions( reference );
+
+ // Sort the list (for asserts later)
+ List<String> testedVersions = new ArrayList<String>();
+ 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 );
+ }
+}
--- /dev/null
+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<String> testedVersionSet = repoContent.getVersions( reference );
+
+ // Sort the list (for asserts later)
+ List<String> testedVersions = new ArrayList<String>();
+ 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<String> testedVersionSet = repoContent.getVersions( reference );
+
+ // Sort the list (for asserts later)
+ List<String> testedVersions = new ArrayList<String>();
+ 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<ArtifactReference> 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 );
+ }
+}
--- /dev/null
+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 );
+ }
+}
--- /dev/null
+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 );
+ }
+}
--- /dev/null
+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 */
+ }
+ }
+}
--- /dev/null
+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.<ArtifactMappingProvider>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 ) ) );
+ }
+}
--- /dev/null
+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 */
+ }
+ }
+}
--- /dev/null
+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() );
+ }
+}
--- /dev/null
+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;
+ }
+
+}