From dc7e193c065b5b5bd13c7f44a6c7849abb7d562e Mon Sep 17 00:00:00 2001 From: "Edwin L. Punzalan" Date: Wed, 15 Feb 2006 08:56:29 +0000 Subject: [PATCH] PR: MRM-62 Allowed the ProxyConfiguration object to read the maven-proxy configuration by copying codes from the maven-proxy source itself git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@377968 13f79535-47bb-0310-9956-ffa450edef68 --- .../configuration/FileRepoConfiguration.java | 50 +++ .../GlobalRepoConfiguration.java | 14 + .../configuration/HttpRepoConfiguration.java | 64 ++++ .../MavenProxyConfiguration.java | 54 +++ .../MavenProxyPropertyLoader.java | 319 ++++++++++++++++++ .../MavenProxyRepoConfiguration.java | 30 ++ .../configuration/ProxyConfiguration.java | 37 ++ .../configuration/RepoConfiguration.java | 110 ++++++ .../RetrievalComponentConfiguration.java | 311 +++++++++++++++++ .../configuration/ValidationException.java | 40 +++ .../src/test/conf/maven-proxy-complete.conf | 144 ++++++++ .../configuration/ProxyConfigurationTest.java | 36 ++ 12 files changed, 1209 insertions(+) create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/FileRepoConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/GlobalRepoConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/HttpRepoConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyPropertyLoader.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyRepoConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RepoConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RetrievalComponentConfiguration.java create mode 100644 maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ValidationException.java create mode 100644 maven-repository-proxy/src/test/conf/maven-proxy-complete.conf diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/FileRepoConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/FileRepoConfiguration.java new file mode 100644 index 000000000..000e15944 --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/FileRepoConfiguration.java @@ -0,0 +1,50 @@ +package org.apache.maven.repository.proxy.configuration; + +/* + * Copyright 2003-2004 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 java.io.File; + +/** + * Strips file:/// off the front of the configured URL and uses that to find files locally. + * + * @author Ben Walding + */ +public class FileRepoConfiguration + extends RepoConfiguration +{ + private final String basePath; + + public FileRepoConfiguration( String key, String url, String description, boolean copy, boolean hardFail, + boolean cacheFailures, long cachePeriod ) + { + super( key, url, description, copy, hardFail, cacheFailures, cachePeriod ); + basePath = url.substring( 8 ); + } + + public String getBasePath() + { + return basePath; + } + + /** + * Given a relative path, returns the absolute file in the repository + */ + public File getLocalFile( String path ) + { + return new File( basePath + path ); + } +} \ No newline at end of file diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/GlobalRepoConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/GlobalRepoConfiguration.java new file mode 100644 index 000000000..23cf8241d --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/GlobalRepoConfiguration.java @@ -0,0 +1,14 @@ +package org.apache.maven.repository.proxy.configuration; + +/** + * @author Ben Walding + */ +public class GlobalRepoConfiguration + extends FileRepoConfiguration +{ + public GlobalRepoConfiguration( String basePath ) + { + super( "global", "file:///" + basePath, "Global Repository", false, true, false, 0 ); + } + +} \ No newline at end of file diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/HttpRepoConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/HttpRepoConfiguration.java new file mode 100644 index 000000000..a7f4510c5 --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/HttpRepoConfiguration.java @@ -0,0 +1,64 @@ +package org.apache.maven.repository.proxy.configuration; + +/* + * Copyright 2003-2004 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 HttpRepoConfiguration + extends RepoConfiguration +{ + private final String username; + + private final String password; + + private final MavenProxyConfiguration proxy; + + public HttpRepoConfiguration( String key, String url, String description, String username, String password, + boolean hardFail, MavenProxyConfiguration proxy, boolean cacheFailures, + long cachePeriod ) + { + super( key, url, description, true, hardFail, cacheFailures, cachePeriod ); + this.username = username; + this.password = password; + this.proxy = proxy; + } + + /** + * + */ + public String getPassword() + { + return password; + } + + /** + * + */ + public String getUsername() + { + return username; + } + + /** + * + */ + public MavenProxyConfiguration getProxy() + { + return proxy; + } +} \ No newline at end of file diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyConfiguration.java new file mode 100644 index 000000000..7ee4164a4 --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyConfiguration.java @@ -0,0 +1,54 @@ +package org.apache.maven.repository.proxy.configuration; + +/** + * Immutable. + * + * @author Ben Walding + */ +public class MavenProxyConfiguration +{ + private final String key; + + private final String host; + + private final int port; + + private final String username; + + private final String password; + + public MavenProxyConfiguration( String key, String host, int port, String username, String password ) + { + this.key = key; + this.host = host; + this.port = port; + this.username = username; + this.password = password; + } + + public String getHost() + { + return host; + } + + public String getKey() + { + return key; + } + + public String getPassword() + { + return password; + } + + public int getPort() + { + return port; + } + + public String getUsername() + { + return username; + } + +} diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyPropertyLoader.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyPropertyLoader.java new file mode 100644 index 000000000..4e56a39c7 --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyPropertyLoader.java @@ -0,0 +1,319 @@ +package org.apache.maven.repository.proxy.configuration; + +/* + * Copyright 2003-2004 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 java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; + +/** + * @author Ben Walding + */ +public class MavenProxyPropertyLoader +{ + + public static final String REPO_LOCAL_STORE = "repo.local.store"; + + public static final String REPO_CUSTOM_STORE = "repo.custom.store"; + + public static final String PORT = "port"; + + public static final String SNAPSHOT_UPDATE = "snapshot.update"; + + public static final String SNAPSHOT_CACHE_FAILURES = "snapshot.cache.failures"; + + public static final String METADATA_UPDATE = "metadata.update"; + + public static final String POM_UPDATE = "pom.update"; + + public static final int DEFAULT_PORT = 4321; + + public static final String LAST_MODIFIED_DATE_FORMAT = "lastModifiedDateFormat"; + + public static final String DEFAULT_LAST_MODIFIED_DATE_FORMAT = null; + + public static final String BROWSABLE = "browsable"; + + public static final String SEARCHABLE = "searchable"; + + public static final String STYLESHEET = "stylesheet"; + + public static final String BGCOLOR = "css.bgColor"; + + public static final String BGCOLORHIGHLIGHT = "css.bgColorHighlight"; + + public static final String ROWCOLOR = "css.rowColor"; + + public static final String ROWCOLORHIGHLIGHT = "css.rowColorHighlight"; + + public static final String PREFIX = "prefix"; + + private static final String SERVERNAME = "serverName"; + + public RetrievalComponentConfiguration load( Properties props ) + throws ValidationException + { + RetrievalComponentConfiguration rcc = new RetrievalComponentConfiguration(); + + String localStore = getMandatoryProperty( props, REPO_LOCAL_STORE ); + GlobalRepoConfiguration globalRepo = new GlobalRepoConfiguration( localStore ); + rcc.setLocalStore( localStore ); + rcc.addRepo( globalRepo ); + + if ( props.getProperty( PORT ) == null ) + { + rcc.setPort( DEFAULT_PORT ); + } + else + { + try + { + rcc.setPort( Integer.parseInt( props.getProperty( PORT ) ) ); + } + catch ( NumberFormatException ex ) + { + throw new ValidationException( "Property " + PORT + " must be a integer" ); + } + } + + rcc.setSnapshotUpdate( Boolean.valueOf( getMandatoryProperty( props, SNAPSHOT_UPDATE ) ).booleanValue() ); + rcc.setMetaDataUpdate( + Boolean.valueOf( getOptionalProperty( props, METADATA_UPDATE, "true" ) ).booleanValue() ); + rcc.setPOMUpdate( Boolean.valueOf( getOptionalProperty( props, POM_UPDATE, "false" ) ).booleanValue() ); + + rcc.setBrowsable( Boolean.valueOf( getMandatoryProperty( props, BROWSABLE ) ).booleanValue() ); + rcc.setSearchable( Boolean.valueOf( getOptionalProperty( props, SEARCHABLE, "true" ) ).booleanValue() ); + rcc.setServerName( props.getProperty( SERVERNAME ) ); + rcc.setPrefix( getMandatoryProperty( props, PREFIX ) ); + rcc.setLastModifiedDateFormat( props.getProperty( LAST_MODIFIED_DATE_FORMAT ) ); + rcc.setStylesheet( getOptionalProperty( props, STYLESHEET, null ) ); + rcc.setBgColor( getOptionalProperty( props, BGCOLOR, "#14B" ) ); + rcc.setBgColorHighlight( getOptionalProperty( props, BGCOLORHIGHLIGHT, "#9BF" ) ); + rcc.setRowColor( getOptionalProperty( props, ROWCOLOR, "#CCF" ) ); + rcc.setRowColorHighlight( getOptionalProperty( props, ROWCOLORHIGHLIGHT, "#DDF" ) ); + + if ( rcc.getPrefix().length() == 0 ) + { + System.err.println( "Using an empty 'prefix' is deprecated behaviour. Please set a prefix." ); + } + + { + String propertyList = props.getProperty( "proxy.list" ); + if ( propertyList != null ) + { + StringTokenizer tok = new StringTokenizer( propertyList, "," ); + while ( tok.hasMoreTokens() ) + { + String key = tok.nextToken(); + 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" ); + MavenProxyConfiguration pc = new MavenProxyConfiguration( key, host, port, username, password ); + rcc.addProxy( pc ); + } + } + } + + { + 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" ); + // the username, password and proxy are not mandatory + String username = repoProps.getProperty( "username" ); + String password = repoProps.getProperty( "password" ); + String description = repoProps.getProperty( "description" ); + String proxyKey = repoProps.getProperty( "proxy" ); + + Boolean cacheFailures = Boolean.valueOf( repoProps.getProperty( "cache.failures", "false" ) ); + Long cachePeriod = Long.valueOf( repoProps.getProperty( "cache.period", "0" ) ); + Boolean hardFail = Boolean.valueOf( repoProps.getProperty( "hardfail", "true" ) ); + + MavenProxyConfiguration proxy = null; + if ( proxyKey != null ) + { + proxy = rcc.getProxy( proxyKey ); + } + + if ( description == null || description.trim().length() == 0 ) + { + description = key; + } + + RepoConfiguration rc = null; + + if ( url.startsWith( "http://" ) ) + { + rc = new HttpRepoConfiguration( key, url, description, username, password, hardFail.booleanValue(), + proxy, cacheFailures.booleanValue(), cachePeriod.longValue() ); + } + + if ( url.startsWith( "file:///" ) ) + { + boolean copy = "true".equalsIgnoreCase( repoProps.getProperty( "copy" ) ); + rc = new FileRepoConfiguration( key, url, description, copy, hardFail.booleanValue(), cacheFailures + .booleanValue(), cachePeriod.longValue() ); + } + + if ( rc == null ) + { + throw new ValidationException( "Unknown upstream repository type: " + url ); + } + + rcc.addRepo( rc ); + } + } + validateDirectories( rcc ); + validateLocalRepo( rcc ); + validateRemoteRepo( rcc ); + return rcc; + + } + + /** + * Checks to make sure a specific value is set + * + * @throws ValidationException if value is null + */ + private String checkSet( String value, String propertyName ) + throws ValidationException + { + if ( value == null ) + { + throw new ValidationException( "Missing property '" + propertyName + "'" ); + } + + return value; + } + + private void validateLocalRepo( RetrievalComponentConfiguration rcc ) + throws ValidationException + { + //Verify local repository set + String tmp = checkSet( rcc.getLocalStore(), MavenProxyPropertyLoader.REPO_LOCAL_STORE ); + + File file = new File( tmp ); + if ( !file.exists() ) + { + throw new ValidationException( "The local repository doesn't exist: " + file.getAbsolutePath() ); + } + + if ( !file.isDirectory() ) + { + throw new ValidationException( "The local repository must be a directory: " + file.getAbsolutePath() ); + } + } + + private void validateRemoteRepo( RetrievalComponentConfiguration rcc ) + throws ValidationException + { + //Verify remote repository set + //only warn if missing + if ( rcc.getRepos().size() < 1 ) + { + throw new ValidationException( "At least one remote repository must be configured." ); + } + } + + 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 RetrievalComponentConfiguration 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 + { + final String value = props.getProperty( key ); + + if ( value == null ) + { + throw new ValidationException( "Missing property: " + key ); + } + + return value; + } + + private String getOptionalProperty( Properties props, String key, String defaultValue ) + { + final String value = props.getProperty( key ); + + if ( value == null ) + { + return defaultValue; + } + + return value; + } + + private void validateDirectories( RetrievalComponentConfiguration rcc ) + throws ValidationException + { + File f = new File( rcc.getLocalStore() ); + if ( !f.exists() ) + { + throw new ValidationException( "Specified directory does not exist: " + f.getAbsolutePath() ); + } + + List repos = rcc.getRepos(); + for ( Iterator iter = repos.iterator(); iter.hasNext(); ) + { + RepoConfiguration repo = (RepoConfiguration) iter.next(); + if ( repo instanceof FileRepoConfiguration ) + { + FileRepoConfiguration fileRepo = (FileRepoConfiguration) repo; + File f2 = new File( fileRepo.getBasePath() ); + if ( !f2.exists() ) + { + throw new ValidationException( "Specified directory does not exist: " + f2.getAbsolutePath() ); + } + } + } + } + +} \ No newline at end of file diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyRepoConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyRepoConfiguration.java new file mode 100644 index 000000000..e6b3ed43e --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/MavenProxyRepoConfiguration.java @@ -0,0 +1,30 @@ +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 Edwin Punzalan + */ +public class MavenProxyRepoConfiguration + extends RepoConfiguration +{ + public MavenProxyRepoConfiguration( String key, String url, String description, boolean copy, boolean hardFail, + boolean cacheFailures, long cachePeriod ) + { + super( key, url, description, copy, hardFail, cacheFailures, cachePeriod ); + } +} diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ProxyConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ProxyConfiguration.java index 0d5732a9a..1c1bda993 100644 --- a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ProxyConfiguration.java +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ProxyConfiguration.java @@ -24,8 +24,11 @@ import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.repository.proxy.repository.ProxyRepository; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; /** @@ -138,4 +141,38 @@ public class ProxyConfiguration { this.repositories = repositories; } + + /** + * Uses maven-proxy classes to read a maven-proxy properties configuration + * + * @param mavenProxyConfigurationFile The location of the maven-proxy configuration file + * @throws ValidationException When a problem occured while processing the properties file + * @throws IOException When a problem occured while reading the property file + */ + public void loadMavenProxyConfiguration( File mavenProxyConfigurationFile ) + throws ValidationException, IOException + { + MavenProxyPropertyLoader loader = new MavenProxyPropertyLoader(); + RetrievalComponentConfiguration rcc = loader.load( new FileInputStream( mavenProxyConfigurationFile ) ); + + this.setRepositoryCachePath( rcc.getLocalStore() ); + this.setBrowsable( rcc.isBrowsable() ); + + List repoList = new ArrayList(); + ArtifactRepositoryLayout layout = new DefaultRepositoryLayout(); + for ( Iterator repos = rcc.getRepos().iterator(); repos.hasNext(); ) + { + RepoConfiguration repoConfig = (RepoConfiguration) repos.next(); + + //skip local store repo + if ( !repoConfig.getKey().equals( "global" ) ) + { + ProxyRepository repo = new ProxyRepository( repoConfig.getKey(), repoConfig.getUrl(), layout ); + + repoList.add( repo ); + } + } + + this.setRepositories( repoList ); + } } diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RepoConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RepoConfiguration.java new file mode 100644 index 000000000..e3783d163 --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RepoConfiguration.java @@ -0,0 +1,110 @@ +package org.apache.maven.repository.proxy.configuration; + +/* + * Copyright 2003-2004 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.logging.AbstractLogEnabled; + +/** + * Immutable. + *

+ * hardfail - if a repository is set to hard fail, then the download engine will terminate the whole download + * process (with a status 500) if any of the repositories have unexpected errors. + *

+ * if a repository expects an error - eg. 400 (not found) - then it is not required to terminate the + * download process. + * + * @author Ben Walding + */ +public abstract class RepoConfiguration + extends AbstractLogEnabled +{ + private final String key; + + private final String description; + + private final String url; + + private final boolean copy; + + private final boolean hardFail; + + private final boolean cacheFailures; + + private final long cachePeriod; + + public RepoConfiguration( String key, String url, String description, boolean copy, boolean hardFail, + boolean cacheFailures, long cachePeriod ) + { + this.key = key; + this.url = url; + this.description = description; + this.copy = copy; + this.hardFail = hardFail; + this.cacheFailures = cacheFailures; + this.cachePeriod = cachePeriod; + } + + /** + * + */ + public String getUrl() + { + return url; + } + + /** + * + */ + public String getKey() + { + return key; + } + + /** + * If a file repository is set to "copy" mode, it will copy the found files into + * the main repository store. + */ + public boolean getCopy() + { + return copy; + } + + public String getDescription() + { + return description; + } + + public boolean getHardFail() + { + return hardFail; + } + + public boolean getCacheFailures() + { + return cacheFailures; + } + + public long getCachePeriod() + { + return cachePeriod; + } + + public String toString() + { + return "Repo[" + getKey() + "]"; + } +} \ No newline at end of file diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RetrievalComponentConfiguration.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RetrievalComponentConfiguration.java new file mode 100644 index 000000000..e4a0fa39e --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/RetrievalComponentConfiguration.java @@ -0,0 +1,311 @@ +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 java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +/** + * @author Ben Walding + */ +public class RetrievalComponentConfiguration +{ + private final Map proxies = new HashMap(); + + private final List repos = new ArrayList(); + + private String localStore; + + private String serverName; + + private String bgColor; + + private String bgColorHighlight; + + private String rowColor; + + private String rowColorHighlight; + + private String stylesheet; + + private boolean searchable; + + private boolean browsable; + + private int port; + + private String prefix; + + private boolean snapshotUpdate; + + private boolean metaDataUpdate; + + private boolean pomUpdate; + + private String lastModifiedDateFormat; + + public String getPrefix() + { + return prefix; + } + + public void setPrefix( String prefix ) + { + this.prefix = prefix; + } + + /** + * @return + */ + public boolean isBrowsable() + { + return browsable; + } + + /** + * @param browsable + */ + public void setBrowsable( boolean browsable ) + { + this.browsable = browsable; + } + + public int getPort() + { + return port; + } + + public void setPort( int port ) + { + this.port = port; + } + + /** + * @return + */ + public String getLocalStore() + { + return localStore; + } + + /** + * @param localStore + */ + public void setLocalStore( String localStore ) + { + this.localStore = localStore; + } + + public void addProxy( MavenProxyConfiguration pc ) + { + proxies.put( pc.getKey(), pc ); + } + + public void removeProxy( String key ) + { + proxies.remove( key ); + } + + public MavenProxyConfiguration getProxy( String key ) + { + return (MavenProxyConfiguration) proxies.get( key ); + } + + /** + * There is no specific order to proxy configuration. + * + * @return + */ + public List getProxies() + { + return new ArrayList( proxies.values() ); + } + + public void addRepo( RepoConfiguration repo ) + { + repos.add( repo ); + } + + public List getRepos() + { + return Collections.unmodifiableList( repos ); + } + + public String getServerName() + { + return serverName; + } + + public void setServerName( String serverName ) + { + this.serverName = serverName; + } + + public void setSnapshotUpdate( boolean snapshotUpdate ) + { + this.snapshotUpdate = snapshotUpdate; + } + + public boolean getSnapshotUpdate() + { + return snapshotUpdate; + } + + public void setMetaDataUpdate( boolean metaDataUpdate ) + { + this.metaDataUpdate = metaDataUpdate; + } + + public boolean getMetaDataUpdate() + { + return metaDataUpdate; + } + + public void setPOMUpdate( boolean pomUpdate ) + { + this.pomUpdate = pomUpdate; + } + + public boolean getPOMUpdate() + { + return pomUpdate; + } + + public String getLastModifiedDateFormat() + { + return lastModifiedDateFormat; + } + + public void setLastModifiedDateFormat( String lastModifiedDateFormat ) + { + this.lastModifiedDateFormat = lastModifiedDateFormat; + } + + public boolean isSearchable() + { + return searchable; + } + + public void setSearchable( boolean searchable ) + { + this.searchable = searchable; + } + + /** + * @return the global repo configuration + */ + public GlobalRepoConfiguration getGlobalRepo() + { + for ( Iterator iter = repos.iterator(); iter.hasNext(); ) + { + RepoConfiguration repo = (RepoConfiguration) iter.next(); + if ( repo instanceof GlobalRepoConfiguration ) + { + return (GlobalRepoConfiguration) repo; + } + } + return null; + } + + private ThreadLocal dateFormatThreadLocal = new ThreadLocal() + { + protected synchronized Object initialValue() + { + DateFormat df; + + if ( getLastModifiedDateFormat() == null || getLastModifiedDateFormat() == "" ) + { + df = new SimpleDateFormat(); + } + else + { + df = new SimpleDateFormat( getLastModifiedDateFormat() ); + } + + df.setTimeZone( TimeZone.getTimeZone( "GMT" ) ); + return df; + } + }; + + /** + * Retrieves and casts the appropriate DateFormat object from a ThreadLocal + * + * @return + */ + public DateFormat getLastModifiedDateFormatForThread() + { + return (DateFormat) dateFormatThreadLocal.get(); + } + + public String getBgColor() + { + return bgColor; + } + + public void setBgColor( String bgColor ) + { + this.bgColor = bgColor; + } + + public String getBgColorHighlight() + { + return bgColorHighlight; + } + + public void setBgColorHighlight( String bgColorHighlight ) + { + this.bgColorHighlight = bgColorHighlight; + } + + public String getStylesheet() + { + return stylesheet; + } + + public void setStylesheet( String stylesheet ) + { + this.stylesheet = stylesheet; + } + + public String getRowColor() + { + return rowColor; + } + + public void setRowColor( String rowColor ) + { + this.rowColor = rowColor; + } + + public String getRowColorHighlight() + { + return rowColorHighlight; + } + + public void setRowColorHighlight( String rowColorHighlight ) + { + this.rowColorHighlight = rowColorHighlight; + } + +} \ No newline at end of file diff --git a/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ValidationException.java b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ValidationException.java new file mode 100644 index 000000000..6f1ca364b --- /dev/null +++ b/maven-repository-proxy/src/main/java/org/apache/maven/repository/proxy/configuration/ValidationException.java @@ -0,0 +1,40 @@ +package org.apache.maven.repository.proxy.configuration; + +/* + * Copyright 2003-2004 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 ); + } +} diff --git a/maven-repository-proxy/src/test/conf/maven-proxy-complete.conf b/maven-repository-proxy/src/test/conf/maven-proxy-complete.conf new file mode 100644 index 000000000..c7722a864 --- /dev/null +++ b/maven-repository-proxy/src/test/conf/maven-proxy-complete.conf @@ -0,0 +1,144 @@ +################ GLOBAL SETTINGS +# This is where maven-proxy stores files it has downloaded +repo.local.store=target + +#The port to listen on - not used if loaded as a webapp +port=9999 + +#This is the base area that all files are loaded from. While it is possible to leave this blank, this behaviour +#is deprecated and will be disabled in version 2.0. There are too many namespace conflicts caused by not using +#a prefix. +#The repository will be shown at http://localhost:9999/repository/ +#for the .war loaded into a webapp server, the default prefix is "repository" (edit the web.xml to change) +# As maven doesn't like a trailing slash, this address shouldn't have one either. +prefix=repository + +#This is the simple date format used to display the last modified date while browsing the repository. +lastModifiedDateFormat=yyyy/MM/dd HH:mm:ss + +################ SNAPSHOT HANDLING +#If you want the proxy to look for newer snapshots, set to true +snapshot.update=true + +################ M2 METADATA HANDLING +#If you want the proxy to prevent looking for newer metadata, set to false (default is true) +#metadata.update=false + +################ M2 POM HANDLING +#If you want the proxy to look for newer POMs, set to true (default is false) +pom.update=true + +################ PROMOTION HANDLING +# ***** NOT CURRENTLY IMPLEMENTED ***** +#Promotion describes the process by which new artifacts are loaded to global maven-proxy repository. It +# is designed to be used by "higher security installations" that do not want to acquire artifacts from +# remote repositories without approval. +# +#If promotion handling is enabled, then the proxy will not download remote artifacts without permission +# (local repositories with copy=false are considered to be local) +# +#Permission to download is granted via the Promotion menu which will be enabled +# when promotion handling is enabled. +# +#If promotion is false, artifacts are sourced from any repository as per normal. +# +#Promotion and snapshots: If promotion is enabled, snapshots are not downloadable. The concept of using +# a snapshot in a production build (which is primarily what promotion is for) is counterintuitive. +## +promotion=false + +################ WEB INTERFACE +# This defines the absolute URL the server should use to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# The prefix will be added to this for the actual repository +# i.e. proxy available at http://localhost:9999/, repository at http://localhost:9999/repository +serverName=http://localhost:9999 + +#If true, the repository can be browsed +browsable=true + +#If true, the repository can be searched +searchable=true + +#Not currently implemented. Will allow webdav access to the repository at some point. +webdav=true + +#Stylesheet - if configured, will override the default stylesheet shipped with maven-proxy - absolute URLs only +#eg. /maven-proxy/style.css, http://www.example.com/style.css +stylesheet=/maven-proxy/style.css + +#bgColor / bgColorHighlight are replaced in the built in stylesheet to produce a simple color scheme. +#If a stylesheet is set, these are not used. +bgColor=#14B +bgColorHighlight=#94B + +#rowColor / rowColorHighlight are replaced in the built in stylesheet to produce a simple color scheme. +#If a stylesheet is set, these are not used. +rowColor=#CCF +rowColorHighlight=#DDF + + +################ PROXIES +#This is just a hack, it should auto discover them +proxy.list=one,two,three + +#Unauthenticated proxy +proxy.one.host=proxy1.example.com +proxy.one.port=3128 + +#Authenticated proxy +proxy.two.host=proxy2.example.org +proxy.two.port=80 +proxy.two.username=username2 +proxy.two.password=password2 + +#Authenticated proxy +proxy.three.host=proxy3.example.net +proxy.three.port=3129 +proxy.three.username=username3 +proxy.three.password=password3 + + +################# REPOSITORIES +#This is not just a hack, it specifies the order repositories should be checked +#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/" +repo.list=local-repo,www-ibiblio-org,dist-codehaus-org,private-example-com + +#local-store +# The local store represents a location that local jars you host can be located. +# This could also be achieved by having a local http repository, but this is less cumbersome +repo.local-repo.url=file:///./src/test/remote-repo1 +repo.local-repo.description=Super Secret Custom Repository +#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos +repo.local-repo.copy=false +#If hardfail is true, any unexpected errors from the repository will cause +#the client download to fail (typically with a 500 error) +repo.local-repo.hardfail=true +#Don't cache a file repository +repo.local-repo.cache.period=0 + + +#www.ibiblio.org +repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2 +repo.www-ibiblio-org.description=www.ibiblio.org +repo.www-ibiblio-org.proxy=one +repo.www-ibiblio-org.hardfail=true +#Cache this repository for 1 hour +repo.www-ibiblio-org.cache.period=3600 +repo.www-ibiblio-org.cache.failures=true + +#dist.codehaus.org +repo.dist-codehaus-org.url=http://dist.codehaus.org +repo.dist-codehaus-org.proxy=two +repo.dist-codehaus-org.hardfail=false +repo.dist-codehaus-org.cache.period=3600 +repo.dist-codehaus-org.cache.failures=true + +#private.example.com +repo.private-example-com.url=http://private.example.com/internal +repo.private-example-com.description=Commercial In Confidence Repository +repo.private-example-com.username=username1 +repo.private-example-com.password=password1 +repo.private-example-com.proxy=three +repo.private-example-com.cache.period=3600 diff --git a/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java index 65082a0e3..3900c0278 100644 --- a/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java +++ b/maven-repository-proxy/src/test/java/org/apache/maven/repository/proxy/configuration/ProxyConfigurationTest.java @@ -24,7 +24,9 @@ import org.apache.maven.repository.proxy.repository.ProxyRepository; import org.codehaus.plexus.PlexusTestCase; import java.io.File; +import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class ProxyConfigurationTest @@ -92,6 +94,40 @@ public class ProxyConfigurationTest assertEquals( repositories, config.getRepositories() ); } + public void testLoadValidMavenProxyConfiguration() + throws ValidationException, IOException + { + File confFile = new File( "src/test/conf/maven-proxy-complete.conf" ); + + config.loadMavenProxyConfiguration( confFile ); + + assertTrue( config.getRepositoryCachePath().endsWith( "target" ) ); + + assertEquals( "Count repositories", 4, config.getRepositories().size() ); + + for ( Iterator repos = config.getRepositories().iterator(); repos.hasNext(); ) + { + ProxyRepository repo = (ProxyRepository) repos.next(); + + if ( "local-repo".equals( repo.getKey() ) ) + { + assertEquals( "file:///./src/test/remote-repo1", repo.getUrl() ); + } + else if ( "www-ibiblio-org".equals( repo.getKey() ) ) + { + assertEquals( "http://www.ibiblio.org/maven2", repo.getUrl() ); + } + else if ( "dist-codehaus-org".equals( repo.getKey() ) ) + { + assertEquals( "http://dist.codehaus.org", repo.getUrl() ); + } + else if ( "private-example-com".equals( repo.getKey() ) ) + { + assertEquals( "http://private.example.com/internal", repo.getUrl() ); + } + } + } + protected void tearDown() throws Exception { -- 2.39.5