mcconnell 2003/11/26 06:11:40
Modified: repository/impl/src/java/org/apache/avalon/repository/impl
DefaultFactory.java
repository/main/src/java/org/apache/avalon/repository/main
Bootstrapper.java InitialRepositoryFactory.java
repository/spi/src/java/org/apache/avalon/repository/criteria
Criteria.java Factory.java
repository/test/src/test/org/apache/avalon/repository/main
InitialRepositoryFactoryTest.java
Added: repository/impl/src/java/org/apache/avalon/repository/impl
RepositoryCriteria.java
Removed: repository/impl/src/java/org/apache/avalon/repository/impl
DefaultRepositoryCriteria.java
Log:
Improve criteria handling and friendliness by defining Criteria as a Map
implementation.
Revision Changes Path
1.12 +5 -16
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFactory.java
Index: DefaultFactory.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFactory.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- DefaultFactory.java 26 Nov 2003 01:16:56 -0000 1.11
+++ DefaultFactory.java 26 Nov 2003 14:11:39 -0000 1.12
@@ -70,7 +70,6 @@
import org.apache.avalon.repository.Repository ;
import org.apache.avalon.repository.RepositoryException ;
import org.apache.avalon.repository.RepositoryRuntimeException;
-import org.apache.avalon.repository.factory.RepositoryCriteria ;
import org.apache.avalon.repository.criteria.Factory ;
import org.apache.avalon.repository.criteria.Criteria ;
import org.apache.avalon.repository.criteria.Parameter ;
@@ -83,7 +82,7 @@
* The default repository factory implementation.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Alex Karasulu</a>
- * @author $Author$
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision$
*/
public class DefaultFactory implements Factory
@@ -103,11 +102,11 @@
* Create a new instance of the default criteria.
* @return a new default criteria instance
*/
- public Criteria createDefaultCriteria()
+ public Map createDefaultCriteria()
{
try
{
- return new DefaultRepositoryCriteria();
+ return new RepositoryCriteria();
}
catch( Throwable e )
{
@@ -123,17 +122,7 @@
*/
public Object create()
{
- return create( createDefaultCriteria().getMap() );
- }
-
- /**
- * Create a new instance of an application.
- * @param criteria the creation criteria
- * @return the application instance
- */
- public Object create( Criteria criteria )
- {
- return create( criteria.getMap() );
+ return create( createDefaultCriteria() );
}
/**
1.1
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/RepositoryCriteria.java
Index: RepositoryCriteria.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact [EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.repository.impl;
import java.io.IOException;
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
import java.util.Hashtable;
import java.util.Map;
import java.net.URL;
import java.net.MalformedURLException;
import org.apache.avalon.repository.RepositoryException;
import org.apache.avalon.repository.criteria.Criteria;
import org.apache.avalon.repository.criteria.Parameter;
import org.apache.avalon.repository.criteria.ValidationException;
import org.apache.avalon.defaults.Defaults;
import org.apache.avalon.defaults.DefaultsFinder;
import org.apache.avalon.defaults.SimpleDefaultsFinder;
import org.apache.avalon.defaults.SystemDefaultsFinder;
/**
* A Criteria is a class holding the values supplied by a user
* for application to a factory.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $
*/
public class RepositoryCriteria extends Criteria
{
//--------------------------------------------------------------
// static
//--------------------------------------------------------------
public static final File USER_HOME = new File( System.getProperty( "user.home"
)) ;
/**
* Repository cache directory parameter descriptor.
*/
public static final Parameter REPOSITORY_CACHE_DIR =
new Parameter(
"avalon.home",
File.class.getName(),
new File( USER_HOME, ".avalon" ) );
/**
* Repository proxy host parameter descriptor.
*/
public static final Parameter REPOSITORY_PROXY_HOST =
new Parameter(
"avalon.repository.proxy.host",
String.class.getName(),
null );
/**
* Repository proxy port parameter descriptor.
*/
public static final Parameter REPOSITORY_PROXY_PORT =
new Parameter(
"avalon.repository.proxy.port",
Integer.class.getName(),
null );
/**
* Repository proxy username parameter descriptor.
*/
public static final Parameter REPOSITORY_PROXY_USERNAME =
new Parameter(
"avalon.repository.proxy.username",
String.class.getName(),
null );
/**
* Repository proxy password parameter descriptor.
*/
public static final Parameter REPOSITORY_PROXY_PASSWORD =
new Parameter(
"avalon.repository.proxy.password",
String.class.getName(),
null );
/**
* Repository proxy password parameter descriptor.
*/
public static final Parameter REPOSITORY_REMOTE_HOSTS =
new Parameter(
"avalon.repository.remote.url",
String[].class.getName(),
new String[0] );
/**
* The factory parameters template.
*/
public static final Parameter[] PARAMS = new Parameter[]{
REPOSITORY_CACHE_DIR,
REPOSITORY_PROXY_HOST,
REPOSITORY_PROXY_PORT,
REPOSITORY_PROXY_USERNAME,
REPOSITORY_PROXY_PASSWORD,
REPOSITORY_REMOTE_HOSTS };
/**
* The name of the static defaults property resource.
*/
public static final String DEFAULTS = "default.properties";
/**
* recognized single keys
*/
private static final String [] SINGLE_KEYS = {
REPOSITORY_CACHE_DIR.getKey(),
REPOSITORY_PROXY_HOST.getKey(),
REPOSITORY_PROXY_PORT.getKey(),
REPOSITORY_PROXY_USERNAME.getKey(),
REPOSITORY_PROXY_PASSWORD.getKey()
};
/**
* regognized multivalue keys
*/
public static final String [] MULTI_VALUE_KEYS = {
REPOSITORY_REMOTE_HOSTS.getKey()
};
//--------------------------------------------------------------
// constructor
//--------------------------------------------------------------
/**
* Creation of a new criteria.
* @param template the template containing the validation parameters
*/
public RepositoryCriteria() throws RepositoryException
{
super( PARAMS );
Properties bootstrap = getDefaultProperties();
//
// Create the finder (discovery policy), construct the defaults, and
// macro expand the values.
//
final DefaultsFinder[] finders = {
new SimpleDefaultsFinder( new Properties[] { bootstrap }, false ),
new SystemDefaultsFinder() };
Defaults defaults = new Defaults( SINGLE_KEYS, MULTI_VALUE_KEYS, finders );
Defaults.macroExpand( defaults, new Properties[]{ System.getProperties() } );
//
// Here we start to populate the empty repository configuration using
// the values stored in the defaults.
//
// TODO: currently assigning the cache as a subdirectory of user.home.
// That's ok, but we really should be translating a value
// ${user.home}/.avalon and avoid the assumption in the first place
// but this assumes that macro expansion is doing its job (and I havn't
// figured this one out yet).
final File home = new File( System.getProperty( "user.home" ) );
String cache =
defaults.getProperty( REPOSITORY_CACHE_DIR.getKey() );
if( null == cache )
{
cache = ".cache";
}
put( REPOSITORY_CACHE_DIR.getKey(),
new File( home, cache ) );
try
{
String[] hosts =
defaults.getEnumerated( REPOSITORY_REMOTE_HOSTS.getKey() );
put( REPOSITORY_REMOTE_HOSTS.getKey(), hosts );
}
catch ( Throwable e )
{
final String error =
"Failed to set remote repositories.";
throw new RepositoryException( error, e );
}
if( defaults.containsKey( REPOSITORY_PROXY_HOST.getKey() ) )
{
put(
REPOSITORY_PROXY_HOST.getKey(),
new Integer( defaults.getProperty( REPOSITORY_PROXY_HOST.getKey() ) )
);
if( defaults.containsKey( REPOSITORY_PROXY_PORT.getKey() ) )
{
put(
REPOSITORY_PROXY_PORT.getKey(),
new Integer( defaults.getProperty( REPOSITORY_PROXY_PORT.getKey()
) ) );
}
if( defaults.containsKey( REPOSITORY_PROXY_USERNAME.getKey() ) )
{
put(
REPOSITORY_PROXY_USERNAME.getKey(),
defaults.getProperty( REPOSITORY_PROXY_USERNAME.getKey() ) );
}
if( defaults.containsKey( REPOSITORY_PROXY_PASSWORD.getKey() ) )
{
put(
REPOSITORY_PROXY_PASSWORD.getKey(),
defaults.getProperty( REPOSITORY_PROXY_PASSWORD.getKey() ) );
}
}
}
//--------------------------------------------------------------
// Criteria
//--------------------------------------------------------------
public String toString()
{
return "[repository: " + super.toString() + "]";
}
//--------------------------------------------------------------
// private
//--------------------------------------------------------------
private Properties getDefaultProperties() throws RepositoryException
{
try
{
return Defaults.getStaticProperties( RepositoryCriteria.class, DEFAULTS
);
}
catch ( IOException e )
{
throw new RepositoryException(
"Failed to load implementation defaults resource: "
+ DEFAULTS, e );
}
}
}
1.2 +2 -2
avalon-sandbox/repository/main/src/java/org/apache/avalon/repository/main/Bootstrapper.java
Index: Bootstrapper.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/repository/main/src/java/org/apache/avalon/repository/main/Bootstrapper.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Bootstrapper.java 24 Nov 2003 08:22:08 -0000 1.1
+++ Bootstrapper.java 26 Nov 2003 14:11:40 -0000 1.2
@@ -507,7 +507,7 @@
//l_bootstrapper.main( l_fqcn, a_args ) ;
}
- catch ( RepositoryException e )
+ catch ( Throwable e )
{
e.printStackTrace() ;
System.exit( -1 ) ;
1.6 +3 -13
avalon-sandbox/repository/main/src/java/org/apache/avalon/repository/main/InitialRepositoryFactory.java
Index: InitialRepositoryFactory.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/repository/main/src/java/org/apache/avalon/repository/main/InitialRepositoryFactory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- InitialRepositoryFactory.java 26 Nov 2003 01:16:56 -0000 1.5
+++ InitialRepositoryFactory.java 26 Nov 2003 14:11:40 -0000 1.6
@@ -257,7 +257,7 @@
* Return a new instance of default criteria for the factory.
* @return a new criteria instance
*/
- public Criteria createDefaultCriteria()
+ public Map createDefaultCriteria()
{
return m_delegate.createDefaultCriteria();
}
@@ -268,17 +268,7 @@
*/
public Object create() throws Exception
{
- return create( createDefaultCriteria().getMap() );
- }
-
- /**
- * Create a new instance of an application.
- * @param criteria the creation criteria
- * @return the application instance
- */
- public Object create( Criteria criteria ) throws Exception
- {
- return create( criteria.getMap() );
+ return create( createDefaultCriteria() );
}
/**
1.4 +197 -14
avalon-sandbox/repository/spi/src/java/org/apache/avalon/repository/criteria/Criteria.java
Index: Criteria.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/repository/spi/src/java/org/apache/avalon/repository/criteria/Criteria.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Criteria.java 26 Nov 2003 00:41:41 -0000 1.3
+++ Criteria.java 26 Nov 2003 14:11:40 -0000 1.4
@@ -48,24 +48,82 @@
*/
-package org.apache.avalon.repository.criteria ;
+package org.apache.avalon.repository.criteria;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.HashMap;
import java.util.Map;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.lang.reflect.Constructor;
+
+import org.apache.avalon.repository.criteria.Criteria;
+import org.apache.avalon.repository.criteria.Parameter;
+import org.apache.avalon.repository.criteria.ValidationException;
+
/**
- * A Criteria is a class holding the values supplied by a user
- * for application to a factory.
+ * A abstract utility class that can be used to simplfy the
+ * creation of domain specific criteria handlers.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision$
*/
-public interface Criteria
+public class Criteria extends HashMap
{
+ //--------------------------------------------------------------
+ // state
+ //--------------------------------------------------------------
+
+ private final Parameter[] m_params;
+
+ //--------------------------------------------------------------
+ // constructor
+ //--------------------------------------------------------------
+
+
/**
- * Return the set of parameter keys for the criteria.
- * @return the keys
+ * Creation of a new criteria instance.
+ * @param params the set of parameters managed by the criteria
*/
- public String[] getKeys();
+ public Criteria( Parameter[] params )
+ {
+ if( null == params )
+ throw new NullPointerException( "params" );
+ m_params = params;
+ }
+
+ /**
+ * Creation of a new criteria instance.
+ * @param params the set of parameters managed by the criteria
+ * @param params an initial set of values
+ */
+ //public Criteria( Parameter[] params, Map values )
+ //{
+ // if( null == params )
+ // throw new NullPointerException( "params" );
+
+ // m_params = params;
+ // for( int i=0; i<params.length; i++ )
+ // {
+ // Parameter p = params[i];
+ // String key = p.getKey();
+ // if( null != values )
+ // {
+ // if( values.containsKey( key ) )
+ // {
+ // super.put( key, values.get( key ) );
+ // }
+ // }
+ // }
+ //}
+
+ //--------------------------------------------------------------
+ // Criteria
+ //--------------------------------------------------------------
/**
* Set a named parameter of the criteria to a value.
@@ -74,18 +132,143 @@
* @exception ValidationException if the supplied value fails
* the validation test for its associated parameter
*/
- public void setValue( final String key, final Object value )
- throws ValidationException;
+ public void put( final String key, final Object value )
+ {
+ final Parameter p = getParameter( key );
+ final Object v = resolveValue( p, value );
+ super.put( key, v );
+ }
/**
* Return the currently assigned value for a key.
* @return the assigned value
*/
- public Object getValue( final String key );
+ public Object get( final Object key )
+ {
+ Parameter param = getParameterFromObject( key );
+ Object value = super.get( param.getKey() );
+ if( null != value ) return value;
+ return param.getDefault();
+ }
+
+ //--------------------------------------------------------------
+ // private and protected
+ //--------------------------------------------------------------
/**
- * Return the current state of the criteria as a map.
- * @return the criteria as a map
+ * Return the currently assigned value for a key.
+ * @return the assigned value
+ */
+ protected Object getValue( final Parameter param )
+ {
+ return get( param.getKey() );
+ }
+
+ /**
+ * Return the parameter associated to the criteria.
+ * @return the parameters
+ */
+ protected Parameter[] getParameters()
+ {
+ return m_params;
+ }
+
+ protected Parameter getParameter( final String key )
+ {
+ Parameter[] params = getParameters();
+ for( int i=0; i<params.length; i++ )
+ {
+ Parameter parameter = params[i];
+ if( parameter.getKey().equals( key ) ) return parameter;
+ }
+
+ final String error =
+ "Unknown key: [" + key + "].";
+ throw new IllegalArgumentException( error );
+ }
+
+ /**
+ * Verify a value relative to the parameter constraints.
+ * @param value the value to verify
+ * @exception ValidationException if the value is invalid
*/
- public Map getMap();
+ private Object resolveValue( Parameter param, Object value )
+ throws ValidationException
+ {
+ if( value == null ) return null;
+ Class c = getParameterClass( param );
+ if( c.isInstance( value ) )
+ {
+ return value;
+ }
+ else
+ {
+ Constructor constructor = null;
+ try
+ {
+ constructor =
+ c.getConstructor(
+ new Class[]{ value.getClass() } );
+ }
+ catch( NoSuchMethodException nsme )
+ {
+ final String error =
+ "Value of class: ["
+ + value.getClass().getName()
+ + "] supplied for key ["
+ + param.getKey()
+ + "] is not an instance of type: ["
+ + param.getClassname()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+
+ try
+ {
+ return constructor.newInstance(
+ new Object[]{ value } );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Value of class: ["
+ + value.getClass().getName()
+ + "] supplied for key ["
+ + param.getKey()
+ + "] is not an instance of or was not resolvable to the type: ["
+ + param.getClassname()
+ + "].";
+ throw new ValidationException( error, e );
+ }
+ }
+ }
+
+ private Parameter getParameterFromObject( Object key )
+ {
+ if( key instanceof Parameter )
+ {
+ return (Parameter) key;
+ }
+ else
+ {
+ return getParameter( key.toString() );
+ }
+ }
+
+ private Class getParameterClass( Parameter param )
+ throws ValidationException
+ {
+ try
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ return loader.loadClass( param.getClassname() );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unable to resolve parameter class: "
+ + param.getClassname();
+ throw new ValidationException( error, e );
+ }
+ }
}
1.4 +3 -10
avalon-sandbox/repository/spi/src/java/org/apache/avalon/repository/criteria/Factory.java
Index: Factory.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/repository/spi/src/java/org/apache/avalon/repository/criteria/Factory.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Factory.java 26 Nov 2003 01:16:56 -0000 1.3
+++ Factory.java 26 Nov 2003 14:11:40 -0000 1.4
@@ -65,7 +65,7 @@
* Return a new instance of default criteria for the factory.
* @return a new criteria instance
*/
- Criteria createDefaultCriteria();
+ Map createDefaultCriteria();
/**
* Create a new instance of an application.
@@ -78,13 +78,6 @@
* @param criteria the creation criteria
* @return the application instance
*/
- Object create( Criteria criteria ) throws Exception;
-
- /**
- * Create a new instance of an application.
- * @param map the creation criteria
- * @return the application instance
- */
- Object create( Map map ) throws Exception; // required
+ Object create( Map criteria ) throws Exception;
}
1.4 +4 -3
avalon-sandbox/repository/test/src/test/org/apache/avalon/repository/main/InitialRepositoryFactoryTest.java
Index: InitialRepositoryFactoryTest.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/repository/test/src/test/org/apache/avalon/repository/main/InitialRepositoryFactoryTest.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- InitialRepositoryFactoryTest.java 24 Nov 2003 13:33:37 -0000 1.3
+++ InitialRepositoryFactoryTest.java 26 Nov 2003 14:11:40 -0000 1.4
@@ -52,6 +52,7 @@
import java.io.File;
import java.net.URL;
+import java.util.Map;
import junit.framework.TestCase ;
@@ -93,9 +94,9 @@
Factory factory = new InitialRepositoryFactory( bootstrap );
assertNotNull( factory );
- Criteria criteria = factory.createDefaultCriteria();
+ Map criteria = factory.createDefaultCriteria();
String[] repositories = getWorkingRepositorySet();
- criteria.setValue( "avalon.repository.remote.url", repositories );
+ criteria.put( "avalon.repository.remote.url", repositories );
Repository repository = (Repository) factory.create( criteria ) ;
assertNotNull( repository ) ;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]