You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/11/11 11:33:49 UTC
cvs commit: jakarta-avalon-excalibur/meta/src/java/org/apache/excalibur/meta/model Parameter.java
mcconnell 2002/11/11 02:33:49
Added: meta/src/java/org/apache/excalibur/meta/model Parameter.java
Log:
Initial commit of the Parameter class. A parameter represent a single constructor parameter
and is used within the scope of an Entry as part of the declarative approach
to context management.
Revision Changes Path
1.1 jakarta-avalon-excalibur/meta/src/java/org/apache/excalibur/meta/model/Parameter.java
Index: Parameter.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, 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", "Avalon", 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 apache@apache.org.
*
* 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 (INCLUDING, 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.excalibur.meta.model;
import java.lang.reflect.Constructor;
import java.util.Map;
/**
* A <code>Parameter</code> represents a single constructor typed argument value. A parameter
* container a classname (default value of <code>java.lang.String</code>) and possible sub-parameters.
* A parameter's value is established by creating a new instance using the parameter's classname,
* together with the values directived from the sub-sidiary parameters as constructor arguments.
*
* <p><b>XML</b></p>
* <p>A parameter is a nested structure containing a string value or contructor parameter arguments.</p>
* <pre>
* <font color="gray"><-- Simple string parameter declaration --></font>
*
* <parameter><font color="darkred">London</font></parameter>
*
* <font color="gray"><-- Typed parameter declaration --></font>
*
* <parameter class="<font color="darkred">java.io.File</font>"><font color="darkred">./home</font></parameter>
*
* <font color="gray"><-- Typed parameter declaration referencing a context value --></font>
*
* <parameter class="<font color="darkred">java.lang.ClassLoader</font>"><font color="darkred">${my-classloader-import-key}</font></parameter>
*
* <font color="gray"><-- Multi-argument parameter declaration --></font>
*
* <parameter class="<font color="darkred">MyClass</font>">
* <parameter class="<font color="darkred">java.io.File</font>"><font color="darkred">./home</font></parameter>
* <parameter><font color="darkred">London</font></parameter>
* </parameter>
* </pre>
*
* @see Entry
* @see Import
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/11/11 10:33:49 $
*/
public class Parameter
{
/**
* The classname to use as the parameter implementation class (defaults to java.lang.String)
*/
private final String m_classname;
/**
* The supplied argument.
*/
private String m_argument;
/**
* The sub-parameters from which the value for this parameter may be derived.
*/
private final Parameter[] m_parameters;
/**
* The derived value.
*/
private Object m_value;
/**
* Creation of a new parameter using the default <code>java.lang.String</code>
* type and a supplied value.
*
* @param value the string value
*/
public Parameter( final String value )
{
m_parameters = new Parameter[ 0 ];
m_classname = "java.lang.String";
m_argument = value;
}
/**
* Creation of a new entry directive using a supplied classname and value.
* @param classname the classname of the parameter
* @param value the parameter constructor value
*/
public Parameter( final String classname, final String value )
{
if( null == classname )
{
throw new NullPointerException( "classname" );
}
if( null == value )
{
throw new NullPointerException( "value" );
}
m_parameters = new Parameter[ 0 ];
m_classname = classname;
m_argument = value;
}
/**
* Creation of a new entry directive.
* @param classname the classname of the entry implementation
* @param parameters implementation class constructor parameter directives
*/
public Parameter( final String classname, final Parameter[] parameters )
{
if( null == classname )
{
throw new NullPointerException( "classname" );
}
m_classname = classname;
m_parameters = parameters;
}
/**
* Return the classname of the parameter implementation to use.
* @return the classname
*/
public String getClassname()
{
return m_classname;
}
/**
* Return the classname of the parameter implementation to use.
* @param loader the classloader to use
* @return the parameter class
* @exception ModelException if the parameter class cannot be resolved
*/
Class getParameterClass( ClassLoader loader ) throws ModelException
{
final String classname = getClassname();
try
{
return loader.loadClass( classname );
}
catch( final ClassNotFoundException e )
{
if( classname.equals( "int" ) )
{
return int.class;
}
else if( classname.equals( "short" ) )
{
return short.class;
}
else if( classname.equals( "long" ) )
{
return long.class;
}
else if( classname.equals( "byte" ) )
{
return byte.class;
}
else if( classname.equals( "double" ) )
{
return double.class;
}
else if( classname.equals( "byte" ) )
{
return byte.class;
}
else if( classname.equals( "float" ) )
{
return float.class;
}
else if( classname.equals( "char" ) )
{
return char.class;
}
else if( classname.equals( "char" ) )
{
return char.class;
}
else if( classname.equals( "boolean" ) )
{
return boolean.class;
}
else
{
throw new ModelException(
"Could not locate the parameter implemetation for class: '"
+ m_classname + "'.", e );
}
}
}
/**
* Return the derived parameter value.
* @param loader the classloader to use
* @param map a map of context values from which import directives may be resolved
* @return the value
* @exception ModelException if the parameter value cannot be resolved
*/
public Object getValue( ClassLoader loader, Map map ) throws ModelException
{
//
// if the parameter value has already been established - return it now
//
if( m_value != null )
{
return m_value;
}
//
// if the parameter contains a text argument then check if its a reference
// to a map entry (in the form"${<key>}" ), otherwise its a simple constructor
// case with a single string paremeter
//
if( m_argument != null )
{
if( m_argument.startsWith( "${" ) )
{
if( m_argument.endsWith( "}" ) )
{
final String key = m_argument.substring( 2, m_argument.length() - 1 );
m_value = map.get( key );
if( m_value != null )
{
return m_value;
}
else
{
final String error = "Missing context value: '" + key + "'.";
throw new IllegalArgumentException( error );
}
}
else
{
final String error = "Illegal formal for context refernence: '" + m_argument + "'.";
throw new IllegalArgumentException( error );
}
}
else
{
//
// the argument is a single string parameter
//
try
{
final Class[] params = new Class[]{String.class};
Constructor constructor = getParameterClass( loader ).getConstructor( params );
final Object[] values = new Object[]{m_argument};
m_value = constructor.newInstance( values );
return m_value;
}
catch( InstantiationException e )
{
final String error = "Unable to instantiate instance of class: " + m_classname
+ " with the single argument: '" + m_argument + "'";
throw new ModelException( error, e );
}
catch( IllegalAccessException e )
{
final String error =
"Cannot access single string parameter constructor for the class: '"
+ m_classname + "'.";
throw new ModelException( error, e );
}
catch( Throwable e )
{
final String error =
"Unexpected exception while creating a single string parameter value for the class: '"
+ m_classname + "'.";
throw new ModelException( error, e );
}
}
}
//
// getting here means we are dealing with 0..n types parameter constructor where the
// parameters are defined by the nested parameter definitions
//
if( m_parameters.length == 0 )
{
try
{
m_value = getParameterClass( loader ).newInstance();
return m_value;
}
catch( InstantiationException e )
{
final String error = "Unable to instantiate instance of class: " + m_classname;
throw new ModelException( error, e );
}
catch( IllegalAccessException e )
{
final String error =
"Cannot access null constructor for the class: '"
+ m_classname + "'.";
throw new ModelException( error, e );
}
}
else
{
Class[] params = new Class[ m_parameters.length ];
for( int i = 0; i < m_parameters.length; i++ )
{
try
{
params[ i ] = m_parameters[ i ].getParameterClass( loader );
}
catch( Throwable e )
{
final String error = "Unable to resolve sub-parameter class: "
+ m_parameters[ i ].getClassname()
+ " inside the parameter " + m_classname;
throw new ModelException( error, e );
}
}
Object[] values = new Object[ m_parameters.length ];
for( int i = 0; i < m_parameters.length; i++ )
{
try
{
values[ i ] = m_parameters[ i ].getValue( loader, map );
}
catch( Throwable e )
{
final String error = "Unable to instantiate sub-parameter for value: "
+ m_parameters[ i ].getClassname()
+ " inside the parameter " + m_classname;
throw new ModelException( error, e );
}
}
Constructor constructor = null;
try
{
constructor = getParameterClass( loader ).getConstructor( params );
}
catch( NoSuchMethodException e )
{
final String error =
"Supplied parameters for " + m_classname
+ " does not match an available constructor. Cause: " + e.toString()
+ "\n" + this;
throw new ModelException( error );
}
try
{
m_value = constructor.newInstance( values );
return m_value;
}
catch( InstantiationException e )
{
final String error =
"Unable to instantiate an instance of a multi-parameter constructor for class: '"
+ m_classname + "'.";
throw new ModelException( error, e );
}
catch( IllegalAccessException e )
{
final String error =
"Cannot access multi-parameter constructor for the class: '"
+ m_classname + "'.";
throw new ModelException( error, e );
}
catch( Throwable e )
{
final String error =
"Unexpected error while attmpting to instantiate a multi-parameter constructor "
+ "for the class: '" + m_classname + "'.";
throw new ModelException( error, e );
}
}
}
private String getClassesAsString( Class[] classes )
{
StringBuffer buffer = new StringBuffer();
for( int i = 0; i < classes.length; i++ )
{
buffer.append( classes[ i ].getName() );
if( ( i + 1 ) < classes.length )
{
buffer.append( "," );
}
}
return buffer.toString();
}
/**
* Returns a string representation of the parameter.
* @return the parameter as a string
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
asString( buffer, " " );
return buffer.toString();
}
/**
* Utility method to build a string buffer of a composite parameter.
* @param buffer the string buffer to append information to
* @param lead string used for formatting content
*/
protected void asString( StringBuffer buffer, String lead )
{
buffer.append(
lead + "[\n"
+ lead + " type: " + this.getClass().getName() + "\n"
+ lead + " class: " + m_classname + "\n"
+ lead + " arg: " + m_argument + "\n"
+ lead + " value: " + m_value + "\n"
+ lead + " params: " + m_parameters.length );
if( m_parameters.length > 0 )
{
buffer.append( "\n" );
String str = lead + " ";
getParamsAsString( buffer, str );
}
buffer.append( "\n" + lead + "]\n" );
}
private void getParamsAsString( StringBuffer buffer, String lead )
{
for( int i = 0; i < m_parameters.length; i++ )
{
m_parameters[ i ].asString( buffer, lead + " " );
}
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>