import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
import org.apache.maven.repository.digest.DigestUtils;
import org.apache.maven.repository.digest.DigesterException;
import org.apache.maven.repository.discovery.ArtifactDiscoverer;
import org.apache.maven.wagon.repository.Repository;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
}
else if ( path.endsWith( "maven-metadata.xml" ) )
{
- // TODO: merge the metadata!
+ File metadataFile = new File( target.getParentFile(), ".metadata-" + repository.getRepository().getId() );
+
policy = repository.getRepository().getReleases();
- if ( force || !target.exists() || isOutOfDate( policy, target ) )
+ if ( force || !metadataFile.exists() || isOutOfDate( policy, metadataFile ) )
{
- getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, target, policy,
- force );
+ getFileFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, metadataFile,
+ policy, force );
+
+ mergeMetadataFiles( target, metadataFile );
}
}
else
}
}
+ private void mergeMetadataFiles( File target, File metadataFile )
+ throws ProxyException
+ {
+ if ( target.exists() )
+ {
+ MetadataXpp3Reader reader = new MetadataXpp3Reader();
+ Metadata metadata;
+ FileReader fileReader = null;
+ try
+ {
+ fileReader = new FileReader( target );
+ metadata = reader.read( fileReader );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new ProxyException( "Unable to parse existing metadata: " + e.getMessage(), e );
+ }
+ catch ( IOException e )
+ {
+ throw new ProxyException( "Unable to read existing metadata: " + e.getMessage(), e );
+ }
+ finally
+ {
+ IOUtil.close( fileReader );
+ }
+
+ fileReader = null;
+ boolean changed = false;
+ try
+ {
+ fileReader = new FileReader( metadataFile );
+ Metadata newMetadata = reader.read( fileReader );
+
+ changed = metadata.merge( newMetadata );
+ }
+ catch ( IOException e )
+ {
+ // ignore the merged file
+ getLogger().warn( "Unable to read new metadata: " + e.getMessage() );
+ }
+ catch ( XmlPullParserException e )
+ {
+ // ignore the merged file
+ getLogger().warn( "Unable to parse new metadata: " + e.getMessage() );
+ }
+ finally
+ {
+ IOUtil.close( fileReader );
+ }
+
+ if ( changed )
+ {
+ FileWriter fileWriter = null;
+ try
+ {
+ fileWriter = new FileWriter( target );
+ new MetadataXpp3Writer().write( fileWriter, metadata );
+ }
+ catch ( IOException e )
+ {
+ getLogger().warn( "Unable to store new metadata: " + e.getMessage() );
+ }
+ finally
+ {
+ IOUtil.close( fileWriter );
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ FileUtils.copyFile( metadataFile, target );
+ }
+ catch ( IOException e )
+ {
+ // warn, but ignore
+ getLogger().warn( "Unable to copy metadata: " + metadataFile + " to " + target );
+ }
+ }
+ }
+
private void getFileFromRepository( String path, ProxiedArtifactRepository repository, String repositoryCachePath,
ProxyInfo httpProxy, File target, ArtifactRepositoryPolicy policy,
boolean force )
throws ProxyException
{
- boolean connected = false;
Map checksums = null;
Wagon wagon = null;
File temp = new File( target.getAbsolutePath() + ".tmp" );
temp.deleteOnExit();
+ boolean connected = false;
try
{
String protocol = repository.getRepository().getProtocol();
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.Wagon;
import java.io.File;
import java.io.IOException;
+import java.io.StringWriter;
import java.net.MalformedURLException;
import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
+import java.util.Locale;
/**
* Test the proxy handler.
*
* @author Brett Porter
* @todo! tests to do vvv
- * @todo test metadata - general
- * @todo test metadata - multiple repos are merged
- * @todo test metadata - update interval
- * @todo test metadata - looking for an update and file has been removed remotely
* @todo test snapshots - general
* @todo test snapshots - newer version on repo1 (than local), timestamp driven
* @todo test snapshots - older version on repo1 skipped (than local), timestamp driven
assertFalse( expectedFile.exists() );
- File file = null;
try
{
- file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
fail( "Found file: " + file + "; but was expecting a failure" );
}
catch ( ResourceDoesNotExistException e )
assertFalse( expectedFile.exists() );
- File file = null;
try
{
- file = requestHandler.getAlways( path, proxiedRepositories, defaultManagedRepository );
+ File file = requestHandler.getAlways( path, proxiedRepositories, defaultManagedRepository );
+ fail( "Found file: " + file + "; but was expecting a failure" );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ // expected
+
+ assertFalse( expectedFile.exists() );
+ }
+ }
+
+ public void testGetMetadataNotPresent()
+ throws ProxyException
+ {
+ String path = "org/apache/maven/test/dummy-artifact/1.0/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+
+ assertFalse( expectedFile.exists() );
+
+ try
+ {
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
fail( "Found file: " + file + "; but was expecting a failure" );
}
catch ( ResourceDoesNotExistException e )
}
}
+ public void testGetMetadataProxied()
+ throws ProxyException, ResourceDoesNotExistException, IOException
+ {
+ String path = "org/apache/maven/test/get-default-metadata/1.0/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+
+ assertFalse( expectedFile.exists() );
+
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+ String expectedContents = FileUtils.fileRead( new File( proxiedRepository1.getBasedir(), path ) );
+ assertEquals( "Check content matches", expectedContents, FileUtils.fileRead( file ) );
+ }
+
+ public void testGetMetadataMergeRepos()
+ throws IOException, ResourceDoesNotExistException, ProxyException
+ {
+ String path = "org/apache/maven/test/get-merged-metadata/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+
+ assertTrue( expectedFile.exists() );
+
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+
+ StringWriter expectedContents = new StringWriter();
+ Metadata m = new Metadata();
+ m.setGroupId( "org.apache.maven.test" );
+ m.setArtifactId( "get-merged-metadata" );
+ m.setVersioning( new Versioning() );
+ m.getVersioning().addVersion( "0.9" );
+ m.getVersioning().addVersion( "1.0" );
+ m.getVersioning().addVersion( "2.0" );
+ m.getVersioning().addVersion( "3.0" );
+ m.getVersioning().addVersion( "5.0" );
+ m.getVersioning().addVersion( "4.0" );
+ m.setModelEncoding( null );
+ new MetadataXpp3Writer().write( expectedContents, m );
+
+ assertEquals( "Check content matches", expectedContents.toString(), FileUtils.fileRead( file ) );
+ }
+
+ public void testGetMetadataRemovedFromProxies()
+ throws ResourceDoesNotExistException, ProxyException, IOException
+ {
+ String path = "org/apache/maven/test/get-removed-metadata/1.0/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+ String expectedContents = FileUtils.fileRead( new File( defaultManagedRepository.getBasedir(), path ) );
+
+ assertTrue( expectedFile.exists() );
+
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+ assertEquals( "Check content matches", expectedContents, FileUtils.fileRead( file ) );
+ }
+
+ public void testGetMetadataNotExpired()
+ throws IOException, ResourceDoesNotExistException, ProxyException
+ {
+ String path = "org/apache/maven/test/get-updated-metadata/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+ String expectedContents = FileUtils.fileRead( new File( defaultManagedRepository.getBasedir(), path ) );
+
+ assertTrue( expectedFile.exists() );
+
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+ assertEquals( "Check content matches", expectedContents, FileUtils.fileRead( file ) );
+
+ String unexpectedContents = FileUtils.fileRead( new File( proxiedRepository1.getBasedir(), path ) );
+ assertFalse( "Check content doesn't match proxy version",
+ unexpectedContents.equals( FileUtils.fileRead( file ) ) );
+ }
+
+ public void testGetMetadataNotUpdated()
+ throws ResourceDoesNotExistException, ProxyException, IOException
+ {
+ String path = "org/apache/maven/test/get-updated-metadata/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+ String expectedContents = FileUtils.fileRead( new File( defaultManagedRepository.getBasedir(), path ) );
+
+ assertTrue( expectedFile.exists() );
+
+ File proxiedFile = new File( proxiedRepository1.getBasedir(), path );
+ new File( expectedFile.getParentFile(), ".metadata-proxied1" ).setLastModified( proxiedFile.lastModified() );
+
+ proxiedRepository1.getReleases().setUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS );
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+ assertEquals( "Check content matches", expectedContents, FileUtils.fileRead( file ) );
+
+ String unexpectedContents = FileUtils.fileRead( proxiedFile );
+ assertFalse( "Check content doesn't match proxy version",
+ unexpectedContents.equals( FileUtils.fileRead( file ) ) );
+ }
+
+ public void testGetMetadataUpdated()
+ throws IOException, ResourceDoesNotExistException, ProxyException, ParseException
+ {
+ String path = "org/apache/maven/test/get-updated-metadata/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+ String unexpectedContents = FileUtils.fileRead( new File( defaultManagedRepository.getBasedir(), path ) );
+
+ assertTrue( expectedFile.exists() );
+
+ new File( expectedFile.getParentFile(), ".metadata-proxied1" ).setLastModified( getHistoricalDate().getTime() );
+
+ File file = requestHandler.get( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+
+ StringWriter expectedContents = new StringWriter();
+ Metadata m = new Metadata();
+ m.setGroupId( "org.apache.maven.test" );
+ m.setArtifactId( "get-updated-metadata" );
+ m.setVersioning( new Versioning() );
+ m.getVersioning().addVersion( "1.0" );
+ m.getVersioning().addVersion( "2.0" );
+ m.setModelEncoding( null );
+ new MetadataXpp3Writer().write( expectedContents, m );
+ assertEquals( "Check content matches", expectedContents.toString(), FileUtils.fileRead( file ) );
+ assertFalse( "Check content doesn't match old version",
+ unexpectedContents.equals( FileUtils.fileRead( file ) ) );
+ }
+
+ public void testGetAlwaysMetadata()
+ throws IOException, ResourceDoesNotExistException, ProxyException
+ {
+ String path = "org/apache/maven/test/get-updated-metadata/maven-metadata.xml";
+ File expectedFile = new File( defaultManagedRepository.getBasedir(), path );
+ String unexpectedContents = FileUtils.fileRead( new File( defaultManagedRepository.getBasedir(), path ) );
+
+ assertTrue( expectedFile.exists() );
+
+ File file = requestHandler.getAlways( path, proxiedRepositories, defaultManagedRepository );
+ assertEquals( "Check file matches", expectedFile, file );
+ assertTrue( "Check file created", file.exists() );
+
+ StringWriter expectedContents = new StringWriter();
+ Metadata m = new Metadata();
+ m.setGroupId( "org.apache.maven.test" );
+ m.setArtifactId( "get-updated-metadata" );
+ m.setVersioning( new Versioning() );
+ m.getVersioning().addVersion( "1.0" );
+ m.getVersioning().addVersion( "2.0" );
+ m.setModelEncoding( null );
+ new MetadataXpp3Writer().write( expectedContents, m );
+ assertEquals( "Check content matches", expectedContents.toString(), FileUtils.fileRead( file ) );
+ assertFalse( "Check content doesn't match old version",
+ unexpectedContents.equals( FileUtils.fileRead( file ) ) );
+ }
+
+ private static Date getHistoricalDate()
+ throws ParseException
+ {
+ return new SimpleDateFormat( "yyyy-MM-dd", Locale.US ).parse( "2000-01-01" );
+ }
+
private void mockFailedChecksums( String path, File expectedFile )
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
{