<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</dependency>
+ <dependency>
+ <groupId>easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>1.2_Java1.3</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<instrumentation>
- <!-- TODO: should this module have tests? -->
+ <!-- exclude generated -->
<excludes>
- <exclude>**/**</exclude>
+ <exclude>org/apache/maven/repository/configuration/io/**</exclude>
+ <exclude>org/apache/maven/repository/configuration/*RepositoryConfiguration.*</exclude>
+ <exclude>org/apache/maven/repository/configuration/Configuration.*</exclude>
+ <exclude>org/apache/maven/repository/configuration/Proxy.*</exclude>
</excludes>
</instrumentation>
</configuration>
* Get the configuration from the store. A cached version may be used.
*
* @return the configuration
+ * @throws ConfigurationStoreException if there is a problem loading the configuration
*/
Configuration getConfigurationFromStore()
throws ConfigurationStoreException;
* @todo would be great for plexus to do this for us - so the configuration would be a component itself rather than this store
* @todo would be good to monitor the store file for changes
* @todo support other implementations than XML file
- * @plexus.component role="org.apache.maven.repository.configuration.ConfigurationStore"
+ * @plexus.component
*/
public class DefaultConfigurationStore
extends AbstractLogEnabled
FileWriter fileWriter = null;
try
{
+ file.getParentFile().mkdirs();
+
fileWriter = new FileWriter( file );
writer.write( fileWriter, configuration );
}
{
private final String name;
+ public InvalidConfigurationException( String name, String message )
+ {
+ super( message );
+ this.name = name;
+ }
+
public InvalidConfigurationException( String name, String message, Throwable cause )
{
super( message, cause );
--- /dev/null
+package org.apache.maven.repository.configuration;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.codehaus.plexus.util.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+/**
+ * @author Ben Walding
+ * @author Brett Porter
+ */
+public class MavenProxyPropertyLoader
+{
+ private static final String REPO_LOCAL_STORE = "repo.local.store";
+
+ private static final String PROXY_LIST = "proxy.list";
+
+ private static final String REPO_LIST = "repo.list";
+
+ public void load( Properties props, Configuration configuration )
+ throws InvalidConfigurationException
+ {
+ // set up the managed repository
+ String localCachePath = getMandatoryProperty( props, REPO_LOCAL_STORE );
+
+ RepositoryConfiguration config = new RepositoryConfiguration();
+ config.setDirectory( localCachePath );
+ config.setName( "Imported Maven-Proxy Cache" );
+ config.setId( "maven-proxy" );
+ configuration.addRepository( config );
+
+ //just get the first HTTP proxy and break
+ String propertyList = props.getProperty( PROXY_LIST );
+ if ( propertyList != null )
+ {
+ StringTokenizer tok = new StringTokenizer( propertyList, "," );
+ while ( tok.hasMoreTokens() )
+ {
+ String key = tok.nextToken();
+ if ( StringUtils.isNotEmpty( key ) )
+ {
+ Proxy proxy = new Proxy();
+ proxy.setHost( getMandatoryProperty( props, "proxy." + key + ".host" ) );
+ proxy.setPort( Integer.parseInt( getMandatoryProperty( props, "proxy." + key + ".port" ) ) );
+
+ // the username and password isn't required
+ proxy.setUsername( props.getProperty( "proxy." + key + ".username" ) );
+ proxy.setPassword( props.getProperty( "proxy." + key + ".password" ) );
+
+ configuration.setProxy( proxy );
+
+ //accept only one proxy configuration
+ break;
+ }
+ }
+ }
+
+ //get the remote repository list
+ String repoList = getMandatoryProperty( props, REPO_LIST );
+
+ StringTokenizer tok = new StringTokenizer( repoList, "," );
+ while ( tok.hasMoreTokens() )
+ {
+ String key = tok.nextToken();
+
+ Properties repoProps = getSubset( props, "repo." + key + "." );
+ String url = getMandatoryProperty( props, "repo." + key + ".url" );
+ String proxyKey = repoProps.getProperty( "proxy" );
+
+ boolean cacheFailures =
+ Boolean.valueOf( repoProps.getProperty( "cache.failures", "false" ) ).booleanValue();
+ boolean hardFail = Boolean.valueOf( repoProps.getProperty( "hardfail", "true" ) ).booleanValue();
+ int cachePeriod = Integer.parseInt( repoProps.getProperty( "cache.period", "60" ) );
+
+ ProxiedRepositoryConfiguration repository = new ProxiedRepositoryConfiguration();
+ repository.setId( key );
+ repository.setLayout( "legacy" );
+ repository.setManagedRepository( config.getId() );
+ repository.setName( "Imported Maven-Proxy Remote Proxy" );
+ repository.setSnapshotsInterval( cachePeriod );
+ repository.setUrl( url );
+ repository.setUseNetworkProxy( StringUtils.isNotEmpty( proxyKey ) );
+ repository.setCacheFailures( cacheFailures );
+ repository.setHardFail( hardFail );
+
+ configuration.addProxiedRepository( repository );
+ }
+ }
+
+ private Properties getSubset( Properties props, String prefix )
+ {
+ Enumeration keys = props.keys();
+ Properties result = new Properties();
+ while ( keys.hasMoreElements() )
+ {
+ String key = (String) keys.nextElement();
+ String value = props.getProperty( key );
+ if ( key.startsWith( prefix ) )
+ {
+ String newKey = key.substring( prefix.length() );
+ result.setProperty( newKey, value );
+ }
+ }
+ return result;
+ }
+
+ public void load( InputStream is, Configuration configuration )
+ throws IOException, InvalidConfigurationException
+ {
+ Properties props = new Properties();
+ props.load( is );
+ load( props, configuration );
+ }
+
+ private String getMandatoryProperty( Properties props, String key )
+ throws InvalidConfigurationException
+ {
+ String value = props.getProperty( key );
+
+ if ( value == null )
+ {
+ throw new InvalidConfigurationException( key, "Missing required field: " + key );
+ }
+
+ return value;
+ }
+}
\ No newline at end of file
<field>
<name>snapshotsInterval</name>
<version>1.0.0</version>
- <type>String</type>
+ <type>int</type>
<description>
The interval in minutes before updating snapshots if the policy is set to 'interval'.
</description>
<field>
<name>releasesInterval</name>
<version>1.0.0</version>
- <type>String</type>
+ <type>int</type>
<description>
The interval in minutes before updating releases if the policy is set to 'interval'.
</description>
Whether to use the network proxy, if one is configured for the protocol of this repository.
</description>
</field>
+ <field>
+ <name>cacheFailures</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ <description>
+ Whether to cache failures to avoid re-attempting them over the network.
+ </description>
+ </field>
+ <field>
+ <name>hardFail</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ <description>
+ Whether to cause the entire request to fail if attempts to retrieve from this proxy fail.
+ </description>
+ </field>
</fields>
</class>
<class>
--- /dev/null
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed 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.
+ -->
+
--- /dev/null
+################ GLOBAL SETTINGS\r
+# This is where maven-proxy stores files it has downloaded\r
+repo.local.store=target\r
+\r
+#The port to listen on - not used if loaded as a webapp\r
+port=9999\r
+\r
+#This is the base area that all files are loaded from. While it is possible to leave this blank, this behaviour\r
+#is deprecated and will be disabled in version 2.0. There are too many namespace conflicts caused by not using\r
+#a prefix.\r
+#The repository will be shown at http://localhost:9999/repository/\r
+#for the .war loaded into a webapp server, the default prefix is "repository" (edit the web.xml to change)\r
+# As maven doesn't like a trailing slash, this address shouldn't have one either.\r
+prefix=repository\r
+\r
+#This is the simple date format used to display the last modified date while browsing the repository.\r
+lastModifiedDateFormat=yyyy/MM/dd HH:mm:ss\r
+\r
+################ SNAPSHOT HANDLING\r
+#If you want the proxy to look for newer snapshots, set to true\r
+snapshot.update=true\r
+\r
+################ M2 METADATA HANDLING\r
+#If you want the proxy to prevent looking for newer metadata, set to false (default is true)\r
+#metadata.update=false\r
+\r
+################ M2 POM HANDLING\r
+#If you want the proxy to look for newer POMs, set to true (default is false)\r
+pom.update=true\r
+\r
+################ PROMOTION HANDLING\r
+# ***** NOT CURRENTLY IMPLEMENTED *****\r
+#Promotion describes the process by which new artifacts are loaded to global maven-proxy repository. It\r
+# is designed to be used by "higher security installations" that do not want to acquire artifacts from\r
+# remote repositories without approval.\r
+#\r
+#If promotion handling is enabled, then the proxy will not download remote artifacts without permission\r
+# (local repositories with copy=false are considered to be local)\r
+#\r
+#Permission to download is granted via the Promotion menu which will be enabled\r
+# when promotion handling is enabled.\r
+#\r
+#If promotion is false, artifacts are sourced from any repository as per normal.\r
+#\r
+#Promotion and snapshots: If promotion is enabled, snapshots are not downloadable. The concept of using\r
+# a snapshot in a production build (which is primarily what promotion is for) is counterintuitive.\r
+##\r
+promotion=false\r
+\r
+################ WEB INTERFACE\r
+# This defines the absolute URL the server should use to identify itself.\r
+# This can often be determined automatically, but we recommend you specify\r
+# it explicitly to prevent problems during startup.\r
+# The prefix will be added to this for the actual repository\r
+# i.e. proxy available at http://localhost:9999/, repository at http://localhost:9999/repository\r
+serverName=http://localhost:9999\r
+\r
+#If true, the repository can be browsed\r
+browsable=true\r
+\r
+#If true, the repository can be searched\r
+searchable=true\r
+\r
+#Not currently implemented. Will allow webdav access to the repository at some point.\r
+webdav=true\r
+\r
+#Stylesheet - if configured, will override the default stylesheet shipped with maven-proxy - absolute URLs only\r
+#eg. /maven-proxy/style.css, http://www.example.com/style.css\r
+stylesheet=/maven-proxy/style.css\r
+\r
+#bgColor / bgColorHighlight are replaced in the built in stylesheet to produce a simple color scheme.\r
+#If a stylesheet is set, these are not used.\r
+bgColor=#14B\r
+bgColorHighlight=#94B\r
+\r
+#rowColor / rowColorHighlight are replaced in the built in stylesheet to produce a simple color scheme.\r
+#If a stylesheet is set, these are not used.\r
+rowColor=#CCF\r
+rowColorHighlight=#DDF\r
+\r
+\r
+################ PROXIES\r
+#This is just a hack, it should auto discover them\r
+proxy.list=one,two,three\r
+\r
+#Unauthenticated proxy\r
+proxy.one.host=proxy1.example.com\r
+proxy.one.port=3128\r
+\r
+#Authenticated proxy\r
+proxy.two.host=proxy2.example.org\r
+proxy.two.port=80\r
+proxy.two.username=username2\r
+proxy.two.password=password2\r
+\r
+#Authenticated proxy\r
+proxy.three.host=proxy3.example.net\r
+proxy.three.port=3129\r
+proxy.three.username=username3\r
+proxy.three.password=password3\r
+\r
+\r
+################# REPOSITORIES\r
+#This is not just a hack, it specifies the order repositories should be checked\r
+#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/"\r
+repo.list=local-repo,www-ibiblio-org,dist-codehaus-org,private-example-com\r
+\r
+#local-store\r
+# The local store represents a location that local jars you host can be located.\r
+# This could also be achieved by having a local http repository, but this is less cumbersome\r
+repo.local-repo.url=file://target\r
+repo.local-repo.description=Super Secret Custom Repository\r
+#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos\r
+repo.local-repo.copy=false\r
+#If hardfail is true, any unexpected errors from the repository will cause\r
+#the client download to fail (typically with a 500 error)\r
+repo.local-repo.hardfail=true\r
+#Don't cache a file repository\r
+repo.local-repo.cache.period=0\r
+\r
+\r
+#www.ibiblio.org\r
+repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2\r
+repo.www-ibiblio-org.description=www.ibiblio.org\r
+repo.www-ibiblio-org.proxy=one\r
+repo.www-ibiblio-org.hardfail=true\r
+#Cache this repository for 1 hour\r
+repo.www-ibiblio-org.cache.period=3600\r
+repo.www-ibiblio-org.cache.failures=true\r
+\r
+#dist.codehaus.org\r
+repo.dist-codehaus-org.url=http://dist.codehaus.org\r
+repo.dist-codehaus-org.proxy=two\r
+repo.dist-codehaus-org.hardfail=false\r
+repo.dist-codehaus-org.cache.period=3600\r
+repo.dist-codehaus-org.cache.failures=true\r
+\r
+#private.example.com\r
+repo.private-example-com.url=http://private.example.com/internal\r
+repo.private-example-com.description=Commercial In Confidence Repository\r
+repo.private-example-com.username=username1\r
+repo.private-example-com.password=password1\r
+repo.private-example-com.proxy=three\r
+repo.private-example-com.cache.period=3600\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed 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.
+ -->
+
+<configuration>
+ <repositories>
+ <repository>
+ <directory>managed-repository</directory>
+ <id>local</id>
+ <name>local</name>
+ </repository>
+ </repositories>
+ <proxiedRepositories>
+ <proxiedRepository>
+ <url>http://www.ibiblio.org/maven2/</url>
+ <managedRepository>local</managedRepository>
+ <snapshotsInterval></snapshotsInterval>
+ <releasesInterval></releasesInterval>
+ <useNetworkProxy>true</useNetworkProxy>
+ <id>ibiblio</id>
+ <name>Ibiblio</name>
+ </proxiedRepository>
+ </proxiedRepositories>
+ <syncedRepositories>
+ <syncedRepository>
+ <id>apache</id>
+ <name>ASF</name>
+ <cronExpression>0 0 * * * ?</cronExpression>
+ <managedRepository>local</managedRepository>
+ <method>rsync</method>
+ <properties>
+ <rsyncHost>host</rsyncHost>
+ <rsyncMethod>ssh</rsyncMethod>
+ </properties>
+ </syncedRepository>
+ </syncedRepositories>
+ <localRepository>local-repository</localRepository>
+ <indexPath>.index</indexPath>
+</configuration>
--- /dev/null
+package org.apache.maven.repository.configuration;
+
+import org.codehaus.plexus.PlexusTestCase;
+import org.easymock.MockControl;
+
+import java.io.File;
+import java.util.Properties;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/**
+ * Test the configuration store.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ConfigurationStoreTest
+ extends PlexusTestCase
+{
+ public void testInvalidFile()
+ throws Exception
+ {
+ ConfigurationStore configurationStore = (ConfigurationStore) lookup( ConfigurationStore.ROLE, "invalid-file" );
+
+ Configuration configuration = configurationStore.getConfigurationFromStore();
+
+ // check default configuration
+ assertNotNull( "check configuration returned", configuration );
+ assertEquals( "check configuration has default elements", "0 0 * * * ?",
+ configuration.getIndexerCronExpression() );
+ assertNull( "check configuration has default elements", configuration.getIndexPath() );
+ assertTrue( "check configuration has default elements", configuration.getRepositories().isEmpty() );
+ }
+
+ public void testCorruptFile()
+ throws Exception
+ {
+ ConfigurationStore configurationStore = (ConfigurationStore) lookup( ConfigurationStore.ROLE, "corrupt-file" );
+
+ try
+ {
+ configurationStore.getConfigurationFromStore();
+ fail( "Configuration should not have succeeded" );
+ }
+ catch ( ConfigurationStoreException e )
+ {
+ // expected
+ assertTrue( true );
+ }
+ }
+
+ public void testGetConfiguration()
+ throws Exception
+ {
+ ConfigurationStore configurationStore = (ConfigurationStore) lookup( ConfigurationStore.ROLE, "default" );
+
+ Configuration configuration = configurationStore.getConfigurationFromStore();
+
+ assertEquals( "check indexPath", ".index", configuration.getIndexPath() );
+ assertEquals( "check localRepository", "local-repository", configuration.getLocalRepository() );
+
+ assertEquals( "check managed repositories", 1, configuration.getRepositories().size() );
+ RepositoryConfiguration repository =
+ (RepositoryConfiguration) configuration.getRepositories().iterator().next();
+
+ assertEquals( "check managed repositories", "managed-repository", repository.getDirectory() );
+ assertEquals( "check managed repositories", "local", repository.getName() );
+ assertEquals( "check managed repositories", "local", repository.getId() );
+ assertEquals( "check managed repositories", "default", repository.getLayout() );
+ assertTrue( "check managed repositories", repository.isIndexed() );
+
+ assertEquals( "check proxied repositories", 1, configuration.getProxiedRepositories().size() );
+ ProxiedRepositoryConfiguration proxiedRepository =
+ (ProxiedRepositoryConfiguration) configuration.getProxiedRepositories().iterator().next();
+
+ assertEquals( "check proxied repositories", "local", proxiedRepository.getManagedRepository() );
+ assertEquals( "check proxied repositories", "http://www.ibiblio.org/maven2/", proxiedRepository.getUrl() );
+ assertEquals( "check proxied repositories", "ibiblio", proxiedRepository.getId() );
+ assertEquals( "check proxied repositories", "Ibiblio", proxiedRepository.getName() );
+ assertEquals( "check proxied repositories", 0, proxiedRepository.getSnapshotsInterval() );
+ assertEquals( "check proxied repositories", 0, proxiedRepository.getReleasesInterval() );
+ assertTrue( "check proxied repositories", proxiedRepository.isUseNetworkProxy() );
+
+ assertEquals( "check synced repositories", 1, configuration.getSyncedRepositories().size() );
+ SyncedRepositoryConfiguration syncedRepository =
+ (SyncedRepositoryConfiguration) configuration.getSyncedRepositories().iterator().next();
+
+ assertEquals( "check synced repositories", "local", syncedRepository.getManagedRepository() );
+ assertEquals( "check synced repositories", "apache", syncedRepository.getId() );
+ assertEquals( "check synced repositories", "ASF", syncedRepository.getName() );
+ assertEquals( "check synced repositories", "0 0 * * * ?", syncedRepository.getCronExpression() );
+ assertEquals( "check synced repositories", "rsync", syncedRepository.getMethod() );
+ Properties properties = new Properties();
+ properties.setProperty( "rsyncHost", "host" );
+ properties.setProperty( "rsyncMethod", "ssh" );
+ assertEquals( "check synced repositories", properties, syncedRepository.getProperties() );
+ }
+
+ public void testStoreConfiguration()
+ throws Exception
+ {
+ ConfigurationStore configurationStore = (ConfigurationStore) lookup( ConfigurationStore.ROLE, "save-file" );
+
+ Configuration configuration = new Configuration();
+ configuration.setIndexPath( "index-path" );
+
+ File file = getTestFile( "target/test/test-file.xml" );
+ file.delete();
+ assertFalse( file.exists() );
+
+ configurationStore.storeConfiguration( configuration );
+
+ assertTrue( "Check file exists", file.exists() );
+
+ // read it back
+ configuration = configurationStore.getConfigurationFromStore();
+ assertEquals( "check value", "index-path", configuration.getIndexPath() );
+ }
+
+ public void testChangeListeners()
+ throws Exception
+ {
+ ConfigurationStore configurationStore = (ConfigurationStore) lookup( ConfigurationStore.ROLE, "save-file" );
+
+ MockControl control = MockControl.createControl( ConfigurationChangeListener.class );
+ ConfigurationChangeListener mock = (ConfigurationChangeListener) control.getMock();
+ configurationStore.addChangeListener( mock );
+
+ Configuration configuration = new Configuration();
+ mock.notifyOfConfigurationChange( configuration );
+ control.replay();
+
+ configurationStore.storeConfiguration( configuration );
+
+ control.verify();
+ }
+}
--- /dev/null
+package org.apache.maven.repository.configuration;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.codehaus.plexus.PlexusTestCase;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author Edwin Punzalan
+ */
+public class MavenProxyPropertyLoaderTest
+ extends PlexusTestCase
+{
+ private static final int DEFAULT_CACHE_PERIOD = 3600;
+
+ private MavenProxyPropertyLoader loader;
+
+ public void testLoadValidMavenProxyConfiguration()
+ throws IOException, InvalidConfigurationException
+ {
+ File confFile = getTestFile( "src/test/conf/maven-proxy-complete.conf" );
+
+ Configuration configuration = new Configuration();
+ Proxy proxy = new Proxy();
+ proxy.setHost( "original-host" );
+ configuration.setProxy( proxy ); // overwritten
+ configuration.setIndexPath( "index-path" ); // existing value
+
+ loader.load( new FileInputStream( confFile ), configuration );
+
+ List list = configuration.getRepositories();
+ assertEquals( "check single managed repository", 1, list.size() );
+ RepositoryConfiguration managedRepository = (RepositoryConfiguration) list.iterator().next();
+ assertEquals( "cache path changed", "target", managedRepository.getDirectory() );
+
+ assertEquals( "Count repositories", 4, configuration.getProxiedRepositories().size() );
+
+ list = configuration.getProxiedRepositories();
+ ProxiedRepositoryConfiguration repo = (ProxiedRepositoryConfiguration) list.get( 0 );
+ assertEquals( "Repository name not as expected", "local-repo", repo.getId() );
+ assertEquals( "Repository url does not match its name", "file://target", repo.getUrl() );
+ assertEquals( "Repository cache period check failed", 0, repo.getSnapshotsInterval() );
+ assertFalse( "Repository failure caching check failed", repo.isCacheFailures() );
+
+ repo = (ProxiedRepositoryConfiguration) list.get( 1 );
+ assertEquals( "Repository name not as expected", "www-ibiblio-org", repo.getId() );
+ assertEquals( "Repository url does not match its name", "http://www.ibiblio.org/maven2", repo.getUrl() );
+ assertEquals( "Repository cache period check failed", DEFAULT_CACHE_PERIOD, repo.getSnapshotsInterval() );
+ assertTrue( "Repository failure caching check failed", repo.isCacheFailures() );
+
+ repo = (ProxiedRepositoryConfiguration) list.get( 2 );
+ assertEquals( "Repository name not as expected", "dist-codehaus-org", repo.getId() );
+ assertEquals( "Repository url does not match its name", "http://dist.codehaus.org", repo.getUrl() );
+ assertEquals( "Repository cache period check failed", DEFAULT_CACHE_PERIOD, repo.getSnapshotsInterval() );
+ assertTrue( "Repository failure caching check failed", repo.isCacheFailures() );
+
+ repo = (ProxiedRepositoryConfiguration) list.get( 3 );
+ assertEquals( "Repository name not as expected", "private-example-com", repo.getId() );
+ assertEquals( "Repository url does not match its name", "http://private.example.com/internal", repo.getUrl() );
+ assertEquals( "Repository cache period check failed", DEFAULT_CACHE_PERIOD, repo.getSnapshotsInterval() );
+ assertFalse( "Repository failure caching check failed", repo.isCacheFailures() );
+ }
+
+ public void testInvalidConfiguration()
+ {
+ Configuration configuration = new Configuration();
+ try
+ {
+ loader.load( new Properties(), configuration );
+ fail( "Incomplete config should have failed" );
+ }
+ catch ( InvalidConfigurationException e )
+ {
+ assertTrue( true );
+ }
+ }
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ loader = new MavenProxyPropertyLoader();
+ }
+}
--- /dev/null
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed 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.
+ -->
+
+<component-set>
+ <components>
+ <component>
+ <role>org.apache.maven.repository.configuration.ConfigurationStore</role>
+ <role-hint>default</role-hint>
+ <implementation>org.apache.maven.repository.configuration.DefaultConfigurationStore</implementation>
+ <configuration>
+ <file>${basedir}/src/test/conf/repository-manager.xml</file>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.repository.configuration.ConfigurationStore</role>
+ <role-hint>corrupt-file</role-hint>
+ <implementation>org.apache.maven.repository.configuration.DefaultConfigurationStore</implementation>
+ <configuration>
+ <file>${basedir}/src/test/conf/corrupt.xml</file>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.repository.configuration.ConfigurationStore</role>
+ <role-hint>invalid-file</role-hint>
+ <implementation>org.apache.maven.repository.configuration.DefaultConfigurationStore</implementation>
+ <configuration>
+ <file>${basedir}/src/test/conf/nada.txt</file>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.repository.configuration.ConfigurationStore</role>
+ <role-hint>save-file</role-hint>
+ <implementation>org.apache.maven.repository.configuration.DefaultConfigurationStore</implementation>
+ <configuration>
+ <file>${basedir}/target/test/test-file.xml</file>
+ </configuration>
+ </component>
+ </components>
+</component-set>
<groupId>org.apache.maven.repository</groupId>
<artifactId>maven-repository-discovery</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.maven.repository</groupId>
+ <artifactId>maven-repository-proxy</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.maven.repository</groupId>
<artifactId>maven-repository-reports-standard</artifactId>
<artifactId>plexus-quartz</artifactId>
<version>1.0-alpha-2</version>
</dependency>
- <!-- Testing -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
* @return the local artifact repository
*/
ArtifactRepository createLocalRepository( Configuration configuration );
+
+ /**
+ * Create an artifact repository from the given proxy repository configuration.
+ *
+ * @param configuration the configuration
+ * @return the artifact repository
+ */
+ ArtifactRepository createProxiedRepository( ProxiedRepositoryConfiguration configuration );
+
+ /**
+ * Create artifact repositories from the given proxy repository configurations.
+ *
+ * @param configuration the configuration containing the repositories
+ * @return the artifact repositories
+ */
+ List createProxiedRepositories( Configuration configuration );
}
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import java.io.File;
return repoFactory.createArtifactRepository( configuration.getId(), repoDir, layout, null, null );
}
+ public ArtifactRepository createProxiedRepository( ProxiedRepositoryConfiguration configuration )
+ {
+ boolean enabled = isEnabled( configuration.getSnapshotsPolicy() );
+ String updatePolicy =
+ getUpdatePolicy( configuration.getSnapshotsPolicy(), configuration.getSnapshotsInterval() );
+ ArtifactRepositoryPolicy snapshotsPolicy =
+ new ArtifactRepositoryPolicy( enabled, updatePolicy, ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
+
+ enabled = isEnabled( configuration.getReleasesPolicy() );
+ updatePolicy = getUpdatePolicy( configuration.getReleasesPolicy(), configuration.getReleasesInterval() );
+ ArtifactRepositoryPolicy releasesPolicy =
+ new ArtifactRepositoryPolicy( enabled, updatePolicy, ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
+
+ ArtifactRepositoryLayout layout = (ArtifactRepositoryLayout) repositoryLayouts.get( configuration.getLayout() );
+ return repoFactory.createArtifactRepository( configuration.getId(), configuration.getUrl(), layout,
+ snapshotsPolicy, releasesPolicy );
+ }
+
public List createRepositories( Configuration configuration )
{
- List repositories = new ArrayList( configuration.getRepositories().size() );
+ List managedRepositories = configuration.getRepositories();
+ List repositories = new ArrayList( managedRepositories.size() );
- for ( Iterator i = configuration.getRepositories().iterator(); i.hasNext(); )
+ for ( Iterator i = managedRepositories.iterator(); i.hasNext(); )
{
repositories.add( createRepository( (RepositoryConfiguration) i.next() ) );
}
return repositories;
}
+ public List createProxiedRepositories( Configuration configuration )
+ {
+ List proxiedRepositories = configuration.getProxiedRepositories();
+ List repositories = new ArrayList( proxiedRepositories.size() );
+
+ for ( Iterator i = proxiedRepositories.iterator(); i.hasNext(); )
+ {
+ repositories.add( createProxiedRepository( (ProxiedRepositoryConfiguration) i.next() ) );
+ }
+
+ return repositories;
+ }
+
public ArtifactRepository createLocalRepository( Configuration configuration )
{
ArtifactRepositoryLayout layout = (ArtifactRepositoryLayout) repositoryLayouts.get( "default" );
localRepository.mkdirs();
return repoFactory.createArtifactRepository( "local", localRepository.toURI().toString(), layout, null, null );
}
+
+ private static String getUpdatePolicy( String policy, int interval )
+ {
+ return "interval".equals( policy ) ? policy + ":" + interval : policy;
+ }
+
+ private static boolean isEnabled( String policy )
+ {
+ return !"disabled".equals( policy );
+ }
}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.artifact.repository.ArtifactRepository;
+import org.apache.maven.repository.configuration.Configuration;
+import org.apache.maven.repository.configuration.ConfigurationStore;
+import org.apache.maven.repository.configuration.ConfigurationStoreException;
+import org.apache.maven.repository.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.repository.configuration.ProxiedRepositoryConfiguration;
+import org.apache.maven.repository.configuration.Proxy;
+import org.apache.maven.repository.configuration.RepositoryConfiguration;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Default implementation of the proxy manager that bridges the repository configuration classes to the proxy API.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo we should be able to configure "views" that sit in front of this (ie, prefix = /legacy, appears as layout maven-1.x, path gets translated before being passed on)
+ * @plexus.component
+ */
+public class DefaultProxyManager
+ implements ProxyManager
+{
+ /**
+ * @plexus.requirement
+ */
+ private ConfigurationStore configurationStore;
+
+ /**
+ * @plexus.requirement
+ */
+ private ProxyRequestHandler requestHandler;
+
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repositoryFactory;
+
+ /**
+ * The proxy handlers for each managed repository.
+ */
+ private Map/*<String,ProxiedRepositoryGroup>*/ proxyGroups;
+
+ public File get( String path )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ assert path.startsWith( "/" );
+
+ Map groups = getProxyRepositoryHandlers();
+
+ String id = parseRepositoryId( path, groups );
+
+ String repositoryPath = path.substring( id.length() + 2 );
+
+ ProxiedRepositoryGroup proxyGroup = (ProxiedRepositoryGroup) groups.get( id );
+
+ return requestHandler.get( repositoryPath, proxyGroup.getProxiedRepositories(),
+ proxyGroup.getManagedRepository(), proxyGroup.getWagonProxy() );
+ }
+
+ public File getAlways( String path )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ assert path.startsWith( "/" );
+
+ Map groups = getProxyRepositoryHandlers();
+
+ String id = parseRepositoryId( path, groups );
+
+ String repositoryPath = path.substring( id.length() + 2 );
+
+ ProxiedRepositoryGroup proxyGroup = (ProxiedRepositoryGroup) groups.get( id );
+
+ return requestHandler.getAlways( repositoryPath, proxyGroup.getProxiedRepositories(),
+ proxyGroup.getManagedRepository(), proxyGroup.getWagonProxy() );
+ }
+
+ private Configuration getConfiguration()
+ throws ProxyException
+ {
+ Configuration configuration;
+ try
+ {
+ configuration = configurationStore.getConfigurationFromStore();
+ }
+ catch ( ConfigurationStoreException e )
+ {
+ throw new ProxyException( "Error reading configuration, unable to proxy any requests: " + e.getMessage(),
+ e );
+ }
+ return configuration;
+ }
+
+ private Map getProxyRepositoryHandlers()
+ throws ProxyException
+ {
+ if ( proxyGroups == null )
+ {
+ Map groups = new HashMap();
+
+ Configuration configuration = getConfiguration();
+
+ ProxyInfo wagonProxy = createWagonProxy( configuration.getProxy() );
+
+ for ( Iterator i = configuration.getRepositories().iterator(); i.hasNext(); )
+ {
+ RepositoryConfiguration repository = (RepositoryConfiguration) i.next();
+ ArtifactRepository managedRepository = repositoryFactory.createRepository( repository );
+ List proxiedRepositories = getProxiedRepositoriesForManagedRepository(
+ configuration.getProxiedRepositories(), repository.getId() );
+
+ groups.put( repository.getId(),
+ new ProxiedRepositoryGroup( proxiedRepositories, managedRepository, wagonProxy ) );
+ }
+
+ proxyGroups = groups;
+ }
+ return proxyGroups;
+ }
+
+ private List getProxiedRepositoriesForManagedRepository( List proxiedRepositories, String id )
+ {
+ List repositories = new ArrayList();
+ for ( Iterator i = proxiedRepositories.iterator(); i.hasNext(); )
+ {
+ ProxiedRepositoryConfiguration config = (ProxiedRepositoryConfiguration) i.next();
+
+ if ( config.getManagedRepository().equals( id ) )
+ {
+ repositories.add( repositoryFactory.createProxiedRepository( config ) );
+ }
+ }
+ return repositories;
+ }
+
+ private static String parseRepositoryId( String path, Map handlers )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ for ( Iterator i = handlers.keySet().iterator(); i.hasNext(); )
+ {
+ String id = (String) i.next();
+
+ if ( path.startsWith( "/" + id + "/" ) )
+ {
+ return id;
+ }
+ }
+ throw new ResourceDoesNotExistException( "No repositories exist under the path: " + path );
+ }
+
+ private static ProxyInfo createWagonProxy( Proxy proxy )
+ {
+ ProxyInfo proxyInfo = null;
+ if ( proxy != null && !StringUtils.isEmpty( proxy.getHost() ) )
+ {
+ proxyInfo = new ProxyInfo();
+ proxyInfo.setHost( proxy.getHost() );
+ proxyInfo.setPort( proxy.getPort() );
+ proxyInfo.setUserName( proxy.getUsername() );
+ proxyInfo.setPassword( proxy.getPassword() );
+ proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
+ proxyInfo.setType( proxy.getProtocol() );
+ }
+ return proxyInfo;
+ }
+}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.artifact.repository.ArtifactRepository;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A set of information to store for a group of proxies.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ProxiedRepositoryGroup
+{
+
+ /**
+ * The locally managed repository that caches proxied artifacts.
+ */
+ private ArtifactRepository managedRepository;
+
+ /**
+ * The remote repositories that are being proxied.
+ */
+ private List/*<ArtifactRepository>*/ proxiedRepositories;
+
+ /**
+ * A wagon proxy to communicate to the proxy repository over a proxy (eg, http proxy)... TerminologyOverflowException
+ */
+ private final ProxyInfo wagonProxy;
+
+ /**
+ * Constructor.
+ *
+ * @param proxiedRepositories the proxied repository
+ * @param managedRepository the locally managed repository
+ * @param wagonProxy the network proxy to use
+ */
+ public ProxiedRepositoryGroup( List/*<ArtifactRepository>*/ proxiedRepositories,
+ ArtifactRepository managedRepository, ProxyInfo wagonProxy )
+ {
+ this.proxiedRepositories = proxiedRepositories;
+
+ this.managedRepository = managedRepository;
+
+ this.wagonProxy = wagonProxy;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param proxiedRepositories the proxied repository
+ * @param managedRepository the locally managed repository
+ */
+ public ProxiedRepositoryGroup( List/*<ArtifactRepository>*/ proxiedRepositories,
+ ArtifactRepository managedRepository )
+ {
+ this( proxiedRepositories, managedRepository, null );
+ }
+
+ public ArtifactRepository getManagedRepository()
+ {
+ return managedRepository;
+ }
+
+ public List getProxiedRepositories()
+ {
+ return proxiedRepositories;
+ }
+
+ public ProxyInfo getWagonProxy()
+ {
+ return wagonProxy;
+ }
+}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.wagon.ResourceDoesNotExistException;
+
+import java.io.File;
+
+/**
+ * Repository proxying component. This component will take requests for a given path within a managed repository
+ * and if it is not found or expired, will look in the specified proxy repositories.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public interface ProxyManager
+{
+ /** The Plexus role for the component. */
+ String ROLE = ProxyManager.class.getName();
+
+ /**
+ * Used to retrieve a cached path or retrieve one if the cache does not contain it yet.
+ *
+ * @param path the expected repository path
+ * @return File object referencing the requested path in the cache
+ * @throws ProxyException when an exception occurred during the retrieval of the requested path
+ * @throws org.apache.maven.wagon.ResourceDoesNotExistException when the requested object can't be found in any of the
+ * configured repositories
+ */
+ File get( String path )
+ throws ProxyException, ResourceDoesNotExistException;
+
+ /**
+ * Used to force remote download of the requested path from any the configured repositories. This method will
+ * only bypass the cache for searching but the requested path will still be cached.
+ *
+ * @param path the expected repository path
+ * @return File object referencing the requested path in the cache
+ * @throws ProxyException when an exception occurred during the retrieval of the requested path
+ * @throws ResourceDoesNotExistException when the requested object can't be found in any of the
+ * configured repositories
+ */
+ File getAlways( String path )
+ throws ProxyException, ResourceDoesNotExistException;
+}
}
catch ( ParseException e )
{
- throw new InvalidConfigurationException( "discoveryCronExpression", "Invalid cron expression", e );
+ throw new InvalidConfigurationException( "indexerCronExpression", "Invalid cron expression", e );
}
catch ( SchedulerException e )
{
<artifactId>maven-repository-metadata</artifactId>
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ <configuration>
+ <check>
+ <!-- TODO: increase coverage -->
+ <totalLineRate>80</totalLineRate>
+ <totalBranchRate>80</totalBranchRate>
+ </check>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
<groupId>org.apache.maven</groupId>\r
<artifactId>maven-artifact</artifactId>\r
</dependency>\r
- <dependency>\r
- <groupId>org.apache.maven</groupId>\r
- <artifactId>maven-artifact-manager</artifactId>\r
- </dependency>\r
<dependency>\r
<groupId>org.apache.maven.wagon</groupId>\r
<artifactId>wagon-file</artifactId>\r
<artifactId>cobertura-maven-plugin</artifactId>\r
<configuration>\r
<check>\r
- <!-- TODO: increase coverage -->\r
+ <!-- TODO!: increase coverage\r
<totalLineRate>60</totalLineRate>\r
- <totalBranchRate>70</totalBranchRate>\r
+ <totalBranchRate>70</totalBranchRate> -->\r
</check>\r
</configuration>\r
</plugin>\r
+++ /dev/null
-package org.apache.maven.repository.proxy;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.artifact.Artifact;
-import org.apache.maven.artifact.manager.ChecksumFailedException;
-import org.apache.maven.artifact.manager.WagonManager;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-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.repository.discovery.ArtifactDiscoverer;
-import org.apache.maven.repository.discovery.DiscovererException;
-import org.apache.maven.repository.proxy.configuration.ProxyConfiguration;
-import org.apache.maven.repository.proxy.repository.ProxyRepository;
-import org.apache.maven.wagon.ConnectionException;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.TransferFailedException;
-import org.apache.maven.wagon.UnsupportedProtocolException;
-import org.apache.maven.wagon.Wagon;
-import org.apache.maven.wagon.authentication.AuthenticationException;
-import org.apache.maven.wagon.authorization.AuthorizationException;
-import org.apache.maven.wagon.observers.ChecksumObserver;
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-import org.codehaus.plexus.util.FileUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Edwin Punzalan
- * @plexus.component role="org.apache.maven.repository.proxy.ProxyManager"
- * @todo too much of wagon manager is reproduced here because checksums need to be downloaded separately - is that necessary?
- * @todo this isn't reusing the parts of artifact resolver that handles snapshots - should this be more artifact based than file-based?
- * @todo currently, cache must be in the same layout as the request, which prohibits any mapping
- */
-public class DefaultProxyManager
- extends AbstractLogEnabled
- implements ProxyManager
-{
- /**
- * @plexus.requirement
- */
- private WagonManager wagonManager;
-
- /**
- * @plexus.requirement
- */
- private ArtifactRepositoryFactory repositoryFactory;
-
- /**
- * @plexus.requirement role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout"
- */
- private Map repositoryLayoutMap;
-
- private Map failuresCache = new HashMap();
-
- private ProxyConfiguration config;
-
- private static final int MS_PER_SEC = 1000;
-
- /**
- * @plexus.requirement role-hint="default"
- * @todo use a map, and have priorities in them
- */
- private ArtifactDiscoverer defaultArtifactDiscoverer;
-
- /**
- * @plexus.requirement role-hint="legacy"
- */
- private ArtifactDiscoverer legacyArtifactDiscoverer;
-
- public void setConfiguration( ProxyConfiguration config )
- {
- this.config = config;
- }
-
- /**
- * @see org.apache.maven.repository.proxy.ProxyManager#get(String)
- */
- public File get( String path )
- throws ProxyException, ResourceDoesNotExistException
- {
- checkConfiguration();
-
- //@todo use wagonManager for cache use file:// as URL
- String cachePath = config.getRepositoryCachePath();
- File cachedFile = new File( cachePath, path );
- if ( !cachedFile.exists() )
- {
- cachedFile = getAlways( path );
- }
- return cachedFile;
- }
-
- /**
- * @see org.apache.maven.repository.proxy.ProxyManager#getAlways(String)
- */
- public File getAlways( String path )
- throws ProxyException, ResourceDoesNotExistException
- {
- checkConfiguration();
-
- return getRemoteFile( path, config.getRepositories() );
- }
-
- /**
- * Tries to download the path from the list of repositories.
- *
- * @param path the request path to download from the proxy or repositories
- * @param repositories list of ArtifactRepositories to download the path from
- * @return File object that points to the downloaded file
- * @throws ProxyException
- * @throws ResourceDoesNotExistException
- */
- private File getRemoteFile( String path, List repositories )
- throws ProxyException, ResourceDoesNotExistException
- {
- checkConfiguration();
-
- File remoteFile;
- if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) )
- {
- remoteFile = getRepositoryFile( path, repositories, false );
- }
- else if ( path.endsWith( "maven-metadata.xml" ) )
- {
- remoteFile = getRepositoryFile( path, repositories );
- }
- else
- {
- Artifact artifact = null;
- try
- {
- artifact = defaultArtifactDiscoverer.buildArtifact( path );
- }
- catch ( DiscovererException e )
- {
- getLogger().debug( "Failed to build artifact using default layout with message: " + e.getMessage() );
- }
-
- if ( artifact == null )
- {
- try
- {
- artifact = legacyArtifactDiscoverer.buildArtifact( path );
- }
- catch ( DiscovererException e )
- {
- getLogger().debug( "Failed to build artifact using legacy layout with message: " + e.getMessage() );
- }
- }
-
- if ( artifact != null )
- {
- getArtifact( artifact, repositories );
-
- remoteFile = artifact.getFile();
- }
- else
- {
- //try downloading non-maven standard files
- remoteFile = getRepositoryFile( path, repositories );
- }
- }
-
- return remoteFile;
- }
-
- /**
- * Used to download an artifact object from the remote repositories.
- *
- * @param artifact the artifact object to be downloaded from a remote repository
- * @param repositories the list of ProxyRepositories to retrieve the artifact from
- * @throws ProxyException when an error occurred during retrieval of the requested artifact
- * @throws ResourceDoesNotExistException when the requested artifact cannot be found in any of the
- * configured repositories
- */
- private void getArtifact( Artifact artifact, List repositories )
- throws ResourceDoesNotExistException, ProxyException
- {
- ArtifactRepository repoCache = getRepositoryCache();
-
- File artifactFile = new File( repoCache.getBasedir(), repoCache.pathOf( artifact ) );
- artifact.setFile( artifactFile );
-
- if ( !artifactFile.exists() )
- {
- for ( Iterator iter = repositories.iterator(); iter.hasNext(); )
- {
- ProxyRepository repository = (ProxyRepository) iter.next();
- try
- {
- if ( checkIfFailureCached( repository.pathOf( artifact ), repository ) )
- {
- getLogger().debug(
- "Skipping repository " + repository.getKey() + " for a cached path failure." );
- }
- else
- {
- wagonManager.getArtifact( artifact, repository );
- }
- }
- catch ( TransferFailedException e )
- {
- if ( repository.isHardfail() )
- {
- throw new ProxyException( e.getMessage(), e );
- }
- }
- catch ( ResourceDoesNotExistException e )
- {
- //handle the failure cache then throw exception as expected
- doCacheFailure( repository.pathOf( artifact ), repository );
-
- throw e;
- }
- }
- }
- }
-
- private void doCacheFailure( String path, ProxyRepository repository )
- {
- if ( repository.isCacheFailures() )
- {
- String key = repository.getKey();
- if ( !failuresCache.containsKey( key ) )
- {
- failuresCache.put( key, new ArrayList() );
- }
-
- List failureCache = (List) failuresCache.get( key );
- if ( !failureCache.contains( path ) )
- {
- failureCache.add( path );
- }
- }
- }
-
- private boolean checkIfFailureCached( String path, ProxyRepository repository )
- {
- boolean pathAlreadyFailed = false;
-
- if ( repository.isCacheFailures() )
- {
- String key = repository.getKey();
-
- if ( failuresCache.containsKey( key ) )
- {
- List failureCache = (List) failuresCache.get( key );
-
- if ( failureCache.contains( path ) )
- {
- pathAlreadyFailed = true;
- }
- }
- }
-
- return pathAlreadyFailed;
- }
-
- private ArtifactRepositoryLayout getLayout()
- throws ProxyException
- {
- String configLayout = config.getLayout();
-
- if ( !repositoryLayoutMap.containsKey( configLayout ) )
- {
- throw new ProxyException( "Unable to find a proxy repository layout for " + configLayout );
- }
-
- return (ArtifactRepositoryLayout) repositoryLayoutMap.get( configLayout );
- }
-
- private ArtifactRepository getRepositoryCache()
- throws ProxyException
- {
- return repositoryFactory.createArtifactRepository( "local-cache", getRepositoryCacheURL().toString(),
- getLayout(), getSnapshotsPolicy(), getReleasesPolicy() );
- }
-
- private ArtifactRepositoryPolicy getReleasesPolicy()
- {
- return config.getCacheReleasePolicy();
- }
-
- private ArtifactRepositoryPolicy getSnapshotsPolicy()
- {
- return config.getCacheSnapshotPolicy();
- }
-
- public URL getRepositoryCacheURL()
- throws ProxyException
- {
- URL url;
-
- try
- {
- url = new File( config.getRepositoryCachePath() ).toURL();
- }
- catch ( MalformedURLException e )
- {
- throw new ProxyException( "Unable to create cache URL from: " + config.getRepositoryCachePath(), e );
- }
-
- return url;
- }
-
- /**
- * Used to retrieve a remote file from the remote repositories. This method is used only when the requested
- * path cannot be resolved into a repository object, for example, an Artifact.
- *
- * @param path the remote path to use to search for the requested file
- * @param repositories the list of repositories to retrieve the file from
- * @return File object representing the remote file in the repository cache
- * @throws ResourceDoesNotExistException when the requested path cannot be found in any of the configured
- * repositories.
- * @throws ProxyException when an error occurred during the retrieval of the requested path
- */
- private File getRepositoryFile( String path, List repositories )
- throws ResourceDoesNotExistException, ProxyException
- {
- return getRepositoryFile( path, repositories, true );
- }
-
- /**
- * Used to retrieve a remote file from the remote repositories. This method is used only when the requested
- * path cannot be resolved into a repository object, for example, an Artifact.
- *
- * @param path the remote path to use to search for the requested file
- * @param repositories the list of repositories to retrieve the file from
- * @param useChecksum forces the download to whether use a checksum (if present in the remote repository) or not
- * @return File object representing the remote file in the repository cache
- * @throws ResourceDoesNotExistException when the requested path cannot be found in any of the configured
- * repositories.
- * @throws ProxyException when an error occurred during the retrieval of the requested path
- */
- private File getRepositoryFile( String path, List repositories, boolean useChecksum )
- throws ResourceDoesNotExistException, ProxyException
- {
- ArtifactRepository cache = getRepositoryCache();
- File target = new File( cache.getBasedir(), path );
-
- for ( Iterator repos = repositories.iterator(); repos.hasNext(); )
- {
- ProxyRepository repository = (ProxyRepository) repos.next();
-
- if ( checkIfFailureCached( path, repository ) )
- {
- getLogger().debug( "Skipping repository " + repository.getKey() + " for a cached path failure." );
- }
- else
- {
- getFromRepository( target, path, repository, useChecksum );
- }
- }
-
- if ( !target.exists() )
- {
- throw new ResourceDoesNotExistException( "Could not find " + path + " in any of the repositories." );
- }
-
- return target;
- }
-
- private void getFromRepository( File target, String path, ProxyRepository repository, boolean useChecksum )
- throws ProxyException
- {
- boolean connected = false;
- Map checksums = null;
- Wagon wagon = null;
-
- try
- {
- wagon = wagonManager.getWagon( repository.getProtocol() );
-
- //@todo configure wagon (ssh settings, etc)
-
- if ( useChecksum )
- {
- checksums = prepareChecksumListeners( wagon );
- }
-
- connected = connectToRepository( wagon, repository );
- if ( connected )
- {
- File temp = new File( target.getAbsolutePath() + ".tmp" );
- temp.deleteOnExit();
-
- int tries = 0;
- boolean success = true;
-
- do
- {
- tries++;
-
- getLogger().info( "Trying " + path + " from " + repository.getId() + "..." );
-
- if ( !target.exists() )
- {
- wagon.get( path, temp );
- }
- else
- {
- long repoTimestamp = target.lastModified() + repository.getCachePeriod() * MS_PER_SEC;
- wagon.getIfNewer( path, temp, repoTimestamp );
- }
-
- if ( useChecksum )
- {
- success = doChecksumCheck( checksums, path, wagon );
- }
-
- if ( tries > 1 && !success )
- {
- throw new ProxyException( "Checksum failures occurred while downloading " + path );
- }
- }
- while ( !success );
-
- disconnectWagon( wagon );
-
- if ( temp.exists() )
- {
- moveTempToTarget( temp, target );
- }
- }
- //try next repository
- }
- catch ( TransferFailedException e )
- {
- String message = "Skipping repository " + repository.getUrl() + ": " + e.getMessage();
- processRepositoryFailure( repository, message, e );
- }
- catch ( ResourceDoesNotExistException e )
- {
- doCacheFailure( path, repository );
- }
- catch ( AuthorizationException e )
- {
- String message = "Skipping repository " + repository.getUrl() + ": " + e.getMessage();
- processRepositoryFailure( repository, message, e );
- }
- catch ( UnsupportedProtocolException e )
- {
- String message = "Skipping repository " + repository.getUrl() + ": no wagonManager configured " +
- "for protocol " + repository.getProtocol();
- processRepositoryFailure( repository, message, e );
- }
- finally
- {
- if ( wagon != null && checksums != null )
- {
- releaseChecksumListeners( wagon, checksums );
- }
-
- if ( connected )
- {
- disconnectWagon( wagon );
- }
- }
- }
-
- /**
- * Used to add checksum observers as transfer listeners to the wagonManager object
- *
- * @param wagon the wagonManager object to use the checksum with
- * @return map of ChecksumObservers added into the wagonManager transfer listeners
- */
- private Map prepareChecksumListeners( Wagon wagon )
- {
- Map checksums = new HashMap();
- try
- {
- ChecksumObserver checksum = new ChecksumObserver( "SHA-1" );
- wagon.addTransferListener( checksum );
- checksums.put( "sha1", checksum );
-
- checksum = new ChecksumObserver( "MD5" );
- wagon.addTransferListener( checksum );
- checksums.put( "md5", checksum );
- }
- catch ( NoSuchAlgorithmException e )
- {
- getLogger().info( "An error occurred while preparing checksum observers", e );
- }
- return checksums;
- }
-
- /**
- * Used to remove the ChecksumObservers from the wagonManager object
- *
- * @param wagon the wagonManager object to remote the ChecksumObservers from
- * @param checksumMap the map representing the list of ChecksumObservers added to the wagonManager object
- */
- private void releaseChecksumListeners( Wagon wagon, Map checksumMap )
- {
- for ( Iterator checksums = checksumMap.values().iterator(); checksums.hasNext(); )
- {
- ChecksumObserver listener = (ChecksumObserver) checksums.next();
- wagon.removeTransferListener( listener );
- }
- }
-
- /**
- * Used to request the wagonManager object to connect to a repository
- *
- * @param wagon the wagonManager object that will be used to connect to the repository
- * @param repository the repository object to connect the wagonManager to
- * @return true when the wagonManager is able to connect to the repository
- */
- private boolean connectToRepository( Wagon wagon, ProxyRepository repository )
- {
- boolean connected = false;
- try
- {
- if ( repository.isProxied() )
- {
- wagon.connect( repository, config.getHttpProxy() );
- }
- else
- {
- wagon.connect( repository );
- }
- connected = true;
- }
- catch ( ConnectionException e )
- {
- getLogger().info( "Could not connect to " + repository.getId() + ": " + e.getMessage() );
- }
- catch ( AuthenticationException e )
- {
- getLogger().info( "Could not connect to " + repository.getId() + ": " + e.getMessage() );
- }
-
- return connected;
- }
-
- /**
- * Used to verify the checksum during a wagonManager download
- *
- * @param checksumMap the map of ChecksumObservers present in the wagonManager as transferlisteners
- * @param path path of the remote object whose checksum is to be verified
- * @param wagon the wagonManager object used to download the requested path
- * @return true when the checksum succeeds and false when the checksum failed.
- */
- private boolean doChecksumCheck( Map checksumMap, String path, Wagon wagon )
- throws ProxyException
- {
- releaseChecksumListeners( wagon, checksumMap );
- for ( Iterator checksums = checksumMap.keySet().iterator(); checksums.hasNext(); )
- {
- String checksumExt = (String) checksums.next();
- ChecksumObserver checksum = (ChecksumObserver) checksumMap.get( checksumExt );
- String checksumPath = path + "." + checksumExt;
- File checksumFile = new File( config.getRepositoryCachePath(), checksumPath );
-
- try
- {
- File tempChecksumFile = new File( checksumFile.getAbsolutePath() + ".tmp" );
-
- wagon.get( checksumPath, tempChecksumFile );
-
- String remoteChecksum = FileUtils.fileRead( tempChecksumFile ).trim();
- if ( remoteChecksum.indexOf( ' ' ) > 0 )
- {
- remoteChecksum = remoteChecksum.substring( 0, remoteChecksum.indexOf( ' ' ) );
- }
-
- boolean checksumCheck = false;
- if ( remoteChecksum.toUpperCase().equals( checksum.getActualChecksum().toUpperCase() ) )
- {
- moveTempToTarget( tempChecksumFile, checksumFile );
-
- checksumCheck = true;
- }
- return checksumCheck;
- }
- catch ( ChecksumFailedException e )
- {
- return false;
- }
- catch ( TransferFailedException e )
- {
- getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(),
- e );
- // do nothing try the next checksum
- }
- catch ( ResourceDoesNotExistException e )
- {
- getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(),
- e );
- // do nothing try the next checksum
- }
- catch ( AuthorizationException e )
- {
- getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(),
- e );
- // do nothing try the next checksum
- }
- catch ( IOException e )
- {
- getLogger().debug( "An error occurred while reading the temporary checksum file.", e );
- return false;
- }
- }
-
- getLogger().debug( "Skipping checksum validation for " + path + ": No remote checksums available." );
-
- return true;
- }
-
- /**
- * Used to ensure that this proxy instance is running with a valid configuration instance.
- *
- * @throws ProxyException
- */
- private void checkConfiguration()
- throws ProxyException
- {
- if ( config == null )
- {
- throw new ProxyException( "No proxy configuration defined." );
- }
- }
-
- /**
- * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles
- * its downloaded files.
- *
- * @param temp The completed download file
- * @param target The final location of the downloaded file
- * @throws ProxyException when the temp file cannot replace the target file
- */
- private void moveTempToTarget( File temp, File target )
- throws ProxyException
- {
- if ( target.exists() && !target.delete() )
- {
- throw new ProxyException( "Unable to overwrite existing target file: " + target.getAbsolutePath() );
- }
-
- if ( !temp.renameTo( target ) )
- {
- getLogger().warn( "Unable to rename tmp file to its final name... resorting to copy command." );
-
- try
- {
- FileUtils.copyFile( temp, target );
- }
- catch ( IOException e )
- {
- throw new ProxyException( "Cannot copy tmp file to its final location", e );
- }
- finally
- {
- temp.delete();
- }
- }
- }
-
- /**
- * Used to disconnect the wagonManager from its repository
- *
- * @param wagon the connected wagonManager object
- */
- private void disconnectWagon( Wagon wagon )
- {
- try
- {
- wagon.disconnect();
- }
- catch ( ConnectionException e )
- {
- getLogger().error( "Problem disconnecting from wagonManager - ignoring: " + e.getMessage() );
- }
- }
-
- /**
- * Queries the configuration on how to handle a repository download failure
- *
- * @param repository the repository object where the failure occurred
- * @param message the message/reason for the failure
- * @param t the cause for the exception
- * @throws ProxyException if hard failure is enabled on the repository causing the failure
- */
- private void processRepositoryFailure( ProxyRepository repository, String message, Throwable t )
- throws ProxyException
- {
- if ( repository.isHardfail() )
- {
- throw new ProxyException(
- "An error occurred in hardfailing repository " + repository.getName() + "...\n " + message, t );
- }
- else
- {
- getLogger().debug( message, t );
- }
- }
-}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.artifact.Artifact;
+import org.apache.maven.artifact.manager.ChecksumFailedException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.repository.discovery.ArtifactDiscoverer;
+import org.apache.maven.repository.discovery.DiscovererException;
+import org.apache.maven.wagon.ConnectionException;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.observers.ChecksumObserver;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.apache.maven.wagon.repository.Repository;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of the proxy handler.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @plexus.component
+ * @todo this currently duplicates a lot of the wagon manager, and doesn't do things like snapshot resolution, etc.
+ * Should we have a more artifact based one? This will merge metadata so should behave correctly, and it is able to
+ * correct some limitations of the wagon manager (eg, it can retrieve newer SNAPSHOT files without metadata)
+ */
+public class DefaultProxyRequestHandler
+ extends AbstractLogEnabled
+ implements ProxyRequestHandler
+{
+ /**
+ * @plexus.requirement role-hint="default"
+ * @todo use a map, and have priorities in them
+ */
+ private ArtifactDiscoverer defaultArtifactDiscoverer;
+
+ /**
+ * @plexus.requirement role-hint="legacy"
+ */
+ private ArtifactDiscoverer legacyArtifactDiscoverer;
+
+ /**
+ * @plexus.requirement role="org.apache.maven.wagon.Wagon"
+ */
+ private Map/*<String,Wagon>*/ wagons;
+
+ public File get( String path, List proxiedRepositories, ArtifactRepository managedRepository )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ return get( path, proxiedRepositories, managedRepository, null );
+ }
+
+ public File get( String path, List proxiedRepositories, ArtifactRepository managedRepository, ProxyInfo wagonProxy )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ //@todo use wagonManager for cache use file:// as URL
+ File cachedFile = new File( managedRepository.getBasedir(), path );
+ if ( !cachedFile.exists() )
+ {
+ cachedFile = getAlways( path, proxiedRepositories, managedRepository, wagonProxy );
+ }
+ return cachedFile;
+ }
+
+
+ public File getAlways( String path, List proxiedRepositories, ArtifactRepository managedRepository )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ return getAlways( path, proxiedRepositories, managedRepository, null );
+ }
+
+ public File getAlways( String path, List proxiedRepositories, ArtifactRepository managedRepository,
+ ProxyInfo wagonProxy )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ File remoteFile = null;
+
+ for ( Iterator i = proxiedRepositories.iterator(); i.hasNext(); )
+ {
+ ProxiedArtifactRepository repository = (ProxiedArtifactRepository) i.next();
+
+ if ( repository.isCachedFailure( path ) )
+ {
+ getLogger().debug( "Skipping repository " + repository.getName() + " for a cached path failure." );
+ }
+ else
+ {
+ if ( path.endsWith( ".md5" ) || path.endsWith( ".sha1" ) )
+ {
+ // always read from the managed repository
+ remoteFile = new File( managedRepository.getBasedir(), path );
+ }
+ else if ( path.endsWith( "maven-metadata.xml" ) )
+ {
+ remoteFile = getFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy,
+ repository.getRepository().getReleases() );
+ }
+ else
+ {
+ Artifact artifact = null;
+ try
+ {
+ artifact = defaultArtifactDiscoverer.buildArtifact( path );
+ }
+ catch ( DiscovererException e )
+ {
+ getLogger().debug(
+ "Failed to build artifact using default layout with message: " + e.getMessage() );
+ }
+
+ if ( artifact == null )
+ {
+ try
+ {
+ artifact = legacyArtifactDiscoverer.buildArtifact( path );
+ }
+ catch ( DiscovererException e )
+ {
+ getLogger().debug(
+ "Failed to build artifact using legacy layout with message: " + e.getMessage() );
+ }
+ }
+
+ if ( artifact != null )
+ {
+ getArtifact( artifact, repository, managedRepository, wagonProxy );
+
+ remoteFile = artifact.getFile();
+ }
+ else
+ {
+ // Some other unknown file in the repository, proxy as is
+ getFromRepository( path, repository, managedRepository.getBasedir(), wagonProxy, null );
+ }
+ }
+
+ if ( remoteFile != null && !remoteFile.exists() )
+ {
+ repository.addFailure( path );
+ throw new ResourceDoesNotExistException(
+ "Could not find " + path + " in any of the repositories." );
+ }
+ else
+ {
+ // in case it previously failed and we've since found it
+ repository.clearFailure( path );
+ }
+ }
+ }
+
+ return remoteFile;
+ }
+
+ private File getFromRepository( String path, ProxiedArtifactRepository repository, String repositoryCachePath,
+ ProxyInfo httpProxy, ArtifactRepositoryPolicy policy )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ File target = new File( repositoryCachePath, path );
+ if ( !target.exists() || isOutOfDate( policy, target ) )
+ {
+ boolean connected = false;
+ Map checksums = null;
+ Wagon wagon = null;
+
+ try
+ {
+ String protocol = repository.getRepository().getProtocol();
+ wagon = (Wagon) wagons.get( protocol );
+ if ( wagon == null )
+ {
+ throw new ProxyException( "Unsupported remote protocol: " + protocol );
+ }
+
+ //@todo configure wagon (ssh settings, etc)
+
+ checksums = prepareChecksumListeners( wagon );
+
+ connected = connectToRepository( wagon, repository, httpProxy );
+ if ( connected )
+ {
+ File temp = new File( target.getAbsolutePath() + ".tmp" );
+ temp.deleteOnExit();
+
+ int tries = 0;
+ boolean success;
+
+ do
+ {
+ tries++;
+
+ getLogger().info( "Trying " + path + " from " + repository.getName() + "..." );
+
+ if ( !target.exists() )
+ {
+ wagon.get( path, temp );
+ }
+ else
+ {
+ wagon.getIfNewer( path, temp, target.lastModified() );
+ }
+
+ success = doChecksumCheck( checksums, path, wagon, repositoryCachePath );
+
+ if ( tries > 1 && !success )
+ {
+ throw new ProxyException( "Checksum failures occurred while downloading " + path );
+ }
+ }
+ while ( !success );
+
+ disconnectWagon( wagon );
+
+ if ( temp.exists() )
+ {
+ moveTempToTarget( temp, target );
+ }
+ }
+ //try next repository
+ }
+ catch ( TransferFailedException e )
+ {
+ String message = "Skipping repository " + repository.getName() + ": " + e.getMessage();
+ processRepositoryFailure( repository, message, e );
+ }
+ catch ( AuthorizationException e )
+ {
+ String message = "Skipping repository " + repository.getName() + ": " + e.getMessage();
+ processRepositoryFailure( repository, message, e );
+ }
+ finally
+ {
+ if ( wagon != null && checksums != null )
+ {
+ releaseChecksumListeners( wagon, checksums );
+ }
+
+ if ( connected )
+ {
+ disconnectWagon( wagon );
+ }
+ }
+ }
+ return target;
+ }
+
+ private static boolean isOutOfDate( ArtifactRepositoryPolicy policy, File target )
+ {
+ return policy != null && policy.checkOutOfDate( new Date( target.lastModified() ) );
+ }
+
+ /**
+ * Used to add checksum observers as transfer listeners to the wagonManager object
+ *
+ * @param wagon the wagonManager object to use the checksum with
+ * @return map of ChecksumObservers added into the wagonManager transfer listeners
+ */
+ private Map prepareChecksumListeners( Wagon wagon )
+ {
+ Map checksums = new HashMap();
+ try
+ {
+ ChecksumObserver checksum = new ChecksumObserver( "SHA-1" );
+ wagon.addTransferListener( checksum );
+ checksums.put( "sha1", checksum );
+
+ checksum = new ChecksumObserver( "MD5" );
+ wagon.addTransferListener( checksum );
+ checksums.put( "md5", checksum );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ getLogger().info( "An error occurred while preparing checksum observers", e );
+ }
+ return checksums;
+ }
+
+ private void releaseChecksumListeners( Wagon wagon, Map checksumMap )
+ {
+ for ( Iterator checksums = checksumMap.values().iterator(); checksums.hasNext(); )
+ {
+ ChecksumObserver listener = (ChecksumObserver) checksums.next();
+ wagon.removeTransferListener( listener );
+ }
+ }
+
+ private boolean connectToRepository( Wagon wagon, ProxiedArtifactRepository repository, ProxyInfo httpProxy )
+ {
+ boolean connected = false;
+ try
+ {
+ ArtifactRepository artifactRepository = repository.getRepository();
+ Repository wagonRepository = new Repository( artifactRepository.getId(), artifactRepository.getUrl() );
+ if ( repository.isUseNetworkProxy() && httpProxy != null )
+ {
+ wagon.connect( wagonRepository, httpProxy );
+ }
+ else
+ {
+ wagon.connect( wagonRepository );
+ }
+ connected = true;
+ }
+ catch ( ConnectionException e )
+ {
+ getLogger().info( "Could not connect to " + repository.getName() + ": " + e.getMessage() );
+ }
+ catch ( AuthenticationException e )
+ {
+ getLogger().info( "Could not connect to " + repository.getName() + ": " + e.getMessage() );
+ }
+
+ return connected;
+ }
+
+ private boolean doChecksumCheck( Map checksumMap, String path, Wagon wagon, String repositoryCachePath )
+ throws ProxyException
+ {
+ releaseChecksumListeners( wagon, checksumMap );
+ for ( Iterator checksums = checksumMap.keySet().iterator(); checksums.hasNext(); )
+ {
+ String checksumExt = (String) checksums.next();
+ ChecksumObserver checksum = (ChecksumObserver) checksumMap.get( checksumExt );
+ String checksumPath = path + "." + checksumExt;
+ File checksumFile = new File( repositoryCachePath, checksumPath );
+
+ try
+ {
+ File tempChecksumFile = new File( checksumFile.getAbsolutePath() + ".tmp" );
+
+ wagon.get( checksumPath, tempChecksumFile );
+
+ String remoteChecksum = FileUtils.fileRead( tempChecksumFile ).trim();
+ if ( remoteChecksum.indexOf( ' ' ) > 0 )
+ {
+ remoteChecksum = remoteChecksum.substring( 0, remoteChecksum.indexOf( ' ' ) );
+ }
+
+ boolean checksumCheck = false;
+ if ( remoteChecksum.toUpperCase().equals( checksum.getActualChecksum().toUpperCase() ) )
+ {
+ moveTempToTarget( tempChecksumFile, checksumFile );
+
+ checksumCheck = true;
+ }
+ return checksumCheck;
+ }
+ catch ( ChecksumFailedException e )
+ {
+ return false;
+ }
+ catch ( TransferFailedException e )
+ {
+ getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(),
+ e );
+ // do nothing try the next checksum
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(),
+ e );
+ // do nothing try the next checksum
+ }
+ catch ( AuthorizationException e )
+ {
+ getLogger().debug( "An error occurred during the download of " + checksumPath + ": " + e.getMessage(),
+ e );
+ // do nothing try the next checksum
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "An error occurred while reading the temporary checksum file.", e );
+ return false;
+ }
+ }
+
+ getLogger().debug( "Skipping checksum validation for " + path + ": No remote checksums available." );
+
+ return true;
+ }
+
+ /**
+ * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles
+ * its downloaded files.
+ *
+ * @param temp The completed download file
+ * @param target The final location of the downloaded file
+ * @throws ProxyException when the temp file cannot replace the target file
+ */
+ private void moveTempToTarget( File temp, File target )
+ throws ProxyException
+ {
+ if ( target.exists() && !target.delete() )
+ {
+ throw new ProxyException( "Unable to overwrite existing target file: " + target.getAbsolutePath() );
+ }
+
+ if ( !temp.renameTo( target ) )
+ {
+ getLogger().warn( "Unable to rename tmp file to its final name... resorting to copy command." );
+
+ try
+ {
+ FileUtils.copyFile( temp, target );
+ }
+ catch ( IOException e )
+ {
+ throw new ProxyException( "Cannot copy tmp file to its final location", e );
+ }
+ finally
+ {
+ temp.delete();
+ }
+ }
+ }
+
+ /**
+ * Used to disconnect the wagonManager from its repository
+ *
+ * @param wagon the connected wagonManager object
+ */
+ private void disconnectWagon( Wagon wagon )
+ {
+ try
+ {
+ wagon.disconnect();
+ }
+ catch ( ConnectionException e )
+ {
+ getLogger().error( "Problem disconnecting from wagonManager - ignoring: " + e.getMessage() );
+ }
+ }
+
+ /**
+ * Queries the configuration on how to handle a repository download failure
+ *
+ * @param repository the repository object where the failure occurred
+ * @param message the message/reason for the failure
+ * @param t the cause for the exception
+ * @throws ProxyException if hard failure is enabled on the repository causing the failure
+ */
+ private void processRepositoryFailure( ProxiedArtifactRepository repository, String message, Throwable t )
+ throws ProxyException
+ {
+ if ( repository.isHardFail() )
+ {
+ throw new ProxyException(
+ "An error occurred in hardfailing repository " + repository.getName() + "...\n " + message, t );
+ }
+ else
+ {
+ getLogger().error( message, t );
+ }
+ }
+
+ private void getArtifact( Artifact artifact, ProxiedArtifactRepository repository, ArtifactRepository repoCache,
+ ProxyInfo httpProxy )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ ArtifactRepository artifactRepository = repository.getRepository();
+ ArtifactRepositoryPolicy policy =
+ artifact.isSnapshot() ? artifactRepository.getSnapshots() : artifactRepository.getReleases();
+
+ if ( !policy.isEnabled() )
+ {
+ getLogger().debug( "Skipping disabled repository " + repository.getName() );
+ }
+ else
+ {
+ getLogger().debug( "Trying repository " + repository.getName() );
+ // Don't use releases policy, we don't want to perform updates on them (only metadata, as used above)
+ getFromRepository( artifactRepository.pathOf( artifact ), repository, repoCache.getBasedir(), httpProxy,
+ artifact.isSnapshot() ? artifactRepository.getSnapshots() : null );
+ getLogger().debug( " Artifact resolved" );
+
+ artifact.setResolved( true );
+ }
+ }
+
+}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.artifact.repository.ArtifactRepository;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A proxied artifact repository - contains the artifact repository and additional information about
+ * the proxied repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ProxiedArtifactRepository
+{
+ /**
+ * Whether to cache failures or not.
+ */
+ private boolean cacheFailures;
+
+ /**
+ * Whether failures on this repository cause the whole group to fail.
+ */
+ private boolean hardFail;
+
+ /**
+ * Whether to use the network proxy for any requests.
+ */
+ private boolean useNetworkProxy;
+
+ /**
+ * The artifact repository on the other end of the proxy.
+ */
+ private ArtifactRepository repository;
+
+ /**
+ * Cache of failures that have already occurred, containing paths from the repository root.
+ */
+ private Set/*<String>*/ failureCache = new HashSet/*<String>*/();
+
+ /**
+ * A user friendly name for the repository.
+ */
+ private String name;
+
+ public boolean isHardFail()
+ {
+ return hardFail;
+ }
+
+ public boolean isUseNetworkProxy()
+ {
+ return useNetworkProxy;
+ }
+
+ public boolean isCacheFailures()
+ {
+ return cacheFailures;
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return repository;
+ }
+
+ public boolean isCachedFailure( String path )
+ {
+ return cacheFailures && failureCache.contains( path );
+ }
+
+ public void addFailure( String path )
+ {
+ if ( cacheFailures )
+ {
+ failureCache.add( path );
+ }
+ }
+
+ public void clearFailure( String path )
+ {
+ if ( cacheFailures )
+ {
+ failureCache.remove( path );
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+}
+++ /dev/null
-package org.apache.maven.repository.proxy;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.repository.proxy.configuration.ProxyConfiguration;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-
-import java.io.File;
-
-/**
- * Class used to bridge the servlet to the repository proxy implementation.
- *
- * @author Edwin Punzalan
- */
-public interface ProxyManager
-{
- String ROLE = ProxyManager.class.getName();
-
- /**
- * Used to retrieve a cached path or retrieve one if the cache does not contain it yet.
- *
- * @param path the expected repository path
- * @return File object referencing the requested path in the cache
- * @throws ProxyException when an exception occurred during the retrieval of the requested path
- * @throws ResourceDoesNotExistException when the requested object can't be found in any of the
- * configured repositories
- */
- File get( String path )
- throws ProxyException, ResourceDoesNotExistException;
-
- /**
- * Used to force remote download of the requested path from any the configured repositories. This method will
- * only bypass the cache for searching but the requested path will still be cached.
- *
- * @param path the expected repository path
- * @return File object referencing the requested path in the cache
- * @throws ProxyException when an exception occurred during the retrieval of the requested path
- * @throws ResourceDoesNotExistException when the requested object can't be found in any of the
- * configured repositories
- */
- File getAlways( String path )
- throws ProxyException, ResourceDoesNotExistException;
-
- /**
- * Used by the factory to set the configuration of the proxy
- *
- * @param config the ProxyConfiguration to set the behavior of the proxy
- */
- void setConfiguration( ProxyConfiguration config );
-}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.artifact.repository.ArtifactRepository;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * An individual request handler for the proxy.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public interface ProxyRequestHandler
+{
+ /**
+ * The Plexus role of the component.
+ */
+ String ROLE = ProxyRequestHandler.class.getName();
+
+ /**
+ * Used to retrieve an artifact at a particular path, giving the cached version if it exists.
+ *
+ * @param path the expected repository path
+ * @param proxiedRepositories the repositories being proxied to
+ * @param managedRepository the locally managed repository to cache artifacts in
+ * @return File object referencing the requested path in the cache
+ * @throws ProxyException when an exception occurred during the retrieval of the requested path
+ * @throws org.apache.maven.wagon.ResourceDoesNotExistException
+ * when the requested object can't be found in any of the
+ * configured repositories
+ */
+ File get( String path, List proxiedRepositories, ArtifactRepository managedRepository )
+ throws ProxyException, ResourceDoesNotExistException;
+
+ /**
+ * Used to retrieve an artifact at a particular path, giving the cached version if it exists.
+ *
+ * @param path the expected repository path
+ * @param proxiedRepositories the repositories being proxied to
+ * @param managedRepository the locally managed repository to cache artifacts in
+ * @param wagonProxy a network proxy to use when transferring files if needed
+ * @return File object referencing the requested path in the cache
+ * @throws ProxyException when an exception occurred during the retrieval of the requested path
+ * @throws org.apache.maven.wagon.ResourceDoesNotExistException
+ * when the requested object can't be found in any of the
+ * configured repositories
+ */
+ File get( String path, List proxiedRepositories, ArtifactRepository managedRepository, ProxyInfo wagonProxy )
+ throws ProxyException, ResourceDoesNotExistException;
+
+ /**
+ * Used to force remote download of the requested path from any the configured repositories. This method will
+ * only bypass the cache for searching but the requested path will still be cached.
+ *
+ * @param path the expected repository path
+ * @param proxiedRepositories the repositories being proxied to
+ * @param managedRepository the locally managed repository to cache artifacts in
+ * @return File object referencing the requested path in the cache
+ * @throws ProxyException when an exception occurred during the retrieval of the requested path
+ * @throws org.apache.maven.wagon.ResourceDoesNotExistException
+ * when the requested object can't be found in any of the
+ * configured repositories
+ */
+ File getAlways( String path, List proxiedRepositories, ArtifactRepository managedRepository )
+ throws ProxyException, ResourceDoesNotExistException;
+
+ /**
+ * Used to force remote download of the requested path from any the configured repositories. This method will
+ * only bypass the cache for searching but the requested path will still be cached.
+ *
+ * @param path the expected repository path
+ * @param proxiedRepositories the repositories being proxied to
+ * @param managedRepository the locally managed repository to cache artifacts in
+ * @param wagonProxy a network proxy to use when transferring files if needed
+ * @return File object referencing the requested path in the cache
+ * @throws ProxyException when an exception occurred during the retrieval of the requested path
+ * @throws org.apache.maven.wagon.ResourceDoesNotExistException
+ * when the requested object can't be found in any of the
+ * configured repositories
+ */
+ File getAlways( String path, List proxiedRepositories, ArtifactRepository managedRepository, ProxyInfo wagonProxy )
+ throws ProxyException, ResourceDoesNotExistException;
+}
+++ /dev/null
-package org.apache.maven.repository.proxy.configuration;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.artifact.repository.layout.DefaultRepositoryLayout;
-import org.apache.maven.repository.proxy.repository.ProxyRepository;
-import org.codehaus.plexus.util.StringUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-/**
- * @author Ben Walding
- */
-public class MavenProxyPropertyLoader
-{
- private static final String REPO_LOCAL_STORE = "repo.local.store";
-
- private static final String PROXY_LIST = "proxy.list";
-
- private static final String REPO_LIST = "repo.list";
-
- public ProxyConfiguration load( Properties props )
- throws ValidationException
- {
- ProxyConfiguration config = new ProxyConfiguration();
-
- config.setLayout( "default" );
-
- config.setRepositoryCachePath( getMandatoryProperty( props, REPO_LOCAL_STORE ) );
-
- //just get the first proxy and break
- String propertyList = props.getProperty( PROXY_LIST );
- if ( propertyList != null )
- {
- StringTokenizer tok = new StringTokenizer( propertyList, "," );
- while ( tok.hasMoreTokens() )
- {
- String key = tok.nextToken();
- if ( StringUtils.isNotEmpty( key ) )
- {
- String host = getMandatoryProperty( props, "proxy." + key + ".host" );
- int port = Integer.parseInt( getMandatoryProperty( props, "proxy." + key + ".port" ) );
-
- // the username and password isn't required
- String username = props.getProperty( "proxy." + key + ".username" );
- String password = props.getProperty( "proxy." + key + ".password" );
-
- if ( StringUtils.isNotEmpty( username ) )
- {
- config.setHttpProxy( host, port, username, password );
- }
- else
- {
- config.setHttpProxy( host, port );
- }
-
- //accept only one proxy configuration
- break;
- }
- }
- }
-
- List repositories = new ArrayList();
-
- //get the remote repository list
- String repoList = getMandatoryProperty( props, REPO_LIST );
-
- StringTokenizer tok = new StringTokenizer( repoList, "," );
- while ( tok.hasMoreTokens() )
- {
- String key = tok.nextToken();
-
- Properties repoProps = getSubset( props, "repo." + key + "." );
- String url = getMandatoryProperty( props, "repo." + key + ".url" );
- String proxyKey = repoProps.getProperty( "proxy" );
-
- boolean cacheFailures =
- Boolean.valueOf( repoProps.getProperty( "cache.failures", "false" ) ).booleanValue();
- boolean hardFail = Boolean.valueOf( repoProps.getProperty( "hardfail", "true" ) ).booleanValue();
- long cachePeriod = Long.parseLong( repoProps.getProperty( "cache.period", "0" ) );
-
- ProxyRepository repository =
- new ProxyRepository( key, url, new DefaultRepositoryLayout(), cacheFailures, cachePeriod );
-
- repository.setHardfail( hardFail );
-
- if ( StringUtils.isNotEmpty( proxyKey ) )
- {
- repository.setProxied( true );
- }
-
- repositories.add( repository );
- }
-
- config.setRepositories( repositories );
-
- config.validate();
-
- return config;
- }
-
- private Properties getSubset( Properties props, String prefix )
- {
- Enumeration keys = props.keys();
- Properties result = new Properties();
- while ( keys.hasMoreElements() )
- {
- String key = (String) keys.nextElement();
- String value = props.getProperty( key );
- if ( key.startsWith( prefix ) )
- {
- String newKey = key.substring( prefix.length() );
- result.setProperty( newKey, value );
- }
- }
- return result;
- }
-
- public ProxyConfiguration load( InputStream is )
- throws IOException, ValidationException
- {
- Properties props = new Properties();
- props.load( is );
- return load( props );
- }
-
- private String getMandatoryProperty( Properties props, String key )
- throws ValidationException
- {
- String value = props.getProperty( key );
-
- if ( value == null )
- {
- throw new ValidationException( "Missing property: " + key );
- }
-
- return value;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.apache.maven.repository.proxy.configuration;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.artifact.repository.ArtifactRepositoryPolicy;
-import org.apache.maven.repository.proxy.repository.ProxyRepository;
-import org.apache.maven.wagon.proxy.ProxyInfo;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Class to represent the configuration file for the proxy
- *
- * @author Edwin Punzalan
- */
-public class ProxyConfiguration
-{
- private List repositories = new ArrayList();
-
- private String cachePath;
-
- private String layout;
-
- private ProxyInfo httpProxy;
-
- private ArtifactRepositoryPolicy cacheReleasePolicy;
-
- private ArtifactRepositoryPolicy cacheSnapshotPolicy;
-
- /**
- * Used to set the location where the proxy should cache the configured repositories
- *
- * @param path
- */
- public void setRepositoryCachePath( String path )
- {
- cachePath = new File( path ).getAbsolutePath();
- }
-
- /**
- * Used to retrieved the absolute path of the repository cache
- *
- * @return path to the proxy cache
- */
- public String getRepositoryCachePath()
- {
- return cachePath;
- }
-
- public void setHttpProxy( ProxyInfo httpProxy )
- {
- this.httpProxy = httpProxy;
- }
-
- public void setHttpProxy( String host, int port )
- {
- ProxyInfo proxyInfo = new ProxyInfo();
- proxyInfo.setHost( host );
- proxyInfo.setPort( port );
-
- httpProxy = proxyInfo;
- }
-
- public void setHttpProxy( String host, int port, String username, String password )
- {
- setHttpProxy( host, port );
- httpProxy.setUserName( username );
- httpProxy.setPassword( password );
- }
-
- public void setHttpProxy( String host, int port, String username, String password, String ntlmHost,
- String ntlmDomain )
- {
- setHttpProxy( host, port );
- httpProxy.setUserName( username );
- httpProxy.setPassword( password );
- httpProxy.setNtlmHost( ntlmHost );
- httpProxy.setNtlmDomain( ntlmDomain );
- }
-
- public ProxyInfo getHttpProxy()
- {
- return httpProxy;
- }
-
- /**
- * Used to add proxied repositories.
- *
- * @param repository the repository to be proxied
- */
- public void addRepository( ProxyRepository repository )
- {
- repositories.add( repository );
- }
-
- /**
- * Used to retrieve an unmodifyable list of proxied repositories. They returned list determines the search sequence
- * for retrieving artifacts.
- *
- * @return a list of ProxyRepository objects representing proxied repositories
- */
- public List getRepositories()
- {
- return Collections.unmodifiableList( repositories );
- }
-
- /**
- * Used to set the list of repositories to be proxied. This replaces any repositories already added to this
- * configuraion instance. Useful for re-arranging an existing proxied list.
- *
- * @param repositories
- */
- public void setRepositories( List repositories )
- {
- this.repositories = repositories;
- }
-
- public String getLayout()
- {
- if ( layout == null )
- {
- layout = "default";
- }
-
- return layout;
- }
-
- public void setLayout( String layout )
- {
- this.layout = layout;
- }
-
- public void validate()
- throws ValidationException
- {
- validateRemoteRepo();
- validateDirectories();
- }
-
- private void validateRemoteRepo()
- throws ValidationException
- {
- //Verify remote repository set
- //only warn if missing
- if ( getRepositories().size() < 1 )
- {
- throw new ValidationException( "At least one remote repository must be configured." );
- }
- }
-
- private void validateDirectories()
- throws ValidationException
- {
- File f = new File( cachePath );
- if ( !f.exists() )
- {
- throw new ValidationException( "Specified directory does not exist: " + f.getAbsolutePath() );
- }
-
- for ( Iterator repos = getRepositories().iterator(); repos.hasNext(); )
- {
- ProxyRepository repo = (ProxyRepository) repos.next();
- if ( repo.getUrl().startsWith( "file://" ) )
- {
- File f2 = new File( repo.getBasedir() );
- if ( !f2.exists() )
- {
- throw new ValidationException( "Specified directory does not exist: " + f2.getAbsolutePath() );
- }
- }
- }
- }
-
- public ArtifactRepositoryPolicy getCacheReleasePolicy()
- {
- if ( cacheReleasePolicy == null )
- {
- cacheReleasePolicy = new ArtifactRepositoryPolicy();
- }
-
- return cacheReleasePolicy;
- }
-
- public void setCacheReleasePolicy( ArtifactRepositoryPolicy cacheReleasePolicy )
- {
- this.cacheReleasePolicy = cacheReleasePolicy;
- }
-
- public ArtifactRepositoryPolicy getCacheSnapshotPolicy()
- {
- if ( cacheSnapshotPolicy == null )
- {
- cacheSnapshotPolicy = new ArtifactRepositoryPolicy();
- }
-
- return cacheSnapshotPolicy;
- }
-
- public void setCacheSnapshotPolicy( ArtifactRepositoryPolicy cacheSnapshotPolicy )
- {
- this.cacheSnapshotPolicy = cacheSnapshotPolicy;
- }
-}
+++ /dev/null
-package org.apache.maven.repository.proxy.configuration;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.
- */
-
-/**
- * @author Ben Walding
- */
-public class ValidationException
- extends Exception
-{
- /**
- * @param
- */
- public ValidationException( String msg )
- {
- super( msg );
- }
-
- /**
- * @param t
- */
- public ValidationException( Throwable t )
- {
- super( t );
- }
-}
+++ /dev/null
-package org.apache.maven.repository.proxy.repository;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.artifact.repository.DefaultArtifactRepository;
-import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
-
-/**
- * Class to represent the Proxy repository. Currently does not provide additional methods from
- * DefaultArtifactRepository but is expected to do so like enabled/disabled when a UI is present.
- *
- * @author Edwin Punzalan
- */
-public class ProxyRepository
- extends DefaultArtifactRepository
-{
- // zero caches forever
- private long cachePeriod;
-
- private boolean cacheFailures;
-
- private boolean hardfail = true;
-
- private boolean proxied;
-
- public ProxyRepository( String id, String url, ArtifactRepositoryLayout layout, boolean cacheFailures,
- long cachePeriod )
- {
- this( id, url, layout );
-
- this.cacheFailures = cacheFailures;
-
- this.cachePeriod = cachePeriod;
- }
-
- public ProxyRepository( String id, String url, ArtifactRepositoryLayout layout )
- {
- super( id, url, layout );
- }
-
- public long getCachePeriod()
- {
- return cachePeriod;
- }
-
- public void setCachePeriod( long cachePeriod )
- {
- this.cachePeriod = cachePeriod;
- }
-
- public boolean isCacheFailures()
- {
- return cacheFailures;
- }
-
- public void setCacheFailures( boolean cacheFailures )
- {
- this.cacheFailures = cacheFailures;
- }
-
- public boolean isProxied()
- {
- return proxied;
- }
-
- public void setProxied( boolean proxied )
- {
- this.proxied = proxied;
- }
-
- /**
- * Checks the repository hardfail setting.
- *
- * @return true if the hardfail is enabled, otherwise, returns false.
- */
- public boolean isHardfail()
- {
- return hardfail;
- }
-
- /**
- * If hardfail is set to true, then any unexpected errors from retrieving files from this repository
- * will cause the download to fail.
- *
- * @param hardfail set to true to enable hard failures
- */
- public void setHardfail( boolean hardfail )
- {
- this.hardfail = hardfail;
- }
-}
+++ /dev/null
-################ GLOBAL SETTINGS\r
-# This is where maven-proxy stores files it has downloaded\r
-repo.local.store=target\r
-\r
-#The port to listen on - not used if loaded as a webapp\r
-port=9999\r
-\r
-#This is the base area that all files are loaded from. While it is possible to leave this blank, this behaviour\r
-#is deprecated and will be disabled in version 2.0. There are too many namespace conflicts caused by not using\r
-#a prefix.\r
-#The repository will be shown at http://localhost:9999/repository/\r
-#for the .war loaded into a webapp server, the default prefix is "repository" (edit the web.xml to change)\r
-# As maven doesn't like a trailing slash, this address shouldn't have one either.\r
-prefix=repository\r
-\r
-#This is the simple date format used to display the last modified date while browsing the repository.\r
-lastModifiedDateFormat=yyyy/MM/dd HH:mm:ss\r
-\r
-################ SNAPSHOT HANDLING\r
-#If you want the proxy to look for newer snapshots, set to true\r
-snapshot.update=true\r
-\r
-################ M2 METADATA HANDLING\r
-#If you want the proxy to prevent looking for newer metadata, set to false (default is true)\r
-#metadata.update=false\r
-\r
-################ M2 POM HANDLING\r
-#If you want the proxy to look for newer POMs, set to true (default is false)\r
-pom.update=true\r
-\r
-################ PROMOTION HANDLING\r
-# ***** NOT CURRENTLY IMPLEMENTED *****\r
-#Promotion describes the process by which new artifacts are loaded to global maven-proxy repository. It\r
-# is designed to be used by "higher security installations" that do not want to acquire artifacts from\r
-# remote repositories without approval.\r
-#\r
-#If promotion handling is enabled, then the proxy will not download remote artifacts without permission\r
-# (local repositories with copy=false are considered to be local)\r
-#\r
-#Permission to download is granted via the Promotion menu which will be enabled\r
-# when promotion handling is enabled.\r
-#\r
-#If promotion is false, artifacts are sourced from any repository as per normal.\r
-#\r
-#Promotion and snapshots: If promotion is enabled, snapshots are not downloadable. The concept of using\r
-# a snapshot in a production build (which is primarily what promotion is for) is counterintuitive.\r
-##\r
-promotion=false\r
-\r
-################ WEB INTERFACE\r
-# This defines the absolute URL the server should use to identify itself.\r
-# This can often be determined automatically, but we recommend you specify\r
-# it explicitly to prevent problems during startup.\r
-# The prefix will be added to this for the actual repository\r
-# i.e. proxy available at http://localhost:9999/, repository at http://localhost:9999/repository\r
-serverName=http://localhost:9999\r
-\r
-#If true, the repository can be browsed\r
-browsable=true\r
-\r
-#If true, the repository can be searched\r
-searchable=true\r
-\r
-#Not currently implemented. Will allow webdav access to the repository at some point.\r
-webdav=true\r
-\r
-#Stylesheet - if configured, will override the default stylesheet shipped with maven-proxy - absolute URLs only\r
-#eg. /maven-proxy/style.css, http://www.example.com/style.css\r
-stylesheet=/maven-proxy/style.css\r
-\r
-#bgColor / bgColorHighlight are replaced in the built in stylesheet to produce a simple color scheme.\r
-#If a stylesheet is set, these are not used.\r
-bgColor=#14B\r
-bgColorHighlight=#94B\r
-\r
-#rowColor / rowColorHighlight are replaced in the built in stylesheet to produce a simple color scheme.\r
-#If a stylesheet is set, these are not used.\r
-rowColor=#CCF\r
-rowColorHighlight=#DDF\r
-\r
-\r
-################ PROXIES\r
-#This is just a hack, it should auto discover them\r
-proxy.list=one,two,three\r
-\r
-#Unauthenticated proxy\r
-proxy.one.host=proxy1.example.com\r
-proxy.one.port=3128\r
-\r
-#Authenticated proxy\r
-proxy.two.host=proxy2.example.org\r
-proxy.two.port=80\r
-proxy.two.username=username2\r
-proxy.two.password=password2\r
-\r
-#Authenticated proxy\r
-proxy.three.host=proxy3.example.net\r
-proxy.three.port=3129\r
-proxy.three.username=username3\r
-proxy.three.password=password3\r
-\r
-\r
-################# REPOSITORIES\r
-#This is not just a hack, it specifies the order repositories should be checked\r
-#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/"\r
-repo.list=local-repo,www-ibiblio-org,dist-codehaus-org,private-example-com\r
-\r
-#local-store\r
-# The local store represents a location that local jars you host can be located.\r
-# This could also be achieved by having a local http repository, but this is less cumbersome\r
-repo.local-repo.url=file://target\r
-repo.local-repo.description=Super Secret Custom Repository\r
-#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos\r
-repo.local-repo.copy=false\r
-#If hardfail is true, any unexpected errors from the repository will cause\r
-#the client download to fail (typically with a 500 error)\r
-repo.local-repo.hardfail=true\r
-#Don't cache a file repository\r
-repo.local-repo.cache.period=0\r
-\r
-\r
-#www.ibiblio.org\r
-repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2\r
-repo.www-ibiblio-org.description=www.ibiblio.org\r
-repo.www-ibiblio-org.proxy=one\r
-repo.www-ibiblio-org.hardfail=true\r
-#Cache this repository for 1 hour\r
-repo.www-ibiblio-org.cache.period=3600\r
-repo.www-ibiblio-org.cache.failures=true\r
-\r
-#dist.codehaus.org\r
-repo.dist-codehaus-org.url=http://dist.codehaus.org\r
-repo.dist-codehaus-org.proxy=two\r
-repo.dist-codehaus-org.hardfail=false\r
-repo.dist-codehaus-org.cache.period=3600\r
-repo.dist-codehaus-org.cache.failures=true\r
-\r
-#private.example.com\r
-repo.private-example-com.url=http://private.example.com/internal\r
-repo.private-example-com.description=Commercial In Confidence Repository\r
-repo.private-example-com.username=username1\r
-repo.private-example-com.password=password1\r
-repo.private-example-com.proxy=three\r
-repo.private-example-com.cache.period=3600\r
+++ /dev/null
-package org.apache.maven.repository.proxy;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.artifact.repository.layout.ArtifactRepositoryLayout;
-import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
-import org.apache.maven.repository.proxy.configuration.ProxyConfiguration;
-import org.apache.maven.repository.proxy.repository.ProxyRepository;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-
-import java.io.File;
-
-/**
- * @author Edwin Punzalan
- */
-public class DefaultProxyManagerTest
- extends PlexusTestCase
-{
- private ProxyManager proxy;
-
- private ProxyConfiguration configuration;
-
- protected void setUp()
- throws Exception
- {
- super.setUp();
-
- proxy = (ProxyManager) container.lookup( ProxyManager.ROLE );
-
- configuration = getProxyConfiguration();
- proxy.setConfiguration( configuration );
- }
-
- public void testExceptions()
- {
- proxy.setConfiguration( null );
-
- try
- {
- proxy.get( "/invalid" );
- fail( "Expected empty configuration error." );
- }
- catch ( ProxyException e )
- {
- assertEquals( "Expected Exception not thrown.", "No proxy configuration defined.", e.getMessage() );
- }
- catch ( ResourceDoesNotExistException e )
- {
- fail( "Expected Exception not thrown." );
- }
- }
-
- public void testArtifactDownload()
- throws Exception
- {
- //test download
- File file = proxy.get( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
-
- //test cache
- proxy.get( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar" );
-
- try
- {
- proxy.get( "/commons-logging/commons-logging/2.0/commons-logging-2.0.jar" );
- fail( "Expected ResourceDoesNotExistException exception not thrown" );
- }
- catch ( ResourceDoesNotExistException e )
- {
- assertTrue( true );
- }
- }
-
- public void testArtifactChecksum()
- throws Exception
- {
- //force the downlod from the remote repository, use getAlways()
- File file = proxy.getAlways( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar.md5" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- public void testNonArtifactWithNoChecksum()
- throws Exception
- {
- File file = proxy.get( "/not-standard/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- public void testNonArtifactWithMD5Checksum()
- throws Exception
- {
- File file = proxy.get( "/checksumed-md5/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- public void testNonArtifactWithSHA1Checksum()
- throws Exception
- {
- File file = proxy.get( "/checksumed-sha1/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- protected void tearDown()
- throws Exception
- {
- container.release( proxy );
-
- super.tearDown();
- }
-
- private ProxyConfiguration getProxyConfiguration()
- throws ComponentLookupException
- {
- ProxyConfiguration config = new ProxyConfiguration();
-
- config.setRepositoryCachePath( "target/proxy-cache" );
-
- ArtifactRepositoryLayout defLayout = new DefaultRepositoryLayout();
-
- File repo1File = getTestFile( "src/test/remote-repo1" );
-
- ProxyRepository repo1 = new ProxyRepository( "test-repo", "file://" + repo1File.getAbsolutePath(), defLayout );
-
- config.addRepository( repo1 );
-
- return config;
- }
-}
+++ /dev/null
-package org.apache.maven.repository.proxy;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.artifact.repository.layout.ArtifactRepositoryLayout;
-import org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout;
-import org.apache.maven.repository.proxy.configuration.ProxyConfiguration;
-import org.apache.maven.repository.proxy.repository.ProxyRepository;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-
-import java.io.File;
-
-/**
- * @author Edwin Punzalan
- */
-public class LegacyProxyManagerTest
- extends PlexusTestCase
-{
- private ProxyManager proxy;
-
- private ProxyConfiguration configuration;
-
- protected void setUp()
- throws Exception
- {
- super.setUp();
-
- proxy = (ProxyManager) container.lookup( ProxyManager.ROLE );
-
- configuration = getProxyConfiguration();
- proxy.setConfiguration( configuration );
- }
-
- public void testExceptions()
- {
- proxy.setConfiguration( null );
-
- try
- {
- proxy.get( "/invalid" );
- fail( "Expected empty configuration error." );
- }
- catch ( ProxyException e )
- {
- assertEquals( "Expected Exception not thrown.", "No proxy configuration defined.", e.getMessage() );
- }
- catch ( ResourceDoesNotExistException e )
- {
- fail( "Expected Exception not thrown." );
- }
- }
-
- public void testArtifactDownload()
- throws Exception
- {
- //test download
- File file = proxy.get( "/commons-logging/jars/commons-logging-1.0.jar" );
- assertTrue( "File must be downloaded: " + file.getAbsolutePath(), file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
-
- //test cache
- proxy.get( "/commons-logging/jars/commons-logging-1.0.jar" );
-
- try
- {
- proxy.get( "/commons-logging/jars/commons-logging-2.0.jar" );
- fail( "Expected ResourceDoesNotExistException exception not thrown" );
- }
- catch ( ResourceDoesNotExistException e )
- {
- assertTrue( true );
- }
- }
-
- public void testArtifactChecksum()
- throws Exception
- {
- //force the downlod from the remote repository, use getAlways()
- File file = proxy.getAlways( "/commons-logging/jars/commons-logging-1.0.jar.md5" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- public void testNonArtifactWithNoChecksum()
- throws Exception
- {
- File file = proxy.get( "/not-standard/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- public void testNonArtifactWithMD5Checksum()
- throws Exception
- {
- File file = proxy.get( "/checksumed-md5/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- public void testNonArtifactWithSHA1Checksum()
- throws Exception
- {
- File file = proxy.get( "/checksumed-sha1/repository/file.txt" );
- assertTrue( "File must be downloaded.", file.exists() );
- assertTrue( "Downloaded file should be present in the cache.",
- file.getAbsolutePath().startsWith( configuration.getRepositoryCachePath() ) );
- }
-
- protected void tearDown()
- throws Exception
- {
- container.release( proxy );
-
- super.tearDown();
- }
-
- private ProxyConfiguration getProxyConfiguration()
- throws ComponentLookupException
- {
- ProxyConfiguration config = new ProxyConfiguration();
-
- config.setRepositoryCachePath( getTestFile( "target/m1-proxy-cache" ).getAbsolutePath() );
-
- ArtifactRepositoryLayout layout = new LegacyRepositoryLayout();
-
- File repo1File = getTestFile( "src/test/m1-remote-repo" );
-
- ProxyRepository repo1 = new ProxyRepository( "m1-test-repo", "file://" + repo1File.getAbsolutePath(), layout );
-
- config.addRepository( repo1 );
-
- return config;
- }
-}
--- /dev/null
+package org.apache.maven.repository.proxy;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.wagon.ResourceDoesNotExistException;
+import org.codehaus.plexus.PlexusTestCase;
+
+import java.io.File;
+
+/**
+ * @author Edwin Punzalan
+ */
+public class ProxyRequestHandlerTest
+ extends PlexusTestCase
+{
+ private ProxyRequestHandler requestHandler;
+
+ public void testdummy(){}
+
+/* TODO!
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ requestHandler = (ProxyRequestHandler) container.lookup( ProxyRequestHandler.ROLE );
+ }
+
+ public void testArtifactDownload()
+ throws Exception
+ {
+ //test download
+ String s = "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar";
+ File file = get( s );
+ assertTrue( "File must be downloaded.", file.exists() );
+ assertTrue( "Downloaded file should be present in the cache.",
+ file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+
+ //test cache
+ get( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar" );
+
+ try
+ {
+ get( "/commons-logging/commons-logging/2.0/commons-logging-2.0.jar" );
+ fail( "Expected ResourceDoesNotExistException exception not thrown" );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ assertTrue( true );
+ }
+ }
+
+ private File get( String s )
+ throws ProxyException, ResourceDoesNotExistException
+ {
+ return requestHandler.get( s, proxiedRepositories, managedRepository );
+ }
+
+ public void testArtifactChecksum()
+ throws Exception
+ {
+ //force the downlod from the remote repository, use getAlways()
+ File file = requestHandler.getAlways( "/commons-logging/commons-logging/1.0/commons-logging-1.0.jar.md5" );
+ assertTrue( "File must be downloaded.", file.exists() );
+ assertTrue( "Downloaded file should be present in the cache.",
+ file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ }
+
+ public void testNonArtifactWithNoChecksum()
+ throws Exception
+ {
+ File file = get( "/not-standard/repository/file.txt" );
+ assertTrue( "File must be downloaded.", file.exists() );
+ assertTrue( "Downloaded file should be present in the cache.",
+ file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ }
+
+ public void testNonArtifactWithMD5Checksum()
+ throws Exception
+ {
+ File file = get( "/checksumed-md5/repository/file.txt" );
+ assertTrue( "File must be downloaded.", file.exists() );
+ assertTrue( "Downloaded file should be present in the cache.",
+ file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ }
+
+ public void testNonArtifactWithSHA1Checksum()
+ throws Exception
+ {
+ File file = get( "/checksumed-sha1/repository/file.txt" );
+ assertTrue( "File must be downloaded.", file.exists() );
+ assertTrue( "Downloaded file should be present in the cache.",
+ file.getAbsolutePath().startsWith( managedRepository.getBasedir() ) );
+ }
+
+ private ProxyConfiguration getProxyConfiguration()
+ throws ComponentLookupException
+ {
+ ProxyConfiguration config = new ProxyConfiguration();
+
+ config.setRepositoryCachePath( "target/requestHandler-cache" );
+
+ ArtifactRepositoryLayout defLayout = new DefaultRepositoryLayout();
+
+ File repo1File = getTestFile( "src/test/remote-repo1" );
+
+ ProxyRepository repo1 = new ProxyRepository( "test-repo", "file://" + repo1File.getAbsolutePath(), defLayout );
+
+ config.addRepository( repo1 );
+
+ return config;
+ }
+*/
+}
+++ /dev/null
-package org.apache.maven.repository.proxy.configuration;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.repository.proxy.repository.ProxyRepository;
-import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.util.FileUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-
-/**
- * @author Edwin Punzalan
- */
-public class MavenProxyPropertyLoaderTest
- extends PlexusTestCase
-{
- private static final int DEFAULT_CACHE_PERIOD = 3600;
-
- public void testLoadValidMavenProxyConfiguration()
- throws ValidationException, IOException
- {
- MavenProxyPropertyLoader loader = new MavenProxyPropertyLoader();
-
- //must create the test directory bec configuration is using relative path which varies
- FileUtils.mkdir( "target/remote-repo1" );
-
- try
- {
- File confFile = getTestFile( "src/test/conf/maven-proxy-complete.conf" );
-
- ProxyConfiguration config = loader.load( new FileInputStream( confFile ) );
-
- assertTrue( "cache path changed", config.getRepositoryCachePath().endsWith( "target" ) );
-
- assertEquals( "Count repositories", 4, config.getRepositories().size() );
-
- ProxyRepository repo = (ProxyRepository) config.getRepositories().get( 0 );
- assertEquals( "Repository name not as expected", "local-repo", repo.getKey() );
- assertEquals( "Repository url does not match its name", "file://target", repo.getUrl() );
- assertEquals( "Repository cache period check failed", 0, repo.getCachePeriod() );
- assertFalse( "Repository failure caching check failed", repo.isCacheFailures() );
-
- repo = (ProxyRepository) config.getRepositories().get( 1 );
- assertEquals( "Repository name not as expected", "www-ibiblio-org", repo.getKey() );
- assertEquals( "Repository url does not match its name", "http://www.ibiblio.org/maven2", repo.getUrl() );
- assertEquals( "Repository cache period check failed", DEFAULT_CACHE_PERIOD, repo.getCachePeriod() );
- assertTrue( "Repository failure caching check failed", repo.isCacheFailures() );
-
- repo = (ProxyRepository) config.getRepositories().get( 2 );
- assertEquals( "Repository name not as expected", "dist-codehaus-org", repo.getKey() );
- assertEquals( "Repository url does not match its name", "http://dist.codehaus.org", repo.getUrl() );
- assertEquals( "Repository cache period check failed", DEFAULT_CACHE_PERIOD, repo.getCachePeriod() );
- assertTrue( "Repository failure caching check failed", repo.isCacheFailures() );
-
- repo = (ProxyRepository) config.getRepositories().get( 3 );
- assertEquals( "Repository name not as expected", "private-example-com", repo.getKey() );
- assertEquals( "Repository url does not match its name", "http://private.example.com/internal",
- repo.getUrl() );
- assertEquals( "Repository cache period check failed", DEFAULT_CACHE_PERIOD, repo.getCachePeriod() );
- assertFalse( "Repository failure caching check failed", repo.isCacheFailures() );
- }
- finally
- {
- //make sure to delete the test directory after tests
- FileUtils.deleteDirectory( "target/remote-repo1" );
- }
- }
-
-}
+++ /dev/null
-package org.apache.maven.repository.proxy.configuration;\r
-\r
-/*\r
- * Copyright 2005-2006 The Apache Software Foundation.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;\r
-import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;\r
-import org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout;\r
-import org.apache.maven.repository.proxy.repository.ProxyRepository;\r
-import org.apache.maven.wagon.proxy.ProxyInfo;\r
-import org.codehaus.plexus.PlexusTestCase;\r
-\r
-import java.io.File;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-public class ProxyConfigurationTest\r
- extends PlexusTestCase\r
-{\r
- private ProxyConfiguration config;\r
-\r
- private static final int DEFAULT_CACHE_PERIOD = 3600;\r
-\r
- private static final int DEFAULT_PORT = 80;\r
-\r
- protected void setUp()\r
- throws Exception\r
- {\r
- super.setUp();\r
-\r
- config = new ProxyConfiguration();\r
- }\r
-\r
- public void testRepositoryCache()\r
- {\r
- File cacheFile = new File( "target/proxy-cache" );\r
- config.setRepositoryCachePath( cacheFile.getAbsolutePath() );\r
- assertEquals( config.getRepositoryCachePath(), cacheFile.getAbsolutePath() );\r
- }\r
-\r
- public void testRepositories()\r
- {\r
- ArtifactRepositoryLayout defLayout = new DefaultRepositoryLayout();\r
- ProxyRepository repo1 = new ProxyRepository( "repo1", "http://www.ibiblio.org/maven2", defLayout );\r
- repo1.setCacheFailures( true );\r
- repo1.setCachePeriod( 0 );\r
- repo1.setHardfail( true );\r
- config.addRepository( repo1 );\r
- assertEquals( 1, config.getRepositories().size() );\r
-\r
- ArtifactRepositoryLayout legacyLayout = new LegacyRepositoryLayout();\r
- ProxyRepository repo2 = new ProxyRepository( "repo2", "http://www.ibiblio.org/maven", legacyLayout );\r
- repo2.setCacheFailures( false );\r
- repo2.setCachePeriod( DEFAULT_CACHE_PERIOD );\r
- repo2.setProxied( true );\r
- config.setHttpProxy( "some.local.proxy", DEFAULT_PORT, "username", "password" );\r
- config.addRepository( repo2 );\r
- assertEquals( 2, config.getRepositories().size() );\r
-\r
- List repositories = config.getRepositories();\r
- ProxyRepository repo = (ProxyRepository) repositories.get( 0 );\r
- assertEquals( "repo1", repo.getId() );\r
- assertEquals( "http://www.ibiblio.org/maven2", repo.getUrl() );\r
- assertTrue( repo.isCacheFailures() );\r
- assertTrue( repo.isHardfail() );\r
- assertEquals( 0, repo.getCachePeriod() );\r
- assertEquals( repo1, repo );\r
-\r
- repo = (ProxyRepository) repositories.get( 1 );\r
- assertEquals( "repo2", repo.getId() );\r
- assertEquals( "http://www.ibiblio.org/maven", repo.getUrl() );\r
- assertFalse( repo.isCacheFailures() );\r
- assertTrue( repo.isHardfail() );\r
- assertEquals( DEFAULT_CACHE_PERIOD, repo.getCachePeriod() );\r
- assertEquals( repo2, repo );\r
- assertTrue( repo.isProxied() );\r
-\r
- ProxyInfo proxyInfo = config.getHttpProxy();\r
- assertNotNull( proxyInfo );\r
- assertEquals( "some.local.proxy", proxyInfo.getHost() );\r
- assertEquals( DEFAULT_PORT, proxyInfo.getPort() );\r
- assertEquals( "username", proxyInfo.getUserName() );\r
- assertEquals( "password", proxyInfo.getPassword() );\r
-\r
- try\r
- {\r
- repositories.add( new ProxyRepository( "repo", "url", defLayout ) );\r
- fail( "Expected UnsupportedOperationException not thrown." );\r
- }\r
- catch ( UnsupportedOperationException e )\r
- {\r
- assertTrue( true );\r
- }\r
-\r
- repositories = new ArrayList();\r
- repositories.add( repo1 );\r
- repositories.add( repo2 );\r
- config.setRepositories( repositories );\r
- assertEquals( repositories, config.getRepositories() );\r
- }\r
-\r
- public void testHttpProxy()\r
- throws Exception\r
- {\r
- config.setHttpProxy( "some.local.proxy", DEFAULT_PORT, "username", "password", "ntlmHost", "ntlmDomain" );\r
-\r
- ProxyInfo proxyInfo = config.getHttpProxy();\r
-\r
- assertEquals( "test proxy host", proxyInfo.getHost(), "some.local.proxy" );\r
- assertEquals( DEFAULT_PORT, proxyInfo.getPort() );\r
- assertEquals( "username", proxyInfo.getUserName() );\r
- assertEquals( "password", proxyInfo.getPassword() );\r
- assertEquals( "ntlmHost", proxyInfo.getNtlmHost() );\r
- assertEquals( "ntlmDomain", proxyInfo.getNtlmDomain() );\r
- }\r
-\r
- protected void tearDown()\r
- throws Exception\r
- {\r
- config = null;\r
-\r
- super.tearDown();\r
- }\r
-}
\ No newline at end of file
<build>
<finalName>maven-repository-webapp</finalName>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <!-- TODO! temporary until tests are fixed -->
- <skip>true</skip>
- </configuration>
- </plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>clean</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-maven-plugin</artifactId>
+++ /dev/null
-package org.apache.maven.repository.proxy.web.action;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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 com.opensymphony.xwork.Action;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.maven.repository.proxy.ProxyException;
-import org.apache.maven.repository.proxy.ProxyManager;
-import org.apache.maven.repository.proxy.configuration.MavenProxyPropertyLoader;
-import org.apache.maven.repository.proxy.configuration.ProxyConfiguration;
-import org.apache.maven.repository.proxy.configuration.ValidationException;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-/**
- * This is the Action class responsible for processing artifact request,
- * relies on the RestfulActionMapper to map the artifact request to this action.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="org.apache.maven.repository.manager.web.action.RepositoryProxyAction"
- */
-public class RepositoryProxyAction
- implements Action
-{
- /**
- * logger instance
- */
- protected static final Log log = LogFactory.getLog( RepositoryProxyAction.class );
-
- public static final String NOTFOUND = "notFound";
-
- public static final String PROXYERROR = "proxyError";
-
- /**
- * file requested by the client,
- * TODO: validate the requestd file using na interceptor
- */
- private String requestedFile;
-
- /**
- * main proxy logic
- *
- * @plexus.requirement role="org.apache.maven.repository.proxy.ProxyManager"
- */
- private ProxyManager repositoryProxyManager;
-
- /**
- * configuration for the ProxyManager
- *
- * @plexus.requirement
- */
- private ProxyConfiguration proxyConfig;
-
- /**
- * the inputstream for the artifact file
- */
- private FileInputStream artifactStream;
-
- /**
- * the cached artifact file
- */
- private File cachedFile;
-
- /**
- * proxy configuration file
- * TODO: recode the configuration part when Configuration is finalized
- * TODO: this is only temporary
- */
- private String configFile;
-
- // setters and getters
-
- public void setProxyManager( ProxyManager manager )
- {
- repositoryProxyManager = manager;
- }
-
- public void setRequestedFile( String reqFile )
- {
- requestedFile = reqFile;
- }
-
- public String getRequestedFile()
- {
- return requestedFile;
- }
-
- public FileInputStream getArtifactStream()
- {
- return artifactStream;
- }
-
- public File getCachedFile()
- {
- return cachedFile;
- }
-
- public void setConfigFile( String fileName )
- {
- configFile = fileName;
- }
-
- /**
- * entry-point
- */
- public String execute()
- throws MalformedURLException, IOException, ValidationException
- {
- try
- {
- MavenProxyPropertyLoader loader = new MavenProxyPropertyLoader();
- proxyConfig = loader.load( new FileInputStream( configFile ) );
- repositoryProxyManager.setConfiguration( proxyConfig );
- cachedFile = repositoryProxyManager.get( requestedFile );
- artifactStream = new FileInputStream( cachedFile );
- }
- catch ( ResourceDoesNotExistException ex )
- {
- log.info( "[not found] " + ex.getMessage() );
- return NOTFOUND;
- }
- catch ( ProxyException ex )
- {
- log.info( "[proxy error] " + ex.getMessage() );
- return PROXYERROR;
- }
- catch ( FileNotFoundException ex )
- {
- log.info( "[not found] " + ex.getMessage() );
- return NOTFOUND;
- }
-
- return SUCCESS;
- }
-}
+++ /dev/null
-package org.apache.maven.repository.proxy.web.action.test;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.repository.proxy.web.action.RepositoryProxyAction;
-import org.apache.maven.repository.proxy.web.action.test.stub.ProxyManagerStub;
-import org.codehaus.plexus.PlexusTestCase;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.Properties;
-
-public class RepositoryProxyActionTest
- extends PlexusTestCase
-{
-
- /**
- * test basic proxy operation
- *
- * @throws Exception
- */
- public void testProxy()
- throws Exception
- {
- String testDir = getBasedir() + "/target/test-classes/unit/proxy-test";
- RepositoryProxyAction action = new RepositoryProxyAction();
- ProxyManagerStub proxyManager = new ProxyManagerStub( testDir );
- File cachedFile = proxyManager.get( "dummyFile" );
-
- if ( !cachedFile.getParentFile().exists() )
- {
- assertTrue( "can not create test file", cachedFile.getParentFile().mkdirs() );
- }
-
- if ( !cachedFile.exists() )
- {
- assertTrue( "can not create test file", cachedFile.createNewFile() );
- }
-
- File tmpDir = getTestFile( "target/tmp-repo" );
- tmpDir.mkdirs();
-
- // TODO: configure manually, test the property loader elsewhere
- Properties properties = new Properties();
- properties.load( getClass().getResourceAsStream( "/unit/proxy-test/maven-proxy-complete.conf" ) );
- properties.setProperty( "repo.local.store", tmpDir.getAbsolutePath() );
- File tempFile = File.createTempFile( "test", "tmp" );
- tempFile.deleteOnExit();
- properties.store( new FileOutputStream( tempFile ), "" );
-
- action.setConfigFile( tempFile.getAbsolutePath() );
- action.setProxyManager( proxyManager );
-
- String result = action.execute();
- FileInputStream fileStream = action.getArtifactStream();
-
- assertEquals( "proxy error", action.SUCCESS, result );
- assertNotNull( "inputstream not set", fileStream );
- assertNotNull( "cached file not set", action.getCachedFile() );
- assertTrue( "proxy error", cachedFile.getPath().equals( action.getCachedFile().getPath() ) );
- }
-}
+++ /dev/null
-package org.apache.maven.repository.proxy.web.action.test.stub;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.repository.proxy.ProxyManager;
-import org.apache.maven.repository.proxy.configuration.ProxyConfiguration;
-
-import java.io.File;
-
-public class ProxyManagerStub
- implements ProxyManager
-{
- String baseDir;
-
- public ProxyManagerStub( String base )
- {
- baseDir = base;
- }
-
- public File get( String requestFile )
- {
- return new File( baseDir, "proxy-cache/test-0.0.jar" );
- }
-
- public File getRemoteFile( String reqFile )
- {
- return new File( baseDir, "proxy-chache/test-0.0.jar" );
- }
-
- public void setConfiguration( ProxyConfiguration config )
- {
- // do nothing
- }
-
- public ProxyConfiguration getConfiguration()
- {
- return null;
- }
-
- public File getAlways( String name )
- {
- return null;
- }
-}
</reporting>
<profiles>
<profile>
- <id>ciProfile</id>
+ <id>ci</id>
<activation>
<property>
<name>enableCiProfile</name>