* Adding Project/Versioned/Artifact functionality to BidirectionalRepositoryLayout.

* Adding Metadata Reader/Write/Merge.



git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/branches/archiva-jpox-database-refactor@529616 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Joakim Erdfelt 2007-04-17 14:11:58 +00:00
parent e37599c559
commit 3f7a13c5a6
11 changed files with 455 additions and 31 deletions

View File

@ -64,8 +64,9 @@ public class DefaultBidirectionalRepositoryLayout
public String toPath( ArtifactReference artifact )
{
return toPath( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getVersion(),
artifact.getClassifier(), artifact.getType() );
String baseVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
return toPath( artifact.getGroupId(), artifact.getArtifactId(), baseVersion, artifact.getVersion(), artifact
.getClassifier(), artifact.getType() );
}
private String toPath( String groupId, String artifactId, String baseVersion, String version, String classifier,

View File

@ -0,0 +1,131 @@
package org.apache.maven.archiva.repository.metadata;
/*
* 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.model.ArchivaModelCloner;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.model.SnapshotVersion;
import java.util.Iterator;
import java.util.List;
/**
* RepositoryMetadataMerge
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RepositoryMetadataMerge
{
public static ArchivaRepositoryMetadata merge( final ArchivaRepositoryMetadata mainMetadata,
final ArchivaRepositoryMetadata sourceMetadata )
throws RepositoryMetadataException
{
if ( mainMetadata == null )
{
throw new RepositoryMetadataException( "Cannot merge a null main project." );
}
if ( sourceMetadata == null )
{
throw new RepositoryMetadataException( "Cannot copy to a null parent project." );
}
ArchivaRepositoryMetadata merged = new ArchivaRepositoryMetadata();
merged.setGroupId( merge( mainMetadata.getGroupId(), sourceMetadata.getGroupId() ) );
merged.setReleasedVersion( merge( mainMetadata.getReleasedVersion(), sourceMetadata.getReleasedVersion() ) );
merged.setSnapshotVersion( merge( mainMetadata.getSnapshotVersion(), sourceMetadata.getSnapshotVersion() ) );
merged.setLastUpdated( merge( mainMetadata.getLastUpdated(), sourceMetadata.getLastUpdated() ) );
merged.setAvailableVersions( mergeAvailableVersions( mainMetadata.getAvailableVersions(), sourceMetadata
.getAvailableVersions() ) );
return merged;
}
private static boolean empty( String val )
{
if ( val == null )
{
return true;
}
return ( val.trim().length() <= 0 );
}
private static SnapshotVersion merge( SnapshotVersion mainSnapshotVersion, SnapshotVersion sourceSnapshotVersion )
{
if ( sourceSnapshotVersion == null )
{
return mainSnapshotVersion;
}
if ( mainSnapshotVersion == null )
{
return ArchivaModelCloner.clone( sourceSnapshotVersion );
}
SnapshotVersion merged = new SnapshotVersion();
merged.setTimestamp( merge( mainSnapshotVersion.getTimestamp(), sourceSnapshotVersion.getTimestamp() ) );
merged
.setBuildNumber( Math.max( mainSnapshotVersion.getBuildNumber(), sourceSnapshotVersion.getBuildNumber() ) );
return merged;
}
private static String merge( String main, String source )
{
if ( empty( main ) && !empty( source ) )
{
return source;
}
return main;
}
private static List mergeAvailableVersions( List mainAvailableVersions, List sourceAvailableVersions )
{
if ( sourceAvailableVersions == null )
{
return mainAvailableVersions;
}
if ( mainAvailableVersions == null )
{
return ArchivaModelCloner.cloneAvailableVersions( sourceAvailableVersions );
}
List merged = ArchivaModelCloner.cloneAvailableVersions( mainAvailableVersions );
Iterator it = sourceAvailableVersions.iterator();
while ( it.hasNext() )
{
String sourceVersion = (String) it.next();
if ( !merged.contains( sourceVersion ) )
{
merged.add( sourceVersion );
}
}
return merged;
}
}

View File

@ -19,9 +19,12 @@ package org.apache.maven.archiva.repository.metadata;
* under the License.
*/
import org.apache.commons.lang.math.NumberUtils;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.model.SnapshotVersion;
import org.apache.maven.archiva.xml.XMLException;
import org.apache.maven.archiva.xml.XMLReader;
import org.dom4j.Element;
import java.io.File;
import java.util.Date;
@ -41,23 +44,39 @@ public class RepositoryMetadataReader
* @return the archiva repository metadata object that represents the provided file contents.
* @throws RepositoryMetadataException
*/
public ArchivaRepositoryMetadata read( File metadataFile ) throws RepositoryMetadataException
public ArchivaRepositoryMetadata read( File metadataFile )
throws RepositoryMetadataException
{
try
{
XMLReader xml = new XMLReader( "metadata", metadataFile );
ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
metadata.setGroupId( xml.getElementText( "//metadata/groupId" ) );
metadata.setArtifactId( xml.getElementText( "//metadata/artifactId" ) );
metadata.setLastModified( new Date( metadataFile.lastModified() ) );
metadata.setSize( metadataFile.length() );
metadata.setWhenIndexed( new Date() );
metadata.setFileLastModified( new Date( metadataFile.lastModified() ) );
metadata.setFileSize( metadataFile.length() );
metadata.setWhenIndexed( null );
metadata.setLastUpdated( xml.getElementText( "//metadata/versioning/lastUpdated" ) );
metadata.setLatestVersion( xml.getElementText( "//metadata/versioning/latest" ) );
metadata.setReleasedVersion( xml.getElementText( "//metadata/versioning/release" ) );
metadata.setAvailableVersions( xml.getElementListText( "//metadata/versioning/versions/version" ) );
Element snapshotElem = xml.getElement( "//metadata/versioning/snapshot" );
if ( snapshotElem != null )
{
SnapshotVersion snapshot = new SnapshotVersion();
snapshot.setTimestamp( snapshotElem.elementTextTrim( "timestamp" ) );
String tmp = snapshotElem.elementTextTrim( "buildNumber" );
if( NumberUtils.isNumber( tmp ))
{
snapshot.setBuildNumber( NumberUtils.toInt( tmp ) );
}
metadata.setSnapshotVersion( snapshot );
}
return metadata;
}
catch ( XMLException e )

View File

@ -0,0 +1,130 @@
package org.apache.maven.archiva.repository.metadata;
/*
* 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.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.xml.XMLException;
import org.apache.maven.archiva.xml.XMLWriter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
/**
* RepositoryMetadataWriter
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RepositoryMetadataWriter
{
public static void write( ArchivaRepositoryMetadata metadata, File outputFile )
throws RepositoryMetadataException
{
FileWriter writer = null;
try
{
writer = new FileWriter( outputFile );
write( metadata, writer );
writer.flush();
}
catch ( IOException e )
{
throw new RepositoryMetadataException( "Unable to write metadata file: " + outputFile.getAbsolutePath()
+ " - " + e.getMessage(), e );
}
finally
{
IOUtils.closeQuietly( writer );
}
}
public static void write( ArchivaRepositoryMetadata metadata, Writer writer )
throws RepositoryMetadataException
{
Document doc = DocumentHelper.createDocument();
Element root = DocumentHelper.createElement( "metadata" );
doc.setRootElement( root );
root.addElement( "groupId" ).setText( metadata.getGroupId() );
root.addElement( "artifactId" ).setText( metadata.getArtifactId() );
addOptionalElementText( root, "version", metadata.getVersion() );
if ( CollectionUtils.isNotEmpty( metadata.getAvailableVersions() )
|| StringUtils.isNotBlank( metadata.getReleasedVersion() )
|| StringUtils.isNotBlank( metadata.getLatestVersion() )
|| StringUtils.isNotBlank( metadata.getLastUpdated() ) || ( metadata.getSnapshotVersion() != null ) )
{
Element versioning = root.addElement( "versioning" );
addOptionalElementText( versioning, "latest", metadata.getLatestVersion() );
addOptionalElementText( versioning, "release", metadata.getReleasedVersion() );
if ( metadata.getSnapshotVersion() != null )
{
Element snapshot = versioning.addElement( "snapshot" );
String bnum = String.valueOf( metadata.getSnapshotVersion().getBuildNumber() );
addOptionalElementText( snapshot, "buildNumber", bnum );
addOptionalElementText( snapshot, "timestamp", metadata.getSnapshotVersion().getTimestamp() );
}
if ( CollectionUtils.isNotEmpty( metadata.getAvailableVersions() ) )
{
Element versions = versioning.addElement( "versions" );
Iterator it = metadata.getAvailableVersions().iterator();
while ( it.hasNext() )
{
String version = (String) it.next();
versions.addElement( "version" ).setText( version );
}
}
addOptionalElementText( versioning, "lastUpdated", metadata.getLastUpdated() );
}
try
{
XMLWriter.write( doc, writer );
}
catch ( XMLException e )
{
throw new RepositoryMetadataException( "Unable to write xml contents to writer: " + e.getMessage(), e );
}
}
private static void addOptionalElementText( Element elem, String elemName, String text )
{
if ( StringUtils.isBlank( text ) )
{
return;
}
elem.addElement( elemName ).setText( text );
}
}

View File

@ -62,15 +62,14 @@ public class ProjectModelMerge
public static ArchivaProjectModel merge( ArchivaProjectModel mainProject, ArchivaProjectModel parentProject )
throws ProjectModelException
{
System.out.println( "## Merging: " + mainProject + " with " + parentProject );
if ( mainProject == null )
{
throw new ProjectModelException( "Cannot copy a null main project." );
throw new ProjectModelException( "Cannot merge with a null main project." );
}
if ( parentProject == null )
{
throw new ProjectModelException( "Cannot copy to a null parent project." );
throw new ProjectModelException( "Cannot merge with a null parent project." );
}
ArchivaProjectModel merged = new ArchivaProjectModel();

View File

@ -20,6 +20,7 @@ package org.apache.maven.archiva.repository.layout;
*/
import org.apache.maven.archiva.model.ArchivaArtifact;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
import org.apache.maven.archiva.repository.layout.LayoutException;
@ -29,11 +30,13 @@ import org.apache.maven.archiva.repository.layout.LayoutException;
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectionalRepositoryLayoutTestCase
public class DefaultBidirectionalRepositoryLayoutTest
extends AbstractBidirectionalRepositoryLayoutTestCase
{
private BidirectionalRepositoryLayout layout;
protected void setUp() throws Exception
protected void setUp()
throws Exception
{
super.setUp();
@ -65,41 +68,65 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
{
ArchivaArtifact artifact = createArtifact( "com.foo", "foo-connector", "2.1-20060822.123456-35", "", "jar" );
assertEquals( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar",
layout.toPath( artifact ) );
assertEquals( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar", layout
.toPath( artifact ) );
}
public void testToArtifactBasicSimpleGroupId() throws LayoutException
public void testTimestampedSnapshotRoundtrip()
throws LayoutException
{
String originalPath = "org/apache/maven/test/get-metadata-snapshot/1.0-SNAPSHOT/get-metadata-snapshot-1.0-20050831.101112-1.jar";
ArchivaArtifact artifact = layout.toArtifact( originalPath );
assertArtifact( artifact, "org.apache.maven.test", "get-metadata-snapshot", "1.0-20050831.101112-1", "", "jar" );
assertEquals( originalPath, layout.toPath( artifact ) );
ArtifactReference aref = new ArtifactReference();
aref.setGroupId( artifact.getGroupId() );
aref.setArtifactId( artifact.getArtifactId() );
aref.setVersion( artifact.getVersion() );
aref.setClassifier( artifact.getClassifier() );
aref.setType( artifact.getType() );
assertEquals( originalPath, layout.toPath( aref ) );
}
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 testToArtifactBasicLongGroupId() throws LayoutException
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() throws LayoutException
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() throws LayoutException
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" );
ArchivaArtifact artifact = layout
.toArtifact( "com/foo/lib/foo-lib/2.1-alpha-1/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() throws LayoutException
public void testToArtifactUsingUniqueSnapshot()
throws LayoutException
{
ArchivaArtifact artifact =
layout.toArtifact( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar" );
ArchivaArtifact artifact = layout
.toArtifact( "com/foo/foo-connector/2.1-SNAPSHOT/foo-connector-2.1-20060822.123456-35.jar" );
assertSnapshotArtifact( artifact, "com.foo", "foo-connector", "2.1-20060822.123456-35", "", "jar" );
}
@ -115,7 +142,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
/* expected path */
}
}
public void testInvalidNonSnapshotInSnapshotDir()
{
try
@ -128,7 +155,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
/* expected path */
}
}
public void testInvalidPathTooShort()
{
try
@ -141,7 +168,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
/* expected path */
}
}
public void testInvalidTimestampSnapshotNotInSnapshotDir()
{
try
@ -154,7 +181,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
/* expected path */
}
}
public void testInvalidVersionPathMismatch()
{
try
@ -167,7 +194,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
/* expected path */
}
}
public void testInvalidVersionPathMismatchAlt()
{
try
@ -180,7 +207,7 @@ public class DefaultBidirectionalRepositoryLayoutTest extends AbstractBidirectio
/* expected path */
}
}
public void testInvalidArtifactIdForPath()
{
try

View File

@ -35,6 +35,7 @@ public class AllTests
{
TestSuite suite = new TestSuite( "Test for org.apache.maven.archiva.repository.metadata" );
//$JUnit-BEGIN$
suite.addTestSuite( RepositoryMetadataWriterTest.class );
suite.addTestSuite( RepositoryMetadataReaderTest.class );
//$JUnit-END$
return suite;

View File

@ -49,4 +49,23 @@ public class RepositoryMetadataReaderTest extends PlexusTestCase
assertTrue( "Available version 1.0", metadata.getAvailableVersions().contains( "1.0" ) );
assertTrue( "Available version 1.1", metadata.getAvailableVersions().contains( "1.1" ) );
}
public void testLoadComplex() throws RepositoryMetadataException
{
File defaultRepoDir = new File( getBasedir(), "src/test/repositories/default-repository" );
File metadataFile = new File( defaultRepoDir, "org/apache/maven/samplejar/maven-metadata.xml" );
RepositoryMetadataReader reader = new RepositoryMetadataReader();
ArchivaRepositoryMetadata metadata = reader.read( metadataFile );
assertNotNull( metadata );
assertEquals( "Group Id", "org.apache.maven", metadata.getGroupId() );
assertEquals( "Artifact Id", "samplejar", metadata.getArtifactId() );
assertEquals( "Released Version", "2.0", metadata.getReleasedVersion() );
assertEquals( "Latest Version", "6.0-SNAPSHOT", metadata.getLatestVersion() );
assertEquals( "List of Available Versions", 18, metadata.getAvailableVersions().size() );
assertTrue( "Available version 6.0-20060311.183228-10", metadata.getAvailableVersions().contains( "6.0-20060311.183228-10" ) );
assertTrue( "Available version 6.0-SNAPSHOT", metadata.getAvailableVersions().contains( "6.0-SNAPSHOT" ) );
}
}

View File

@ -0,0 +1,60 @@
package org.apache.maven.archiva.repository.metadata;
/*
* 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.io.FileUtils;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.codehaus.plexus.PlexusTestCase;
import java.io.File;
import java.io.StringWriter;
/**
* RepositoryMetadataWriterTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RepositoryMetadataWriterTest
extends PlexusTestCase
{
public void testWriteSimple()
throws Exception
{
File defaultRepoDir = new File( getBasedir(), "src/test/repositories/default-repository" );
File expectedFile = new File( defaultRepoDir, "org/apache/maven/shared/maven-downloader/maven-metadata.xml" );
String expectedContent = FileUtils.readFileToString( expectedFile, null );
ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
metadata.setGroupId( "org.apache.maven.shared" );
metadata.setArtifactId( "maven-downloader" );
metadata.setVersion( "1.0" );
metadata.setReleasedVersion( "1.1" );
metadata.getAvailableVersions().add( "1.0" );
metadata.getAvailableVersions().add( "1.1" );
metadata.setLastUpdated( "20061212214311" );
StringWriter actual = new StringWriter();
RepositoryMetadataWriter.write( metadata, actual );
assertEquals( "XML Contents", expectedContent, actual.toString() );
}
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.maven</groupId>
<artifactId>samplejar</artifactId>
<version>6.0-SNAPSHOT</version>
<versioning>
<release>2.0</release>
<latest>6.0-SNAPSHOT</latest>
<snapshot>
<buildNumber>26</buildNumber>
</snapshot>
<versions>
<version>6.0-SNAPSHOT</version>
<version>6.0-20060311.093250-41</version>
<version>6.0-20060311.183228-42</version>
<version>6.0-20060311.183228-40</version>
<version>6.0-20060311.183228-37</version>
<version>6.0-20060311.183228-30</version>
<version>6.0-20060311.183228-29</version>
<version>6.0-20060311.183228-6</version>
<version>6.0-20060311.183228-9</version>
<version>6.0-20060311.183228-10</version>
<version>6.0-20060313.001659-43</version>
<version>6.0-20060313.001659-41</version>
<version>6.0-20060313.001659-38</version>
<version>6.0-20060313.001659-31</version>
<version>6.0-20060313.001659-30</version>
<version>6.0-20060313.001659-7</version>
<version>6.0-20060313.001659-10</version>
<version>6.0-20060313.001659-11</version>
</versions>
<lastUpdated>20060313010719</lastUpdated>
</versioning>
</metadata>

View File

@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?><metadata>
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-downloader</artifactId>
<version>1.0</version>
@ -10,4 +12,4 @@
</versions>
<lastUpdated>20061212214311</lastUpdated>
</versioning>
</metadata>
</metadata>