notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
svn commit: r2560 - development/main/transit/core/handler/src/main/net/dpml/transit/repository
- From: mcconnell AT dpml.net
- To: notify-dpml AT lists.ibiblio.org
- Subject: svn commit: r2560 - development/main/transit/core/handler/src/main/net/dpml/transit/repository
- Date: Sun, 15 May 2005 07:18:11 +0000
Author: mcconnell AT dpml.net
Date: Sun May 15 07:18:09 2005
New Revision: 2560
Modified:
development/main/transit/core/handler/src/main/net/dpml/transit/repository/Repository.java
development/main/transit/core/handler/src/main/net/dpml/transit/repository/StandardLoader.java
Log:
Rework the repository impl so that the logic concerning object instantiation
is exposed as a utility service.
Modified:
development/main/transit/core/handler/src/main/net/dpml/transit/repository/Repository.java
==============================================================================
---
development/main/transit/core/handler/src/main/net/dpml/transit/repository/Repository.java
(original)
+++
development/main/transit/core/handler/src/main/net/dpml/transit/repository/Repository.java
Sun May 15 07:18:09 2005
@@ -74,4 +74,19 @@
Object getPlugin( ClassLoader parent, URI uri, Object[] args )
throws IOException;
+ /**
+ * Instantiate an instance of a class using the supplied array of
constructor
+ * parameter arguments. Arguments will be evaluated in the order
supplied
+ * for each of the parameters declared by a single public constructor of
the
+ * supplied class. If a parameter cannot be resolved from supplied
arguments
+ * and the parameter is a class with a single public constructor and
implementation
+ * shall attempt to instantiate an instance of that class via a recursive
+ * invocation of this method.
+ *
+ * @param clazz the class of the object to instantiate
+ * @param params a priority ordered array of instances values to be used
in
+ * constructor parameter value assignment
+ */
+ Object instantiate( Class clazz, Object[] params ) throws
RepositoryException;
+
}
Modified:
development/main/transit/core/handler/src/main/net/dpml/transit/repository/StandardLoader.java
==============================================================================
---
development/main/transit/core/handler/src/main/net/dpml/transit/repository/StandardLoader.java
(original)
+++
development/main/transit/core/handler/src/main/net/dpml/transit/repository/StandardLoader.java
Sun May 15 07:18:09 2005
@@ -37,6 +37,7 @@
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Properties;
+import java.util.prefs.Preferences;
/**
* Utility class supporting downloading of resources based on
@@ -122,7 +123,9 @@
/**
- * Get a plugin class relative to a supplied artifact.
+ * Get a plugin class relative to a supplied artifact. The artifact uri
+ * must refer to a plugin descriptor (i.e. the artifact type is "plugin").
+ * The class returned will be the class named in the plugin descriptor.
*
* @param parent the parent classloader
* @param uri the plugin artifact
@@ -147,7 +150,13 @@
}
/**
- * Creates a Factory from an artifact reference.
+ * Instantiate an object using a plugin uri, parent classloader and
+ * a supplied argument array. The plugin uri is used to resolve a plugin
+ * descriptor. A classloader stack will be constructed using the supplied
+ * classloader as the anchor for stack construction. A classname declared
+ * in the plugin descriptor must has a single public constructor. The
+ * implementation will resolve constructor parameters relative to the
+ * supplied argument array and return an instance of the class.
*
* @param parent the parent classloader
* @param uri the reference to the application
@@ -168,11 +177,6 @@
{
throw new NullArgumentException( "parent" );
}
- if( null == args )
- {
- throw new NullArgumentException( "args" );
- }
-
if( m_monitor != null )
{
m_monitor.getPluginRequested( parent, uri, args );
@@ -184,7 +188,6 @@
m_monitor.sequenceInfo( "building classload stack" );
ClassLoader classloader = createClassLoader( parent, descriptor
);
String classname = descriptor.getClassname();
-
if( null == classname )
{
final String error =
@@ -193,7 +196,6 @@
+ "] does not declare a main class.";
throw new IOException( error );
}
-
Class clazz = loadPluginClass( classloader, classname );
m_monitor.establishedPluginClass( clazz );
return createPlugin( classloader, descriptor, clazz, args );
@@ -314,6 +316,10 @@
{
throw new NullArgumentException( "clazz" );
}
+ if( null == args )
+ {
+ throw new NullArgumentException( "args" );
+ }
if( null == classloader )
{
throw new NullArgumentException( "classloader" );
@@ -322,26 +328,48 @@
{
throw new NullArgumentException( "descriptor" );
}
- if( null == args )
+ Object[] params = new Object[ args.length + 3 ];
+ for( int i=0; i<args.length; i++ )
{
- throw new NullArgumentException( "args" );
+ params[i] = args[i];
}
+ params[ args.length ] = classloader;
+ params[ args.length + 1 ] = descriptor;
+ params[ args.length + 2 ] = this;
+ return instantiate( null, clazz, params );
+ }
- Constructor[] constructors = clazz.getConstructors();
- if( constructors.length < 1 )
+ public Object instantiate( Class clazz, Object[] args ) throws
RepositoryException
+ {
+ checkArgs( args );
+ if( null == clazz )
{
- final String error =
- "Factory class ["
- + clazz.getName()
- + "] does not declare a public constructor.";
- throw new RepositoryException( error );
+ throw new NullArgumentException( "clazz" );
}
+ return instantiate( null, clazz, args );
+ }
- Constructor constructor = constructors[0];
+ protected Object instantiate( Class parent, Class clazz, Object[] args )
throws RepositoryException
+ {
+ Constructor constructor = getSingleConstructor( clazz );
+ return instantiate( parent, constructor, args );
+ }
- if( m_monitor != null )
+ protected Object instantiate( Class parent, Constructor constructor,
Object[] args ) throws RepositoryException
+ {
+ Object[] arguments = populate( parent, constructor, args );
+ return newInstance( constructor, arguments );
+ }
+
+ protected Object[] populate( Class parent, Constructor constructor,
Object[] args ) throws RepositoryException
+ {
+ if( null == constructor )
{
- m_monitor.pluginConstructorFound( constructor, args );
+ throw new NullArgumentException( "constructor" );
+ }
+ if( null == args )
+ {
+ throw new NullArgumentException( "args" );
}
Class[] classes = constructor.getParameterTypes();
@@ -349,14 +377,13 @@
//
// sweep though the construct arguments one by one and
- // see if we can assign a value based on the supplied parameters
+ // see if we can assign a value based on the supplied args
//
- for( int i=0; i < classes.length; i++ )
+ for( int i=0; i<classes.length; i++ )
{
Class c = classes[i];
-
- for( int j=0; j < args.length; j++ )
+ for( int j=0; j<args.length; j++ )
{
Object object = args[j];
if( c.isAssignableFrom( object.getClass() ) )
@@ -372,22 +399,18 @@
// is something we can implicity establish
//
- for( int i=0; i < arguments.length; i++ )
+ for( int i=0; i<arguments.length; i++ )
{
if( null == arguments[i] )
{
Class c = classes[i];
- if( Plugin.class.isAssignableFrom( c ) )
- {
- arguments[i] = descriptor;
- }
- else if( ClassLoader.class.isAssignableFrom( c ) )
+ if( ClassLoader.class.isAssignableFrom( c ) )
{
- arguments[i] = classloader;
+ arguments[i] =
constructor.getDeclaringClass().getClassLoader();
}
- else if( Repository.class.isAssignableFrom( c ) )
+ else if( Preferences.class.isAssignableFrom( c ) )
{
- arguments[i] = this;
+ arguments[i] = Preferences.userNodeForPackage( c );
}
else if( c.isArray() )
{
@@ -395,17 +418,40 @@
}
else
{
- final String error =
- "Unable to resolve an argument for parameter ["
- + ( i + 1 )
- + "] requesting the ["
- + classes[i].getName()
- + "] class in the plugin class [" + clazz.getName() +
"].";
- throw new RepositoryException( error );
+ try
+ {
+ arguments[i] = instantiate( parent, c, args );
+ }
+ catch( RepositoryException e )
+ {
+ if( null != parent )
+ {
+ final String error =
+ "Unable to resolve a nested value for a
constructor parameter parameter."
+ + "\nEnclosing class: "+ parent.getName()
+ + "\nConstructor class: " +
constructor.getDeclaringClass().getName()
+ + "\nParameter class: " + c.getName()
+ + "\nParameter position: " + ( i + 1 );
+ throw new RepositoryException( error, e );
+ }
+ else
+ {
+ final String error =
+ "Unable to resolve a value for a constructor
parameter parameter."
+ + "\nConstructor class: " +
constructor.getDeclaringClass().getName()
+ + "\nParameter class: " + c.getName()
+ + "\nParameter position: " + ( i + 1 );
+ throw new RepositoryException( error, e );
+ }
+ }
}
}
}
+ return arguments;
+ }
+ private Object newInstance( Constructor constructor, Object[] arguments
) throws RepositoryException
+ {
try
{
Object instance = constructor.newInstance( arguments );
@@ -418,8 +464,8 @@
catch( InvocationTargetException e )
{
final String error =
- "Cannot create plugin ["
- + clazz.getName()
+ "Cannot create an instance of ["
+ + constructor.getDeclaringClass().getName()
+ "] due to an invocation failure.";
Throwable cause = e.getTargetException();
throw new RepositoryException( error, cause );
@@ -427,13 +473,60 @@
catch( Throwable e )
{
final String error =
- "Cannot create plugin ["
- + clazz.getName()
+ "Cannot create an instance of ["
+ + constructor.getDeclaringClass().getName()
+ "] due to an instantiation failure.";
throw new RepositoryException( error, e );
}
}
+ private Constructor getSingleConstructor( Class clazz ) throws
RepositoryException
+ {
+ if( null == clazz )
+ {
+ throw new NullArgumentException( "clazz" );
+ }
+ Constructor[] constructors = clazz.getConstructors();
+ if( constructors.length < 1 )
+ {
+ final String error =
+ "Target class ["
+ + clazz.getName()
+ + "] does not declare a public constructor.";
+ throw new RepositoryException( error );
+ }
+ else if( constructors.length > 1 )
+ {
+ final String error =
+ "Target class ["
+ + clazz.getName()
+ + "] declares multiple public constructors.";
+ throw new RepositoryException( error );
+ }
+ else
+ {
+ return constructors[0];
+ }
+ }
+
+ private void checkArgs( Object[] args )
+ {
+ if( null == args )
+ {
+ throw new NullArgumentException( "args" );
+ }
+ for( int i=0; i<args.length; i++ )
+ {
+ Object p = args[i];
+ if( null == p )
+ {
+ final String error =
+ "User supplied constructor argument [" + i + "] is a null
value.";
+ throw new NullArgumentException( error );
+ }
+ }
+ }
+
/**
* Constructs an empty array instance.
* @param clazz the array class
- svn commit: r2560 - development/main/transit/core/handler/src/main/net/dpml/transit/repository, mcconnell, 05/15/2005
Archive powered by MHonArc 2.6.24.