package org.codehaus.plexus.component;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.DefaultPlexusConfiguration;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.ComponentRequirement;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.apache.xbean.recipe.MissingAccessorException;
import junit.framework.TestCase;
import java.util.List;
public class PlexusExceptionTest extends TestCase
{
private static DefaultPlexusContainer container;
private ComponentDescriptor<ExceptionalComponent> exceptionalDescriptor;
private ComponentDescriptor<RequiresComponent> requiresDescriptor;
private static Exception constructorException;
private static Exception setterException;
private static Exception startException;
private static boolean lookupInSetter;
private static boolean lookupInConstructor;
protected void setUp() throws Exception
{
super.setUp();
container = new DefaultPlexusContainer();
//
// ExceptionalComponent definition
//
exceptionalDescriptor = new ComponentDescriptor<ExceptionalComponent>(
ExceptionalComponent.class,
container.getContainerRealm() );
exceptionalDescriptor.setRoleClass( ExceptionalComponent.class );
PlexusConfiguration exceptionalConfiguration = new DefaultPlexusConfiguration(){};
exceptionalConfiguration.setAttribute( "name", "exceptional bean" );
exceptionalDescriptor.setConfiguration( exceptionalConfiguration );
exceptionalDescriptor.setSource( "exceptionalDescriptor.xml" );
container.addComponentDescriptor( exceptionalDescriptor );
//
// RequiresComponent definition
//
requiresDescriptor = new ComponentDescriptor<RequiresComponent>(
RequiresComponent.class,
container.getContainerRealm() );
requiresDescriptor.setRoleClass( RequiresComponent.class );
PlexusConfiguration requiresConfiguration = new DefaultPlexusConfiguration(){};
requiresConfiguration.setAttribute( "name", "requires bean" );
requiresDescriptor.setConfiguration( requiresConfiguration );
requiresDescriptor.setSource( "requiresDescriptor.xml" );
container.addComponentDescriptor( requiresDescriptor );
constructorException = null;
setterException = null;
startException = null;
lookupInConstructor = false;
lookupInSetter = false;
}
public void testConstructorCheckedException() throws Exception {
constructorException = new TestCheckedException( "constructor test" );
assertLookupFailed( constructorException );
}
public void testConstructorRuntimeException() throws Exception {
constructorException = new TestRuntimeException( "constructor test" );
assertLookupFailed( constructorException );
}
public void testSetterCheckedException() throws Exception {
setterException = new TestCheckedException( "setter test");
assertLookupFailed( setterException );
}
public void testSetterRuntimeException() throws Exception {
setterException = new TestRuntimeException( "setter test");
assertLookupFailed( setterException );
}
public void testStartCheckedException() throws Exception {
startException = new StartingException( "start test");
assertLookupFailed( startException );
}
public void testStartRuntimeException() throws Exception {
startException = new TestRuntimeException( "start test");
assertLookupFailed( startException );
}
public void testMissingProperty() throws Exception {
exceptionalDescriptor.getConfiguration().addChild( "unknown", "unknown" );
Throwable cause = assertLookupFailed( null );
assertTrue("cause should be an instance of MissingAccessorException", cause instanceof MissingAccessorException );
}
public void testMissingRequirementProperty() throws Exception {
exceptionalDescriptor.addRequirement( new ComponentRequirement( "unknown", ExceptionalComponent.class.getName()) );
Throwable cause = assertLookupFailed( null );
assertTrue("cause should be an instance of MissingAccessorException", cause instanceof MissingAccessorException );
}
private Throwable assertLookupFailed( Exception expected )
{
try
{
container.lookup( ExceptionalComponent.class );
fail("Expected ComponentLookupException");
throw new AssertionError("Unreachable statement");
}
catch ( ComponentLookupException lookupException )
{
// verify cause is the same excption thrown from the component constructor
Throwable cause = lookupException.getCause();
assertNotNull( "ComponentLookupException.getCause() is null", cause );
if ( expected != null )
{
assertSame( "cause should be same instance thrown from component", expected, cause );
}
// verify stack contains only the one component
List<ComponentStackElement> stack = lookupException.getComponentStack();
assertEquals( "Component stack", 1, stack.size() );
ComponentDescriptor<?> failedDescriptor = stack.get( 0 ).getDescriptor();
assertSame( "Failed component descriptor should be created component", exceptionalDescriptor, failedDescriptor );
return lookupException.getCause();
}
}
public void testNestedRequiresConstructorCheckedException() throws Exception {
constructorException = new TestCheckedException( "constructor test" );
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
assertNestedRequiresFailed( constructorException );
}
public void testNestedRequiresConstructorRuntimeException() throws Exception {
constructorException = new TestRuntimeException( "constructor test" );
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
assertNestedRequiresFailed( constructorException );
}
public void testNestedRequiresSetterCheckedException() throws Exception {
setterException = new TestCheckedException( "setter test");
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
assertNestedRequiresFailed( setterException );
}
public void testNestedRequiresSetterRuntimeException() throws Exception {
setterException = new TestRuntimeException( "setter test");
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
assertNestedRequiresFailed( setterException );
}
public void testNestedRequiresStartCheckedException() throws Exception {
startException = new StartingException( "start test");
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
assertNestedRequiresFailed( startException );
}
public void testNestedRequiresStartRuntimeException() throws Exception {
startException = new TestRuntimeException( "start test");
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
assertNestedRequiresFailed( startException );
}
public void testNestedRequiresMissingProperty() throws Exception {
exceptionalDescriptor.getConfiguration().addChild( "unknown", "unknown" );
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
Throwable cause = assertNestedRequiresFailed( null );
assertTrue("cause should be an instance of MissingAccessorException", cause instanceof MissingAccessorException );
}
public void testNestedRequiresMissingRequirementProperty() throws Exception {
exceptionalDescriptor.addRequirement( new ComponentRequirement( "unknown", ExceptionalComponent.class.getName()) );
requiresDescriptor.addRequirement( new ComponentRequirement( "component", ExceptionalComponent.class.getName()) );
Throwable cause = assertNestedRequiresFailed( null );
assertTrue("cause should be an instance of MissingAccessorException", cause instanceof MissingAccessorException );
}
public void testNestedLookupInConstructor() throws Exception {
constructorException = new TestCheckedException( "constructor test" );
lookupInConstructor = true;
assertNestedRequiresFailed( constructorException );
}
public void testNestedLookupInSetter() throws Exception {
constructorException = new TestCheckedException( "constructor test" );
lookupInSetter = true;
assertNestedRequiresFailed( constructorException );
}
private Throwable assertNestedRequiresFailed( Exception expected )
{
try
{
container.lookup( RequiresComponent.class );
fail("Expected ComponentLookupException");
throw new AssertionError("Unreachable statement");
}
catch ( ComponentLookupException lookupException )
{
// verify cause is the same excption thrown from the component constructor
Throwable cause = lookupException.getCause();
assertNotNull( "ComponentLookupException.getCause() is null", cause );
if ( expected != null )
{
assertSame( "cause should be same instance thrown from component", expected, cause );
}
// verify stack contains only the one component
List<ComponentStackElement> stack = lookupException.getComponentStack();
assertEquals( "Component stack", 2, stack.size() );
ComponentDescriptor<?> failedDescriptor = stack.get( 0 ).getDescriptor();
assertSame( "Failed component descriptor should be created component", exceptionalDescriptor, failedDescriptor );
ComponentStackElement wrapperElement = stack.get( 1 );
ComponentDescriptor<?> wrapperDescriptor = wrapperElement.getDescriptor();
assertSame( "Wrapper component descriptor should be looked-up component", requiresDescriptor, wrapperDescriptor );
if ( requiresDescriptor.getRequirements().size() > 0 )
{
assertSame( "Wrapper property", "component", wrapperElement.getProperty() );
}
return lookupException.getCause();
}
}
public static class ExceptionalComponent implements Startable
{
private String myName;
public ExceptionalComponent() throws Exception
{
if ( constructorException != null )
{
throw constructorException;
}
}
public void setName( String name ) throws Exception
{
if ( setterException != null )
{
throw setterException;
}
this.myName = name;
}
public void start() throws StartingException
{
if ( startException instanceof RuntimeException )
{
throw (RuntimeException) startException;
}
if ( startException instanceof StartingException )
{
throw (StartingException) startException;
}
if ( startException != null )
{
throw new StartingException( "", startException );
}
}
public void stop() throws StoppingException
{
}
public String toString()
{
return myName;
}
}
public static class RequiresComponent
{
private String myName;
public ExceptionalComponent component;
public RequiresComponent() throws Exception
{
if ( lookupInConstructor )
{
container.lookup( ExceptionalComponent.class );
}
}
public void setName( String name ) throws Exception
{
if ( lookupInSetter )
{
container.lookup( ExceptionalComponent.class );
}
this.myName = name;
}
public String toString()
{
return myName;
}
}
public static class TestRuntimeException extends RuntimeException
{
public TestRuntimeException( String message )
{
super( message );
}
}
public static class TestCheckedException extends RuntimeException
{
public TestCheckedException( String message )
{
super( message );
}
}
}