diff --git a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java index 382a6d8ee..7ac1a9e9e 100644 --- a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java +++ b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java @@ -26,7 +26,7 @@ import org.apache.maven.archiva.model.VersionedReference; /** * BidirectionalRepositoryLayout - Similar in scope to ArtifactRepositoryLayout, but does - * the both the Path to Artifact, and Artifact to Path conversions. + * the both the Path to Artifact, and Artifact to Path conversions. * * @author Joakim Erdfelt * @version $Id$ @@ -35,80 +35,90 @@ public interface BidirectionalRepositoryLayout { /** * Get the identifier for this layout. - * + * * @return the identifier for this layout. */ public String getId(); - + + /** + * Given a repository relative path, return true if the path is valid + * according to the repository layout. + */ + public boolean isValidPath( String path ); + /** * Given an ArchivaArtifact, return the relative path to the artifact. - * + * * @param artifact the artifact to use. - * @return the relative path to the artifact. + * @return the relative path to the artifact. */ public String toPath( ArchivaArtifact artifact ); - + /** * Given an ArtifactReference, return the relative path to the artifact. - * + * * @param reference the artifact reference to use. - * @return the relative path to the artifact. + * @return the relative path to the artifact. */ public String toPath( ArtifactReference reference ); - + /** * Given an {@link VersionedReference}, return the relative path to that reference. - * + * * @param reference the versioned project reference to use. - * @return the relative path to the project reference. + * @return the relative path to the project reference. */ public String toPath( VersionedReference reference ); - + /** * Given an ProjectReference, return the relative path to that reference. - * + * * @param reference the project reference to use. - * @return the relative path to the project reference. + * @return the relative path to the project reference. */ public String toPath( ProjectReference reference ); /** * Given a repository relative path to a filename, return the {@link ArchivaArtifact} object suitable for the path. - * + * * @param path the path relative to the repository base dir for the artifact. - * @return the {@link ArchivaArtifact} representing the path. (or null if path cannot be converted to + * @return the {@link ArchivaArtifact} representing the path. (or null if path cannot be converted to * an {@link ArchivaArtifact}) * @throws LayoutException if there was a problem converting the path to an artifact. */ - public ArchivaArtifact toArtifact( String path ) throws LayoutException; - + public ArchivaArtifact toArtifact( String path ) + throws LayoutException; + /** * Given a repository relative path to a filename, return the {@link ProjectReference} object suitable for the path. - * + * * @param path the path relative to the repository base dir for the artifact. - * @return the {@link ProjectReference} representing the path. (or null if path cannot be converted to + * @return the {@link ProjectReference} representing the path. (or null if path cannot be converted to * a {@link ProjectReference}) * @throws LayoutException if there was a problem converting the path to an artifact. */ - public ProjectReference toProjectReference( String path ) throws LayoutException; - + public ProjectReference toProjectReference( String path ) + throws LayoutException; + /** * Given a repository relative path to a filename, return the {@link VersionedReference} object suitable for the path. - * + * * @param path the path relative to the repository base dir for the artifact. - * @return the {@link VersionedReference} representing the path. (or null if path cannot be converted to + * @return the {@link VersionedReference} representing the path. (or null if path cannot be converted to * a {@link VersionedReference}) * @throws LayoutException if there was a problem converting the path to an artifact. */ - public VersionedReference toVersionedReference( String path ) throws LayoutException; - + public VersionedReference toVersionedReference( String path ) + throws LayoutException; + /** * Given a repository relative path to a filename, return the {@link VersionedReference} object suitable for the path. - * + * * @param path the path relative to the repository base dir for the artifact. - * @return the {@link ArtifactReference} representing the path. (or null if path cannot be converted to + * @return the {@link ArtifactReference} representing the path. (or null if path cannot be converted to * a {@link ArtifactReference}) * @throws LayoutException if there was a problem converting the path to an artifact. */ - public ArtifactReference toArtifactReference( String path ) throws LayoutException; + public ArtifactReference toArtifactReference( String path ) + throws LayoutException; } diff --git a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactory.java b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactory.java index b1e6c2fb3..e60064d09 100644 --- a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactory.java +++ b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactory.java @@ -31,14 +31,14 @@ import org.codehaus.plexus.registry.Registry; import org.codehaus.plexus.registry.RegistryListener; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; /** - * BidirectionalRepositoryLayoutFactory + * BidirectionalRepositoryLayoutFactory * * @author Joakim Erdfelt * @version $Id$ - * * @plexus.component role="org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayoutFactory" */ public class BidirectionalRepositoryLayoutFactory @@ -49,12 +49,12 @@ public class BidirectionalRepositoryLayoutFactory * @plexus.requirement role="org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout" */ private Map layouts; - + /** * @plexus.requirement */ private ArchivaConfiguration configuration; - + private Map repositoryMap = new HashMap(); public BidirectionalRepositoryLayout getLayout( String type ) @@ -62,13 +62,28 @@ public class BidirectionalRepositoryLayoutFactory { if ( !layouts.containsKey( type ) ) { - throw new LayoutException( "Layout type [" + type + "] does not exist. " + "Available types [" - + layouts.keySet() + "]" ); + throw new LayoutException( + "Layout type [" + type + "] does not exist. " + "Available types [" + layouts.keySet() + "]" ); } return (BidirectionalRepositoryLayout) layouts.get( type ); } + public BidirectionalRepositoryLayout getLayoutForPath( String path ) + throws LayoutException + { + for ( Iterator iter = layouts.values().iterator(); iter.hasNext(); ) + { + BidirectionalRepositoryLayout layout = (BidirectionalRepositoryLayout) iter.next(); + if ( layout.isValidPath( path ) ) + { + return layout; + } + } + throw new LayoutException( "No valid layout was found for path [" + path + "]" ); + } + + public BidirectionalRepositoryLayout getLayout( ArchivaArtifact artifact ) throws LayoutException { @@ -76,13 +91,13 @@ public class BidirectionalRepositoryLayoutFactory { throw new LayoutException( "Cannot determine layout using a null artifact." ); } - + String repoId = artifact.getModel().getRepositoryId(); if ( StringUtils.isBlank( repoId ) ) { throw new LayoutException( "Cannot determine layout using artifact with no repository id: " + artifact ); } - + RepositoryConfiguration repo = (RepositoryConfiguration) this.repositoryMap.get( repoId ); return getLayout( repo.getLayout() ); } @@ -99,7 +114,7 @@ public class BidirectionalRepositoryLayoutFactory { /* do nothing */ } - + private void initRepositoryMap() { synchronized ( this.repositoryMap ) diff --git a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java index 9cc6f368e..8f1c3cd96 100644 --- a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java +++ b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java @@ -32,7 +32,6 @@ import org.apache.maven.archiva.repository.content.DefaultArtifactExtensionMappi * * @author Joakim Erdfelt * @version $Id$ - * * @plexus.component role-hint="default" */ public class DefaultBidirectionalRepositoryLayout @@ -134,7 +133,8 @@ public class DefaultBidirectionalRepositoryLayout path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR ); path.append( reference.getArtifactId() ).append( PATH_SEPARATOR ); - if( reference.getVersion() != null ) { + if ( reference.getVersion() != null ) + { // add the version only if it is present path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR ); } @@ -148,8 +148,8 @@ public class DefaultBidirectionalRepositoryLayout { if ( !path.endsWith( "/maven-metadata.xml" ) ) { - throw new LayoutException( "Only paths ending in '/maven-metadata.xml' can be " - + "converted to a ProjectReference." ); + throw new LayoutException( + "Only paths ending in '/maven-metadata.xml' can be " + "converted to a ProjectReference." ); } PathReferences pathrefs = toPathReferences( path, false ); @@ -165,8 +165,8 @@ public class DefaultBidirectionalRepositoryLayout { if ( !path.endsWith( "/maven-metadata.xml" ) ) { - throw new LayoutException( "Only paths ending in '/maven-metadata.xml' can be " - + "converted to a VersionedReference." ); + throw new LayoutException( + "Only paths ending in '/maven-metadata.xml' can be " + "converted to a VersionedReference." ); } PathReferences pathrefs = toPathReferences( path, false ); @@ -211,6 +211,19 @@ public class DefaultBidirectionalRepositoryLayout return path.toString(); } + public boolean isValidPath( String path ) + { + try + { + toPathReferences( path, false ); + return true; + } + catch ( LayoutException e ) + { + return false; + } + } + private PathReferences toPathReferences( String path, boolean parseFilename ) throws LayoutException { @@ -232,8 +245,8 @@ public class DefaultBidirectionalRepositoryLayout if ( pathParts.length < 4 ) { // Illegal Path Parts Length. - throw new LayoutException( "Not enough parts to the path [" + path - + "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" ); + throw new LayoutException( "Not enough parts to the path [" + path + + "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" ); } // Maven 2.x path. @@ -246,9 +259,9 @@ public class DefaultBidirectionalRepositoryLayout // Second to last is the baseVersion (the directory version) prefs.baseVersion = pathParts[baseVersionPos]; - if ( "maven-metadata.xml".equals( pathParts[filenamePos] ) ) + if ( "maven-metadata.xml".equals( pathParts[filenamePos] ) ) { - if( !VersionUtil.isVersion( prefs.baseVersion ) ) + if ( !VersionUtil.isVersion( prefs.baseVersion ) ) { // We have a simple path without a version identifier. prefs.baseVersion = null; diff --git a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java index f32b79ea5..8fbebb565 100644 --- a/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java +++ b/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java @@ -34,7 +34,6 @@ import java.util.Map; * * @author Joakim Erdfelt * @version $Id$ - * * @plexus.component role-hint="legacy" */ public class LegacyBidirectionalRepositoryLayout @@ -63,8 +62,8 @@ public class LegacyBidirectionalRepositoryLayout public String toPath( ArchivaArtifact artifact ) { - return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), - artifact.getClassifier(), artifact.getType() ); + return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getClassifier(), + artifact.getType() ); } public String toPath( ProjectReference reference ) @@ -177,8 +176,8 @@ public class LegacyBidirectionalRepositoryLayout if ( pathParts.length != 3 ) { // Illegal Path Parts Length. - throw new LayoutException( "Invalid number of parts to the path [" + path - + "] to construct an ArchivaArtifact from. (Required to be 3 parts)" ); + throw new LayoutException( "Invalid number of parts to the path [" + path + + "] to construct an ArchivaArtifact from. (Required to be 3 parts)" ); } // The Group ID. @@ -204,9 +203,9 @@ public class LegacyBidirectionalRepositoryLayout if ( !prefs.type.equals( prefs.fileParts.extension ) ) { - throw new LayoutException( "Invalid artifact, mismatch on extension <" + prefs.fileParts.extension - + "> and expected layout specified type <" + prefs.pathType + "> (mapped type: <" + prefs.type - + ">) on path <" + path + ">" ); + throw new LayoutException( "Invalid artifact, mismatch on extension <" + prefs.fileParts.extension + + "> and expected layout specified type <" + prefs.pathType + "> (mapped type: <" + prefs.type + + ">) on path <" + path + ">" ); } } @@ -219,6 +218,19 @@ public class LegacyBidirectionalRepositoryLayout throw new LayoutException( "Cannot parse legacy paths to a Project Reference." ); } + public boolean isValidPath( String path ) + { + try + { + toPathReferences( path, false ); + return true; + } + catch ( LayoutException e ) + { + return false; + } + } + public ArchivaArtifact toArtifact( String path ) throws LayoutException { diff --git a/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactoryTest.java b/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactoryTest.java index 6a14d6788..d9adc9762 100644 --- a/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactoryTest.java +++ b/archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayoutFactoryTest.java @@ -22,7 +22,7 @@ package org.apache.maven.archiva.repository.layout; import org.apache.maven.archiva.model.ArchivaArtifact; /** - * BidirectionalRepositoryLayoutFactoryTest + * BidirectionalRepositoryLayoutFactoryTest * * @author Joakim Erdfelt * @version $Id$ @@ -74,4 +74,15 @@ public class BidirectionalRepositoryLayoutFactoryTest /* expected path */ } } + + public void testFindLayoutForPath() + throws LayoutException + { + BidirectionalRepositoryLayout layout = + factory.getLayoutForPath( "javax/servlet/servlet-api/2.3/servlet-api-2.3.jar" ); + assertEquals( "default", layout.getId() ); + + layout = factory.getLayoutForPath( "javax.servlet/jars/servlet-api-2.3.jar" ); + assertEquals( "legacy", layout.getId() ); + } } diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java index b25daef6a..1b8ecefd0 100644 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java @@ -38,12 +38,11 @@ import org.codehaus.plexus.webdav.DavServerException; import org.codehaus.plexus.webdav.servlet.DavServerRequest; import org.codehaus.plexus.webdav.util.WebdavMethodUtil; -import java.io.File; -import java.io.IOException; - import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; /** * ProxiedDavServer @@ -51,8 +50,8 @@ import javax.servlet.http.HttpServletResponse; * @author Joakim Erdfelt * @version $Id$ * @plexus.component role="org.codehaus.plexus.webdav.DavServerComponent" - * role-hint="proxied" - * instantiation-strategy="per-lookup" + * role-hint="proxied" + * instantiation-strategy="per-lookup" */ public class ProxiedDavServer extends AbstractDavServerComponent @@ -154,13 +153,25 @@ public class ProxiedDavServer ProjectReference project; VersionedReference versioned; ArtifactReference artifact; + BidirectionalRepositoryLayout resourceLayout; try { - artifact = layout.toArtifactReference( resource ); + resourceLayout = layoutFactory.getLayoutForPath( resource ); + } + catch ( LayoutException e ) + { + /* invalid request - eat it */ + return; + } + + try + { + artifact = resourceLayout.toArtifactReference( resource ); if ( artifact != null ) { connectors.fetchFromProxies( managedRepository, artifact ); + request.getRequest().setPathInfo( layout.toPath( artifact ) ); return; } } @@ -171,10 +182,11 @@ public class ProxiedDavServer try { - versioned = layout.toVersionedReference( resource ); + versioned = resourceLayout.toVersionedReference( resource ); if ( versioned != null ) { connectors.fetchFromProxies( managedRepository, versioned ); + request.getRequest().setPathInfo( layout.toPath( versioned ) ); return; } } @@ -185,10 +197,11 @@ public class ProxiedDavServer try { - project = layout.toProjectReference( resource ); + project = resourceLayout.toProjectReference( resource ); if ( project != null ) { connectors.fetchFromProxies( managedRepository, project ); + request.getRequest().setPathInfo( layout.toPath( project ) ); return; } }