summaryrefslogtreecommitdiffstats
path: root/archiva-repository-layer
diff options
context:
space:
mode:
authorJoakim Erdfelt <joakime@apache.org>2007-03-16 22:45:38 +0000
committerJoakim Erdfelt <joakime@apache.org>2007-03-16 22:45:38 +0000
commit3331e0fd83fc47647187c82bdff211248856f670 (patch)
tree29cea9c58332dd1a7c5e7af4192aa7c96aa28e6a /archiva-repository-layer
parentf5da04241399259534e7a02cdabc8bf3c5e7d66d (diff)
downloadarchiva-3331e0fd83fc47647187c82bdff211248856f670.tar.gz
archiva-3331e0fd83fc47647187c82bdff211248856f670.zip
More Work Against Scanner / Layout / Artifact / Database
git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/branches/archiva-jpox-database-refactor@519169 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'archiva-repository-layer')
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/ArchivaArtifact.java42
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayout.java78
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java (renamed from archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/BidirectionalRepositoryLayout.java)5
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java129
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LayoutException.java41
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java (renamed from archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyBidirectionalRepositoryLayout.java)46
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java219
-rw-r--r--archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/version/VersionUtil.java62
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java (renamed from archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/AbstractBidirectionalRepositoryLayoutTestCase.java)33
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java (renamed from archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayoutTest.java)23
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayoutTest.java (renamed from archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/LegacyBidirectionalRepositoryLayoutTest.java)44
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtilsTest.java206
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/CentralScannerTiming.java132
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/RepositoryScannerTest.java70
-rw-r--r--archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/ScanConsumer.java82
-rw-r--r--archiva-repository-layer/src/test/resources/log4j.xml40
16 files changed, 1120 insertions, 132 deletions
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/ArchivaArtifact.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/ArchivaArtifact.java
index 4aa0025b7..2456f29f3 100644
--- a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/ArchivaArtifact.java
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/ArchivaArtifact.java
@@ -21,11 +21,9 @@ package org.apache.maven.archiva.repository;
import org.apache.maven.archiva.model.ArchivaArtifactModel;
import org.apache.maven.archiva.model.RepositoryContent;
+import org.apache.maven.archiva.repository.version.VersionUtil;
import org.codehaus.plexus.util.StringUtils;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* ArchivaArtifact - Mutable artifact object.
*
@@ -34,16 +32,17 @@ import java.util.regex.Pattern;
*/
public class ArchivaArtifact
{
- private static final String SNAPSHOT_VERSION = "SNAPSHOT";
-
- private static final Pattern VERSION_FILE_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}\\.[0-9]{6})-([0-9]+)$" );
-
private ArchivaArtifactModel model;
-
+
private String baseVersion;
-
+
private boolean snapshot = false;
-
+
+ public ArchivaArtifact( String groupId, String artifactId, String version, String classifier, String type )
+ {
+ this( null, groupId, artifactId, version, classifier, type );
+ }
+
public ArchivaArtifact( ArchivaRepository repository, String groupId, String artifactId, String version,
String classifier, String type )
{
@@ -69,22 +68,19 @@ public class ArchivaArtifact
model = new ArchivaArtifactModel();
- model.setContentKey( new RepositoryContent( repository.getModel(), groupId, artifactId, version ) );
- model.setClassifier( StringUtils.defaultString( classifier ) );
- model.setType( type );
-
- // Determine Snapshot Base Version.
- Matcher m = VERSION_FILE_PATTERN.matcher( version );
- if ( m.matches() )
+ if( repository == null )
{
- this.baseVersion = m.group( 1 ) + "-" + SNAPSHOT_VERSION ;
- snapshot = true;
+ model.setContentKey( new RepositoryContent( groupId, artifactId, version ) );
}
else
{
- this.baseVersion = version;
- snapshot = version.endsWith( SNAPSHOT_VERSION );
+ model.setContentKey( new RepositoryContent( repository.getModel(), groupId, artifactId, version ) );
}
+ model.setClassifier( StringUtils.defaultString( classifier ) );
+ model.setType( type );
+
+ this.snapshot = VersionUtil.isSnapshot( version );
+ this.baseVersion = VersionUtil.getBaseVersion( version );
}
public String getGroupId()
@@ -106,12 +102,12 @@ public class ArchivaArtifact
{
return baseVersion;
}
-
+
public boolean isSnapshot()
{
return snapshot;
}
-
+
public String getClassifier()
{
return model.getClassifier();
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayout.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayout.java
deleted file mode 100644
index a199c1eef..000000000
--- a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayout.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.apache.maven.archiva.repository.content;
-
-/*
- * 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.maven.archiva.repository.ArchivaArtifact;
-
-/**
- * DefaultBidirectionalRepositoryLayout - the layout mechanism for use by Maven 2.x repositories.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- *
- * @plexus.component role="org.apache.maven.archiva.repository.content.BidirectionalRepositoryLayout"
- * role-hint="default"
- */
-public class DefaultBidirectionalRepositoryLayout implements BidirectionalRepositoryLayout
-{
- private static final char PATH_SEPARATOR = '/';
-
- private static final char GROUP_SEPARATOR = '.';
-
- private static final char ARTIFACT_SEPARATOR = '-';
-
- private ArtifactExtensionMapping extensionMapper = new DefaultArtifactExtensionMapping();
-
- public String getId()
- {
- return "default";
- }
-
- public String pathOf( ArchivaArtifact artifact )
- {
- StringBuffer path = new StringBuffer();
-
- path.append( formatAsDirectory( artifact.getGroupId() ) ).append( PATH_SEPARATOR );
- path.append( artifact.getArtifactId() ).append( PATH_SEPARATOR );
- path.append( artifact.getBaseVersion() ).append( PATH_SEPARATOR );
- path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
-
- if ( artifact.hasClassifier() )
- {
- path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
- }
-
- path.append( GROUP_SEPARATOR ).append( extensionMapper.getExtension( artifact ) );
-
- return path.toString();
- }
-
- private String formatAsDirectory( String directory )
- {
- return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
- }
-
- public ArchivaArtifact toArtifact( String path )
- {
-
-
- return null;
- }
-}
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/BidirectionalRepositoryLayout.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java
index 4e46722f1..29770dffc 100644
--- a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/BidirectionalRepositoryLayout.java
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/BidirectionalRepositoryLayout.java
@@ -1,4 +1,4 @@
-package org.apache.maven.archiva.repository.content;
+package org.apache.maven.archiva.repository.layout;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -50,6 +50,7 @@ public interface BidirectionalRepositoryLayout
*
* @param path the path relative to the repository base dir for the artifact.
* @return the ArchivaArtifact representing the path. (or null if path cannot be converted to an ArchivaArtifact)
+ * @throws LayoutException if there was a problem converting the path to an artifact.
*/
- ArchivaArtifact toArtifact( String path );
+ public ArchivaArtifact toArtifact( String path ) throws LayoutException;
}
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java
new file mode 100644
index 000000000..35406aa07
--- /dev/null
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayout.java
@@ -0,0 +1,129 @@
+package org.apache.maven.archiva.repository.layout;
+
+/*
+ * 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.commons.lang.StringUtils;
+import org.apache.maven.archiva.repository.ArchivaArtifact;
+import org.apache.maven.archiva.repository.content.ArtifactExtensionMapping;
+import org.apache.maven.archiva.repository.content.DefaultArtifactExtensionMapping;
+
+/**
+ * DefaultBidirectionalRepositoryLayout - the layout mechanism for use by Maven 2.x repositories.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role-hint="default"
+ */
+public class DefaultBidirectionalRepositoryLayout
+ implements BidirectionalRepositoryLayout
+{
+ private static final char PATH_SEPARATOR = '/';
+
+ private static final char GROUP_SEPARATOR = '.';
+
+ private static final char ARTIFACT_SEPARATOR = '-';
+
+ private ArtifactExtensionMapping extensionMapper = new DefaultArtifactExtensionMapping();
+
+ public String getId()
+ {
+ return "default";
+ }
+
+ public String pathOf( ArchivaArtifact artifact )
+ {
+ StringBuffer path = new StringBuffer();
+
+ path.append( formatAsDirectory( artifact.getGroupId() ) ).append( PATH_SEPARATOR );
+ path.append( artifact.getArtifactId() ).append( PATH_SEPARATOR );
+ path.append( artifact.getBaseVersion() ).append( PATH_SEPARATOR );
+ path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
+
+ if ( artifact.hasClassifier() )
+ {
+ path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
+ }
+
+ path.append( GROUP_SEPARATOR ).append( extensionMapper.getExtension( artifact ) );
+
+ return path.toString();
+ }
+
+ private String formatAsDirectory( String directory )
+ {
+ return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
+ }
+
+ public ArchivaArtifact toArtifact( String path ) throws LayoutException
+ {
+ String normalizedPath = StringUtils.replace( path, "\\", "/" );
+
+ String pathParts[] = StringUtils.split( normalizedPath, '/' );
+
+ /* Minimum parts.
+ *
+ * path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"
+ * path[0] = "commons-lang"; // The Group ID
+ * path[1] = "commons-lang"; // The Artifact ID
+ * path[2] = "2.1"; // The Version
+ * path[3] = "commons-lang-2.1.jar" // The filename.
+ */
+
+ 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)" );
+ }
+
+ // Maven 2.x path.
+ int partCount = pathParts.length;
+
+ // Last part is the filename
+ String filename = pathParts[partCount - 1];
+
+ // Second to last is the baseVersion (the directory version)
+ // (Don't need it) String baseVersion = pathParts[partCount - 2];
+
+ // Third to last is the artifact Id.
+ String artifactId = pathParts[partCount - 3];
+
+ // Remaining pieces are the groupId.
+ String groupId = "";
+ for ( int i = 0; i <= partCount - 4; i++ )
+ {
+ if ( groupId.length() > 0 )
+ {
+ groupId += ".";
+ }
+ groupId += pathParts[i];
+ }
+
+ // Now we need to parse the filename to get the artifact version Id.
+ String fileParts[] = RepositoryLayoutUtils.splitFilename( filename, artifactId );
+ String version = fileParts[1];
+ String classifier = fileParts[2];
+
+ String type = extensionMapper.getType( filename );
+
+ return new ArchivaArtifact( groupId, artifactId, version, classifier, type );
+ }
+}
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LayoutException.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LayoutException.java
new file mode 100644
index 000000000..0fc833689
--- /dev/null
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LayoutException.java
@@ -0,0 +1,41 @@
+package org.apache.maven.archiva.repository.layout;
+
+/*
+ * 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.maven.archiva.common.ArchivaException;
+
+/**
+ * LayoutException
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class LayoutException extends ArchivaException
+{
+ public LayoutException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public LayoutException( String message )
+ {
+ super( message );
+ }
+}
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyBidirectionalRepositoryLayout.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java
index a739c9b96..0344a5245 100644
--- a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/LegacyBidirectionalRepositoryLayout.java
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayout.java
@@ -1,4 +1,4 @@
-package org.apache.maven.archiva.repository.content;
+package org.apache.maven.archiva.repository.layout;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,7 +19,10 @@ package org.apache.maven.archiva.repository.content;
* under the License.
*/
+import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.repository.ArchivaArtifact;
+import org.apache.maven.archiva.repository.content.ArtifactExtensionMapping;
+import org.apache.maven.archiva.repository.content.LegacyArtifactExtensionMapping;
import java.util.HashMap;
import java.util.Map;
@@ -30,8 +33,7 @@ import java.util.Map;
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
- * @plexus.component role="org.apache.maven.archiva.repository.content.BidirectionalRepositoryLayout"
- * role-hint="legacy"
+ * @plexus.component role-hint="legacy"
*/
public class LegacyBidirectionalRepositoryLayout implements BidirectionalRepositoryLayout
{
@@ -92,10 +94,42 @@ public class LegacyBidirectionalRepositoryLayout implements BidirectionalReposit
return artifact.getType() + "s";
}
- public ArchivaArtifact toArtifact( String path )
+ public ArchivaArtifact toArtifact( String path ) throws LayoutException
{
- // TODO Auto-generated method stub
- return null;
+ 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 number of parts to the path [" + path
+ + "] to construct an ArchivaArtifact from. (Required to be 3 parts)" );
+ }
+
+ // The Group ID.
+ String groupId = pathParts[0];
+
+ // The Filename.
+ String filename = pathParts[2];
+
+ String fileParts[] = RepositoryLayoutUtils.splitFilename( filename, null );
+
+ String artifactId = fileParts[0];
+ String version = fileParts[1];
+ String classifier = fileParts[2];
+
+ String type = extensionMapper.getType( filename );
+
+ return new ArchivaArtifact( groupId, artifactId, version, classifier, type );
}
}
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java
new file mode 100644
index 000000000..8e2c144c9
--- /dev/null
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtils.java
@@ -0,0 +1,219 @@
+package org.apache.maven.archiva.repository.layout;
+
+/*
+ * 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.commons.lang.StringUtils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * RepositoryLayoutUtils - utility methods common for most BidirectionalRepositoryLayout implementation.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class RepositoryLayoutUtils
+{
+ /**
+ * Complex 2+ part extensions.
+ * Do not include initial "." character in extension names here.
+ */
+ private static final String ComplexExtensions[] = new String[] { "tar.gz", "tar.bz2" };
+
+ /**
+ * These are the version patterns found in the filenames of the various artifact's versions IDs.
+ * These patterns are all tackling lowercase version IDs.
+ */
+ private static final String VersionPatterns[] =
+ new String[] { "(snapshot)", "([0-9][_.0-9a-z]*)", "(g?[_.0-9ab]*(pre|rc|g|m)[_.0-9]*)", "(dev[_.0-9]*)",
+ "(alpha[_.0-9]*)", "(beta[_.0-9]*)", "(rc[_.0-9]*)", "(test[_.0-9]*)", "(debug[_.0-9]*)",
+ "(unofficial[_.0-9]*)", "(current)", "(latest)", "(fcs)", "(release[_.0-9]*)", "(nightly)", "(final)",
+ "(incubating)", "(incubator)", "([ab][_.0-9]*)" };
+
+ private static final String VersionMegaPattern = StringUtils.join( VersionPatterns, '|' );
+
+ /**
+ * Filename Parsing Mode - Artifact Id.
+ */
+ private static final int ARTIFACTID = 1;
+
+ /**
+ * Filename Parsing Mode - Version.
+ */
+ private static final int VERSION = 2;
+
+ /**
+ * Filename Parsing Mode - Classifier.
+ */
+ private static final int CLASSIFIER = 3;
+
+ /**
+ * Split the provided filename into 4 String parts.
+ *
+ * <pre>
+ * String part[] = splitFilename( filename );
+ * artifactId = part[0];
+ * version = part[1];
+ * classifier = part[2];
+ * extension = part[3];
+ * </pre>
+ *
+ * @param filename the filename to split.
+ * @param possibleArtifactId the optional artifactId to aide in splitting the filename.
+ * (null to allow algorithm to calculate one)
+ * @return the parts of the filename.
+ * @throws LayoutException
+ */
+ public static String[] splitFilename( String filename, String possibleArtifactId ) throws LayoutException
+ {
+ if ( StringUtils.isBlank( filename ) )
+ {
+ throw new IllegalArgumentException( "Unable to split blank filename." );
+ }
+
+ String filestring = filename.trim();
+
+ String artifactId = "";
+ String version = "";
+ String classifier = "";
+ String extension = "";
+
+ // I like working backwards.
+
+ // Find the extension.
+
+ // Work on multipart extensions first.
+ boolean found = false;
+
+ String lowercaseFilename = filestring.toLowerCase();
+ for ( int i = 0; i < ComplexExtensions.length && !found; i++ )
+ {
+ if ( lowercaseFilename.endsWith( "." + ComplexExtensions[i] ) )
+ {
+ extension = ComplexExtensions[i];
+ filestring = filestring.substring( 0, filestring.length() - ComplexExtensions[i].length() - 1 );
+ found = true;
+ }
+ }
+
+ if ( !found )
+ {
+ // Default to 1 part extension.
+
+ int index = filestring.lastIndexOf( '.' );
+ if ( index <= 0 )
+ {
+ // Bad Filename - No Extension
+ throw new LayoutException( "Unable to determine extension from filename " + filename );
+ }
+ extension = filestring.substring( index + 1 );
+ filestring = filestring.substring( 0, index );
+ }
+
+ // Work on version string.
+
+ if ( ( possibleArtifactId != null ) && filename.startsWith( possibleArtifactId ) )
+ {
+ artifactId = possibleArtifactId;
+ filestring = filestring.substring( possibleArtifactId.length() + 1 );
+ }
+
+ String fileParts[] = StringUtils.split( filestring, '-' );
+
+ int versionStart = -1;
+ int versionEnd = -1;
+
+ Pattern pat = Pattern.compile( VersionMegaPattern, Pattern.CASE_INSENSITIVE );
+ Matcher mat;
+
+ for ( int i = 0; i < fileParts.length; i++ )
+ {
+ String part = fileParts[i];
+ mat = pat.matcher( part );
+
+ if ( mat.matches() )
+ {
+ // It is a potential verion part.
+ if ( versionStart < 0 )
+ {
+ versionStart = i;
+ }
+
+ versionEnd = i;
+ }
+ }
+
+ if ( versionStart < 0 )
+ {
+ throw new LayoutException( "Unable to determine version from filename " + filename );
+ }
+
+ // Gather up the ArtifactID - Version - Classifier pieces found.
+
+ int mode = ARTIFACTID;
+ for ( int i = 0; i < fileParts.length; i++ )
+ {
+ String part = fileParts[i];
+
+ if ( ( mode == ARTIFACTID ) && ( i >= versionStart ) )
+ {
+ if ( StringUtils.isBlank( artifactId ) )
+ {
+ throw new LayoutException( "No Artifact Id detected." );
+ }
+ mode = VERSION;
+ }
+
+ switch ( mode )
+ {
+ case ARTIFACTID:
+ if ( artifactId.length() > 0 )
+ {
+ artifactId += "-";
+ }
+ artifactId += part;
+ break;
+ case VERSION:
+ if ( version.length() > 0 )
+ {
+ version += "-";
+ }
+ version += part;
+ break;
+ case CLASSIFIER:
+ if ( classifier.length() > 0 )
+ {
+ classifier += "-";
+ }
+ classifier += part;
+ break;
+ }
+
+ if ( i >= versionEnd )
+ {
+ mode = CLASSIFIER;
+ }
+ }
+
+ return new String[] { artifactId, version, classifier, extension };
+ }
+
+}
diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/version/VersionUtil.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/version/VersionUtil.java
new file mode 100644
index 000000000..c8ce3716f
--- /dev/null
+++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/version/VersionUtil.java
@@ -0,0 +1,62 @@
+package org.apache.maven.archiva.repository.version;
+
+/*
+ * 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 java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * VersionConstants
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class VersionUtil
+{
+ public static final String SNAPSHOT = "SNAPSHOT";
+
+ public static final Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}\\.[0-9]{6})-([0-9]+)$" );
+
+ public static boolean isSnapshot( String version )
+ {
+ Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
+ if ( m.matches() )
+ {
+ return true;
+ }
+ else
+ {
+ return version.endsWith( SNAPSHOT );
+ }
+ }
+
+ public static String getBaseVersion( String version )
+ {
+ Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
+ if ( m.matches() )
+ {
+ return m.group( 1 ) + "-" + SNAPSHOT;
+ }
+ else
+ {
+ return version;
+ }
+ }
+}
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/AbstractBidirectionalRepositoryLayoutTestCase.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java
index c2eca44af..b15685a3b 100644
--- a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/AbstractBidirectionalRepositoryLayoutTestCase.java
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/AbstractBidirectionalRepositoryLayoutTestCase.java
@@ -1,4 +1,4 @@
-package org.apache.maven.archiva.repository.content;
+package org.apache.maven.archiva.repository.layout;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -39,38 +39,42 @@ public class AbstractBidirectionalRepositoryLayoutTestCase extends PlexusTestCas
protected void setUp() throws Exception
{
super.setUp();
-
+
repository = createTestRepository();
}
-
+
protected ArchivaRepository createTestRepository()
{
File targetDir = new File( getBasedir(), "target" );
File testRepo = new File( targetDir, "test-repo" );
-
+
if ( !testRepo.exists() )
{
testRepo.mkdirs();
}
-
- String repoUri = "file://" + StringUtils.replace( testRepo.getAbsolutePath(), "\\", "/" ) ;
-
+
+ String repoUri = "file://" + StringUtils.replace( testRepo.getAbsolutePath(), "\\", "/" );
+
ArchivaRepository repo = new ArchivaRepository( "testRepo", "Test Repository", repoUri );
-
+
return repo;
}
- protected ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String classifier, String type )
+ protected ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String classifier,
+ String type )
{
ArchivaArtifact artifact = new ArchivaArtifact( repository, groupId, artifactId, version, classifier, type );
assertNotNull( artifact );
return artifact;
}
- protected void assertArtifact( ArchivaArtifact actualArtifact, String groupId, String artifactId, String version, String classifier, String type )
+ protected void assertArtifact( ArchivaArtifact actualArtifact, String groupId, String artifactId, String version,
+ String classifier, String type )
{
String expectedId = groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type;
-
+
+ assertNotNull( expectedId + " - Should not be null.", actualArtifact );
+
assertEquals( expectedId + " - Group ID", actualArtifact.getGroupId(), groupId );
assertEquals( expectedId + " - Artifact ID", actualArtifact.getArtifactId(), artifactId );
assertEquals( expectedId + " - Version ID", actualArtifact.getVersion(), version );
@@ -78,10 +82,13 @@ public class AbstractBidirectionalRepositoryLayoutTestCase extends PlexusTestCas
assertEquals( expectedId + " - Type", actualArtifact.getType(), type );
}
- protected void assertSnapshotArtifact( ArchivaArtifact actualArtifact, String groupId, String artifactId, String version, String classifier, String type )
+ protected void assertSnapshotArtifact( ArchivaArtifact actualArtifact, String groupId, String artifactId,
+ String version, String classifier, String type )
{
String expectedId = groupId + ":" + artifactId + ":" + version + ":" + classifier + ":" + type;
-
+
+ assertNotNull( expectedId + " - Should not be null.", actualArtifact );
+
assertEquals( expectedId + " - Group ID", actualArtifact.getGroupId(), groupId );
assertEquals( expectedId + " - Artifact ID", actualArtifact.getArtifactId(), artifactId );
assertEquals( expectedId + " - Version ID", actualArtifact.getVersion(), version );
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayoutTest.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java
index a2e186fff..249104a7f 100644
--- a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/DefaultBidirectionalRepositoryLayoutTest.java
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/DefaultBidirectionalRepositoryLayoutTest.java
@@ -1,4 +1,4 @@
-package org.apache.maven.archiva.repository.content;
+package org.apache.maven.archiva.repository.layout;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,6 +20,8 @@ package org.apache.maven.archiva.repository.content;
*/
import org.apache.maven.archiva.repository.ArchivaArtifact;
+import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
+import org.apache.maven.archiva.repository.layout.LayoutException;
/**
* DefaultBidirectionalRepositoryLayoutTest
@@ -54,7 +56,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
public void testToPathWithClassifier()
{
- ArchivaArtifact artifact = createArtifact( "com.foo.lib", "foo-lib", "2.1-alpha-1", "sources", "jar" );
+ ArchivaArtifact artifact = createArtifact( "com.foo.lib", "foo-lib", "2.1-alpha-1", "sources", "java-source" );
assertEquals( "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar", layout.pathOf( artifact ) );
}
@@ -66,28 +68,35 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
assertEquals( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar",
layout.pathOf( artifact ) );
}
+
+ public void testToArtifactBasicSimpleGroupId() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "commons-lang/commons-lang/2.1/commons-lang-2.1.jar" );
+ assertArtifact( artifact, "commons-lang", "commons-lang", "2.1", "", "jar" );
+ }
- public void testToArtifactBasic()
+ public void testToArtifactBasicLongGroupId() throws LayoutException
{
ArchivaArtifact artifact = layout.toArtifact( "com/foo/foo-tool/1.0/foo-tool-1.0.jar" );
assertArtifact( artifact, "com.foo", "foo-tool", "1.0", "", "jar" );
}
- public void testToArtifactEjbClient()
+ public void testToArtifactEjbClient() throws LayoutException
{
ArchivaArtifact artifact = layout.toArtifact( "com/foo/foo-client/1.0/foo-client-1.0.jar" );
// The type is correct. as we cannot possibly know this is an ejb client without parsing the pom
assertArtifact( artifact, "com.foo", "foo-client", "1.0", "", "jar" );
}
- public void testToArtifactWithClassifier()
+ public void testToArtifactWithClassifier() throws LayoutException
{
ArchivaArtifact artifact =
layout.toArtifact( "com/foo/lib/foo-lib/2.1-alpha-1/foo-lib-2.1-alpha-1-sources.jar" );
- assertArtifact( artifact, "com.foo.lib", "foo-lib", "2.1-alpha-1", "sources", "jar" );
+ // The 'java-source' type is correct. You might be thinking of extension, which we are not testing here.
+ assertArtifact( artifact, "com.foo.lib", "foo-lib", "2.1-alpha-1", "sources", "java-source" );
}
- public void testToArtifactUsingUniqueSnapshot()
+ public void testToArtifactUsingUniqueSnapshot() throws LayoutException
{
ArchivaArtifact artifact =
layout.toArtifact( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar" );
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/LegacyBidirectionalRepositoryLayoutTest.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayoutTest.java
index af61e1e34..c90f3b56f 100644
--- a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/content/LegacyBidirectionalRepositoryLayoutTest.java
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/LegacyBidirectionalRepositoryLayoutTest.java
@@ -1,4 +1,4 @@
-package org.apache.maven.archiva.repository.content;
+package org.apache.maven.archiva.repository.layout;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,6 +20,7 @@ package org.apache.maven.archiva.repository.content;
*/
import org.apache.maven.archiva.repository.ArchivaArtifact;
+import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
/**
* LegacyBidirectionalRepositoryLayoutTest
@@ -63,7 +64,44 @@ public class LegacyBidirectionalRepositoryLayoutTest extends AbstractBidirection
{
ArchivaArtifact artifact = createArtifact( "com.foo", "foo-connector", "2.1-20060822.123456-35", "", "jar" );
- assertEquals( "com.foo/jars/foo-connector-2.1-20060822.123456-35.jar",
- layout.pathOf( artifact ) );
+ assertEquals( "com.foo/jars/foo-connector-2.1-20060822.123456-35.jar", layout.pathOf( artifact ) );
+ }
+
+ public void testToArtifactBasicSimpleGroupId() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "commons-lang/jars/commons-lang-2.1.jar" );
+ assertArtifact( artifact, "commons-lang", "commons-lang", "2.1", "", "jar" );
+ }
+
+ public void testToArtifactBasicLongGroupId() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "org.apache.derby/jars/derby-10.2.2.0.jar" );
+ assertArtifact( artifact, "org.apache.derby", "derby", "10.2.2.0", "", "jar" );
+ }
+
+ public void testToArtifactLongGroupId() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "org.apache.geronimo.specs/jars/geronimo-ejb_2.1_spec-1.0.1.jar" );
+ assertArtifact( artifact, "org.apache.geronimo.specs", "geronimo-ejb_2.1_spec", "1.0.1", "", "jar" );
+ }
+
+ public void testToArtifactEjbClient() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "org.apache.beehive/jars/beehive-ejb-control-1.0.1.jar" );
+ // The type is correct. as we cannot possibly know this is an ejb client without parsing the pom
+ assertArtifact( artifact, "org.apache.beehive", "beehive-ejb-control", "1.0.1", "", "jar" );
+ }
+
+ public void testToArtifactWithClassifier() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "commons-lang/jars/commons-lang-2.3-sources.jar" );
+ // The 'java-source' type is correct. You might be thinking of extension, which we are not testing here.
+ assertArtifact( artifact, "commons-lang", "commons-lang", "2.3", "sources", "java-source" );
+ }
+
+ public void testToArtifactSnapshot() throws LayoutException
+ {
+ ArchivaArtifact artifact = layout.toArtifact( "directory-clients/poms/ldap-clients-0.9.1-SNAPSHOT.pom" );
+ assertSnapshotArtifact( artifact, "directory-clients", "ldap-clients", "0.9.1-SNAPSHOT", "", "pom" );
}
}
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtilsTest.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtilsTest.java
new file mode 100644
index 000000000..5a4e7049e
--- /dev/null
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/layout/RepositoryLayoutUtilsTest.java
@@ -0,0 +1,206 @@
+package org.apache.maven.archiva.repository.layout;
+
+/*
+ * 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;
+
+/**
+ * RepositoryLayoutUtilsTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class RepositoryLayoutUtilsTest extends TestCase
+{
+ public void testSplitFilenameBasic() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-2.1.jar", "commons-lang" ), "commons-lang",
+ "2.1", "", "jar" );
+ }
+
+ public void testSplitFilenameAlphaVersion() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-2.0-alpha-1.jar", "commons-lang" ),
+ "commons-lang", "2.0-alpha-1", "", "jar" );
+ }
+
+ public void testSplitFilenameSnapshot() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "foo-2.0-SNAPSHOT.jar", "foo" ), "foo", "2.0-SNAPSHOT", "",
+ "jar" );
+ }
+
+ public void testSplitFilenameUniqueSnapshot() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "fletch-2.0-20060822-123456-35.tar.gz", "fletch" ), "fletch",
+ "2.0-20060822-123456-35", "", "tar.gz" );
+ }
+
+ public void testSplitFilenameBasicClassifier() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-2.1-sources.jar", "commons-lang" ),
+ "commons-lang", "2.1", "sources", "jar" );
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-2.1-javadoc.jar", "commons-lang" ),
+ "commons-lang", "2.1", "javadoc", "jar" );
+ }
+
+ public void testSplitFilenameAlphaClassifier() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-2.0-alpha-1-sources.jar", "commons-lang" ),
+ "commons-lang", "2.0-alpha-1", "sources", "jar" );
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-2.0-alpha-1-javadoc.jar", "commons-lang" ),
+ "commons-lang", "2.0-alpha-1", "javadoc", "jar" );
+ }
+
+ public void testSplitFilenameSnapshotClassifier() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-3.1-SNAPSHOT-sources.jar", "commons-lang" ),
+ "commons-lang", "3.1-SNAPSHOT", "sources", "jar" );
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-3.1-SNAPSHOT-javadoc.jar", "commons-lang" ),
+ "commons-lang", "3.1-SNAPSHOT", "javadoc", "jar" );
+ }
+
+ public void testSplitFilenameUniqueSnapshotClassifier() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-3.1-SNAPSHOT-sources.jar", "commons-lang" ),
+ "commons-lang", "3.1-SNAPSHOT", "sources", "jar" );
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commons-lang-3.1-SNAPSHOT-javadoc.jar", "commons-lang" ),
+ "commons-lang", "3.1-SNAPSHOT", "javadoc", "jar" );
+ }
+
+ public void testSplitFilenameApacheIncubator() throws LayoutException
+ {
+ assertSplit( RepositoryLayoutUtils.splitFilename( "cxf-common-2.0-incubator-M1.pom", null ), "cxf-common",
+ "2.0-incubator-M1", "", "pom" );
+ assertSplit( RepositoryLayoutUtils.splitFilename( "commonj-api_r1.1-1.0-incubator-M2.jar", null ),
+ "commonj-api_r1.1", "1.0-incubator-M2", "", "jar" );
+ }
+
+ public void testSplitFilenameBlankInputs()
+ {
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( null, null );
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ /* expected path */
+ }
+ catch ( LayoutException e )
+ {
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( "", null );
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ /* expected path */
+ }
+ catch ( LayoutException e )
+ {
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( " ", null );
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ /* expected path */
+ }
+ catch ( LayoutException e )
+ {
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( " \t \n ", null );
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ /* expected path */
+ }
+ catch ( LayoutException e )
+ {
+ fail( "Should have thrown an IllegalArgumentException." );
+ }
+ }
+
+ public void testSplitFilenameBadInputs()
+ {
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( "commons-lang.jar", null );
+ fail( "Should have thrown a LayoutException (No Version)." );
+ }
+ catch ( LayoutException e )
+ {
+ /* Expected Path */
+ }
+
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( "geronimo-store", null );
+ fail( "Should have thrown a LayoutException (No Extension)." );
+ }
+ catch ( LayoutException e )
+ {
+ /* Expected Path */
+ }
+
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( "The Sixth Sick Sheiks Sixth Sheep is Sick.", null );
+ fail( "Should have thrown a LayoutException (No Extension)." );
+ }
+ catch ( LayoutException e )
+ {
+ /* Expected Path */
+ }
+
+ try
+ {
+ RepositoryLayoutUtils.splitFilename( "1.0.jar", null );
+ fail( "Should have thrown a LayoutException (No Artifact ID)." );
+ }
+ catch ( LayoutException e )
+ {
+ /* Expected Path */
+ }
+ }
+
+ private void assertSplit( String[] actualSplit, String artifactId, String version, String classifier,
+ String extension )
+ {
+ assertEquals( "Split - artifactId", artifactId, actualSplit[0] );
+ assertEquals( "Split - version", version, actualSplit[1] );
+ assertEquals( "Split - classifier", classifier, actualSplit[2] );
+ assertEquals( "Split - extension", extension, actualSplit[3] );
+ }
+}
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/CentralScannerTiming.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/CentralScannerTiming.java
new file mode 100644
index 000000000..3c2c3a2aa
--- /dev/null
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/CentralScannerTiming.java
@@ -0,0 +1,132 @@
+package org.apache.maven.archiva.repository.scanner;
+
+/*
+ * 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.maven.archiva.common.utils.BaseFile;
+import org.apache.maven.archiva.common.utils.DateUtil;
+import org.apache.maven.archiva.model.RepositoryContentStatistics;
+import org.apache.maven.archiva.repository.ArchivaRepository;
+import org.apache.maven.archiva.repository.RepositoryException;
+import org.apache.maven.archiva.repository.consumer.Consumer;
+import org.apache.maven.archiva.repository.consumer.ConsumerException;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * CentralScannerTiming
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class CentralScannerTiming
+{
+ public static void main( String[] args )
+ {
+ String pathToCentral = "/home/repo1/ibiblio";
+
+ ( new CentralScannerTiming() ).scanIt( pathToCentral );
+ }
+
+ public void scanIt( String path )
+ {
+ ArchivaRepository centralRepo = new ArchivaRepository( "central", "Central Mirror", "file://" + path );
+
+ RepositoryScanner scanner = new RepositoryScanner();
+
+ List consumerList = new ArrayList();
+ BasicConsumer consumer = new BasicConsumer();
+ consumerList.add( consumer );
+
+ try
+ {
+ RepositoryContentStatistics stats = scanner.scan( centralRepo, consumerList, true );
+
+ SimpleDateFormat df = new SimpleDateFormat();
+ System.out.println( "-------" );
+ System.out.println( " Repository ID : " + stats.getRepositoryId() );
+ System.out.println( " Duration : " + DateUtil.getDuration( stats.getDuration() ) );
+ System.out.println( " When Gathered : " + df.format( stats.getWhenGathered() ) );
+ System.out.println( " Total File Count: " + stats.getTotalFileCount() );
+ System.out.println( " New File Count : " + stats.getNewFileCount() );
+ }
+ catch ( RepositoryException e )
+ {
+ e.printStackTrace( System.err );
+ }
+ }
+
+ class BasicConsumer implements Consumer
+ {
+ int count = 0;
+
+ public List getExcludePatterns()
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ public List getIncludePatterns()
+ {
+ List includes = new ArrayList();
+ includes.add( "**/*.pom" );
+ includes.add( "**/*.jar" );
+ includes.add( "**/*.war" );
+ includes.add( "**/*.ear" );
+ includes.add( "**/*.sar" );
+ includes.add( "**/*.car" );
+ includes.add( "**/*.mar" );
+// includes.add( "**/*.sha1" );
+// includes.add( "**/*.md5" );
+// includes.add( "**/*.asc" );
+ includes.add( "**/*.dtd" );
+ includes.add( "**/*.tld" );
+ includes.add( "**/*.gz" );
+ includes.add( "**/*.bz2" );
+ includes.add( "**/*.zip" );
+ return includes;
+ }
+
+ public String getName()
+ {
+ return "Basic No-op Consumer";
+ }
+
+ public boolean init( ArchivaRepository repository )
+ {
+ return true;
+ }
+
+ public void processFile( BaseFile file ) throws ConsumerException
+ {
+ count++;
+ if ( ( count % 1000 ) == 0 )
+ {
+ System.out.println( "Files Processed: " + count );
+ }
+ }
+
+ public void processFileProblem( BaseFile file, String message )
+ {
+ /* no-op */
+ }
+ }
+}
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/RepositoryScannerTest.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/RepositoryScannerTest.java
new file mode 100644
index 000000000..4907819f0
--- /dev/null
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/RepositoryScannerTest.java
@@ -0,0 +1,70 @@
+package org.apache.maven.archiva.repository.scanner;
+
+/*
+ * 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.commons.lang.StringUtils;
+import org.apache.maven.archiva.model.RepositoryContentStatistics;
+import org.apache.maven.archiva.repository.ArchivaRepository;
+import org.apache.maven.archiva.repository.RepositoryException;
+import org.codehaus.plexus.PlexusTestCase;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * RepositoryScannerTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class RepositoryScannerTest extends PlexusTestCase
+{
+ private ArchivaRepository createDefaultRepository()
+ {
+ File repoDir = new File( getBasedir(), "src/test/repositories/default-repository" );
+
+ assertTrue( "Default Test Repository should exist.", repoDir.exists() && repoDir.isDirectory() );
+
+ String repoUri = "file://" + StringUtils.replace( repoDir.getAbsolutePath(), "\\", "/" );
+
+ ArchivaRepository repo = new ArchivaRepository( "testDefaultRepo", "Test Default Repository", repoUri );
+
+ return repo;
+ }
+
+ public void testDefaultRepositoryScanner() throws RepositoryException
+ {
+ ArchivaRepository repository = createDefaultRepository();
+
+ List consumers = new ArrayList();
+ ScanConsumer consumer = new ScanConsumer();
+ consumers.add( consumer );
+
+ RepositoryScanner scanner = new RepositoryScanner();
+ boolean includeSnapshots = true;
+ RepositoryContentStatistics stats = scanner.scan( repository, consumers, includeSnapshots );
+
+ assertNotNull( "Stats should not be null.", stats );
+ assertEquals( "Stats.totalFileCount", 17, stats.getTotalFileCount() );
+ assertEquals( "Processed Count", 17, consumer.getProcessCount() );
+ }
+
+}
diff --git a/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/ScanConsumer.java b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/ScanConsumer.java
new file mode 100644
index 000000000..d1c8e0a10
--- /dev/null
+++ b/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/scanner/ScanConsumer.java
@@ -0,0 +1,82 @@
+package org.apache.maven.archiva.repository.scanner;
+
+/*
+ * 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.maven.archiva.common.utils.BaseFile;
+import org.apache.maven.archiva.repository.ArchivaRepository;
+import org.apache.maven.archiva.repository.consumer.Consumer;
+import org.apache.maven.archiva.repository.consumer.ConsumerException;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * ScanConsumer
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class ScanConsumer implements Consumer
+{
+ private int processCount = 0;
+
+ public List getExcludePatterns()
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ public List getIncludePatterns()
+ {
+ List includes = new ArrayList();
+ includes.add( "**/*.jar" );
+ return includes;
+ }
+
+ public String getName()
+ {
+ return "Scan Consumer";
+ }
+
+ public boolean init( ArchivaRepository repository )
+ {
+ return true;
+ }
+
+ public void processFile( BaseFile file ) throws ConsumerException
+ {
+ this.processCount++;
+ }
+
+ public void processFileProblem( BaseFile file, String message )
+ {
+ /* do nothing */
+ }
+
+ public int getProcessCount()
+ {
+ return processCount;
+ }
+
+ public void setProcessCount( int processCount )
+ {
+ this.processCount = processCount;
+ }
+}
diff --git a/archiva-repository-layer/src/test/resources/log4j.xml b/archiva-repository-layer/src/test/resources/log4j.xml
new file mode 100644
index 000000000..23d4d08d6
--- /dev/null
+++ b/archiva-repository-layer/src/test/resources/log4j.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d [%t] %-5p %-30c{1} - %m%n"/>
+ </layout>
+ </appender>
+
+ <!-- Help identify bugs during testing -->
+ <logger name="org.apache.maven">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.codehaus.plexus.security">
+ <level value="info"/>
+ </logger>
+
+ <!-- squelch noisy objects (for now) -->
+ <logger name="org.codehaus.plexus.mailsender.MailSender">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.codehaus.plexus.PlexusContainer">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.codehaus.plexus.component.manager.ClassicSingletonComponentManager">
+ <level value="error"/>
+ </logger>
+
+ <root>
+ <priority value ="warn" />
+ <appender-ref ref="console" />
+ </root>
+
+</log4j:configuration>