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 [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 (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: <mailto:avalon-cvs-unsubscribe@;jakarta.apache.org> For additional commands, e-mail: <mailto:avalon-cvs-help@;jakarta.apache.org>
