mcconnell 2003/07/14 15:30:02
Modified: meta .cvsignore
Added: meta/impl/src/java/org/apache/avalon/meta/info/verifier
Resources.properties TypeVerifier.java
VerifyException.java package.html
Log:
Add type implementation class vertification.
Revision Changes Path
1.3 +0 -1 avalon-sandbox/meta/.cvsignore
Index: .cvsignore
===================================================================
RCS file: /home/cvs/avalon-sandbox/meta/.cvsignore,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- .cvsignore 10 Jul 2003 21:19:08 -0000 1.2
+++ .cvsignore 14 Jul 2003 22:30:01 -0000 1.3
@@ -3,5 +3,4 @@
build.properties
target
build.xml
-site
build.xml
1.1
avalon-sandbox/meta/impl/src/java/org/apache/avalon/meta/info/verifier/Resources.properties
Index: Resources.properties
===================================================================
# TypeVerifier
# ============
verifier.non-public-ctor.error=The implementation class {1} for the component type
named "{0}" does not have a public no-argument constructor.
verifier.missing-noargs-ctor.error=The implementation class {1} for the component
type named "{0}" does not have a no-argument constructor.
verifier.abstract-class.error=The implementation class {1} for the component type
named "{0}" is abstract.
verifier.nonpublic-class.error=The implementation class {1} for the component type
named "{0}" is not public.
verifier.primitive-class.error=The implementation class {1} for the component type
named "{0}" is primitive.
verifier.interface-class.error=The implementation class {1} for the component type
named "{0}" is an interface.
verifier.array-class.error=The implementation class {1} for the component type named
"{0}" is an array class.
verifier.non-interface-service.error=The service class {1} for the component type
named "{0}" is not an interface.
verifier.non-public-service.error=The service class {1} for the component type named
"{0}" is not public.
verifier.incompat-serviceable.error=The implementation class {1} for the component
type named "{0}" is both Serviceable and Composable (incompatible lifecycle
interfaces).
verifier.noimpl-service.error=The implementation class {1} for the component type
named "{0}" does not implement the service interface {2} which it declares it supports.
verifier.noimpl-phase.error=The implementation class {1} for the component type
named "{0}" does not implement the phase interface {2} which it declares it supports.
1.1
avalon-sandbox/meta/impl/src/java/org/apache/avalon/meta/info/verifier/TypeVerifier.java
Index: TypeVerifier.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.meta.info.verifier;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Suspendable;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.component.Recomposable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Reconfigurable;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.Recontextualizable;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Reparameterizable;
import org.apache.avalon.framework.service.Serviceable;
/**
* Utility class to help verify that component respects the
* rules of an Avalon component.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/07/14 22:30:01 $
*/
public class TypeVerifier
{
private static final Resources REZ =
ResourceManager.getPackageResources( ComponentVerifier.class );
private static final Class[] EMPTY_TYPES = new Class[ 0 ];
/**
* The interfaces representing lifecycle stages.
*/
private static final Class[] FRAMEWORK_CLASSES = new Class[]
{
LogEnabled.class,
Contextualizable.class,
Recontextualizable.class,
Composable.class,
Recomposable.class,
Serviceable.class,
Configurable.class,
Reconfigurable.class,
Parameterizable.class,
Reparameterizable.class,
Initializable.class,
Startable.class,
Suspendable.class,
Disposable.class
};
/**
* Verify that the supplied implementation class
* and service classes are valid for a component.
*
* @param name the name of component
* @param implementation the implementation class of component
* @param services the classes representing services
* @param phases the classes representing stage depedencies
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyType( final String name,
final Class implementation,
final Class[] services,
final Class[] phases )
throws VerifyException
{
verifyComponent( name, implementation, services );
verifyImplementsPhases( name, implementation, phases );
}
/**
* Verify that the supplied implementation class
* and service classes are valid for a component.
*
* @param name the name of component
* @param implementation the implementation class of component
* @param services the classes representing services
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyComponent( final String name,
final Class implementation,
final Class[] services )
throws VerifyException
{
verifyClass( name, implementation );
verifyLifecycles( name, implementation );
verifyServices( name, services );
verifyImplementsServices( name, implementation, services );
}
/**
* Verify that the supplied implementation implements the specified
* phase interfaces.
*
* @param name the name of component
* @param implementation the class representing the component
* @param phases the phase interfaces that the implementation must provide
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyImplementsPhases( final String name,
final Class implementation,
final Class[] phases )
throws VerifyException
{
for( int i = 0; i < phases.length; i++ )
{
if( !phases[ i ].isAssignableFrom( implementation ) )
{
final String message =
REZ.getString( "verifier.noimpl-phase.error",
name,
implementation.getName(),
phases[ i ].getName() );
throw new VerifyException( message );
}
}
}
/**
* Verify that the supplied implementation implements the specified
* services.
*
* @param name the name of component
* @param implementation the class representign component
* @param services the services that the implementation must provide
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyImplementsServices( final String name,
final Class implementation,
final Class[] services )
throws VerifyException
{
for( int i = 0; i < services.length; i++ )
{
if( !services[ i ].isAssignableFrom( implementation ) )
{
final String message =
REZ.getString( "verifier.noimpl-service.error",
name,
implementation.getName(),
services[ i ].getName() );
throw new VerifyException( message );
}
}
}
/**
* Verify that the supplied class is a valid class for
* a Component.
*
* @param name the name of component
* @param clazz the class representing component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyClass( final String name,
final Class clazz )
throws VerifyException
{
verifyNoArgConstructor( name, clazz );
verifyNonAbstract( name, clazz );
verifyNonArray( name, clazz );
verifyNonInterface( name, clazz );
verifyNonPrimitive( name, clazz );
verifyPublic( name, clazz );
}
/**
* Verify that the supplied classes are valid classes for
* a service.
*
* @param name the name of component
* @param classes the classes representign services
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyServices( final String name,
final Class[] classes )
throws VerifyException
{
for( int i = 0; i < classes.length; i++ )
{
verifyService( name, classes[ i ] );
}
}
/**
* Verify that the supplied class is a valid class for
* a service.
*
* @param name the name of component
* @param clazz the class representign service
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyService( final String name,
final Class clazz )
throws VerifyException
{
verifyServiceIsPublic( name, clazz );
//
// the following two validation points need more work
// (a) it is valid to pass a class as a service because the class may be a
proxy
// (b) when (a) is a class, it may be implementing lifecycle interfaces
which could
// could be hidden under another proxy
//
//verifyServiceIsaInterface( name, clazz );
//verifyServiceNotALifecycle( name, clazz );
}
/**
* Verify that the implementation class does not
* implement incompatible lifecycle interfaces.
*
* @param name the name of component
* @param implementation the implementation class
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyLifecycles( final String name,
final Class implementation )
throws VerifyException
{
final boolean composable =
Composable.class.isAssignableFrom( implementation )
|| Recomposable.class.isAssignableFrom( implementation );
final boolean serviceable = Serviceable.class.isAssignableFrom(
implementation );
if( serviceable && composable )
{
final String message =
REZ.getString( "verifier.incompat-serviceable.error",
name,
implementation.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the service implemented by
* specified component is an interface.
*
* @param name the name of component
* @param clazz the class representign service
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyServiceIsaInterface( final String name,
final Class clazz )
throws VerifyException
{
if( !clazz.isInterface() )
{
final String message =
REZ.getString( "verifier.non-interface-service.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the service implemented by
* specified component is public.
*
* @param name the name of component
* @param clazz the class representign service
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyServiceIsPublic( final String name,
final Class clazz )
throws VerifyException
{
final boolean isPublic =
Modifier.isPublic( clazz.getModifiers() );
if( !isPublic )
{
final String message =
REZ.getString( "verifier.non-public-service.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the service implemented by
* specified component does not extend any lifecycle interfaces.
*
* @param name the name of component
* @param clazz the class representign service
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyServiceNotALifecycle( final String name,
final Class clazz )
throws VerifyException
{
for( int i = 0; i < FRAMEWORK_CLASSES.length; i++ )
{
final Class lifecycle = FRAMEWORK_CLASSES[ i ];
if( lifecycle.isAssignableFrom( clazz ) )
{
final String message =
REZ.getString( "verifier.service-isa-lifecycle.error",
name,
clazz.getName(),
lifecycle.getName() );
throw new VerifyException( message );
}
}
}
/**
* Verify that the component has a no-arg aka default
* constructor.
*
* @param name the name of component
* @param clazz the class representign component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyNoArgConstructor( final String name,
final Class clazz )
throws VerifyException
{
try
{
final Constructor ctor = clazz.getConstructor( EMPTY_TYPES );
if( !Modifier.isPublic( ctor.getModifiers() ) )
{
final String message =
REZ.getString( "verifier.non-public-ctor.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
catch( final NoSuchMethodException nsme )
{
final String message =
REZ.getString( "verifier.missing-noargs-ctor.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the component is not represented by
* abstract class.
*
* @param name the name of component
* @param clazz the class representign component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyNonAbstract( final String name,
final Class clazz )
throws VerifyException
{
final boolean isAbstract =
Modifier.isAbstract( clazz.getModifiers() );
if( isAbstract )
{
final String message =
REZ.getString( "verifier.abstract-class.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the component is not represented by
* abstract class.
*
* @param name the name of component
* @param clazz the class representign component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyPublic( final String name,
final Class clazz )
throws VerifyException
{
final boolean isPublic =
Modifier.isPublic( clazz.getModifiers() );
if( !isPublic )
{
final String message =
REZ.getString( "verifier.nonpublic-class.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the component is not represented by
* primitive class.
*
* @param name the name of component
* @param clazz the class representign component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyNonPrimitive( final String name,
final Class clazz )
throws VerifyException
{
if( clazz.isPrimitive() )
{
final String message =
REZ.getString( "verifier.primitive-class.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the component is not represented by
* interface class.
*
* @param name the name of component
* @param clazz the class representign component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyNonInterface( final String name,
final Class clazz )
throws VerifyException
{
if( clazz.isInterface() )
{
final String message =
REZ.getString( "verifier.interface-class.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
/**
* Verify that the component is not represented by
* an array class.
*
* @param name the name of component
* @param clazz the class representign component
* @throws VerifyException if error thrown on failure and
* component fails check
*/
public void verifyNonArray( final String name,
final Class clazz )
throws VerifyException
{
if( clazz.isArray() )
{
final String message =
REZ.getString( "verifier.array-class.error",
name,
clazz.getName() );
throw new VerifyException( message );
}
}
}
1.1
avalon-sandbox/meta/impl/src/java/org/apache/avalon/meta/info/verifier/VerifyException.java
Index: VerifyException.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.meta.info.verifier;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate error verifying a Block or application.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/07/14 22:30:01 $
*/
public final class VerifyException
extends CascadingException
{
/**
* Construct a new <code>VerifyException</code> instance.
*
* @param message The detail message for this exception.
*/
public VerifyException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>VerifyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public VerifyException( final String message, final Throwable throwable )
{
super( message, throwable );
}
}
1.1
avalon-sandbox/meta/impl/src/java/org/apache/avalon/meta/info/verifier/package.html
Index: package.html
===================================================================
<body>
<p>A set of classes supporting verification of components types using class and
component meta information.</p>
<h3>Overview</h3>
<p>This package includes a set of classes supporting the verification of the
integrity of a component class and the verification of the integrity of a
relationships and inter-dependecies based on supplied meta info. The
[EMAIL PROTECTED] org.apache.avalon.meta.info.verifier.TypeVerifier} provides
support for the validation of a component type implementation class. It
includes validation functions that check for structural and best-practice
integrity related to the class, lifecycle patterns and service.
</body>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]