Author: britter
Date: Tue Feb 12 20:22:00 2013
New Revision: 1445335

URL: http://svn.apache.org/r1445335
Log:
[SANDBOX-441] - Handling of types that can not be instantiated in 
DefaultClassAccessor should be improved to give users better feedback

Modified:
    commons/sandbox/beanutils2/trunk/src/changes/changes.xml
    
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java
    
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java
    
commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java

Modified: commons/sandbox/beanutils2/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/changes/changes.xml?rev=1445335&r1=1445334&r2=1445335&view=diff
==============================================================================
--- commons/sandbox/beanutils2/trunk/src/changes/changes.xml (original)
+++ commons/sandbox/beanutils2/trunk/src/changes/changes.xml Tue Feb 12 
20:22:00 2013
@@ -23,6 +23,10 @@
   </properties>
   <body>
   <release version="0.1" date="201?-??-??" description="First release.">
+    <action dev="britter" type="update" issue="SANDBOX-441">
+      Handling of types that can not be instantiated in DefaultClassAccessor 
should 
+      be improved to give users better feedback
+    </action>
     <action dev="britter" type="update" issue="SANDBOX-439">
       Rename ClassLoaderBuilder.loadWithClassLoader to loadWith
     </action>

Modified: 
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java?rev=1445335&r1=1445334&r2=1445335&view=diff
==============================================================================
--- 
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java
 (original)
+++ 
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/BeanInstantiationException.java
 Tue Feb 12 20:22:00 2013
@@ -27,7 +27,12 @@ public class BeanInstantiationException
 
     public BeanInstantiationException( Class<?> beanType, Throwable cause )
     {
-        super( cause, beanType, "Could not create a new instance of type 
'%s'.", beanType );
+        super( cause, beanType, "Cannot not create a new instance of type 
'%s'.", beanType );
+    }
+
+    BeanInstantiationException( Class<?> beanType, String reason )
+    {
+        super( null, beanType, "Cannot not create a new instance of type '%s'. 
Reason: " + reason, beanType );
     }
 
 }

Modified: 
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java?rev=1445335&r1=1445334&r2=1445335&view=diff
==============================================================================
--- 
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java
 (original)
+++ 
commons/sandbox/beanutils2/trunk/src/main/java/org/apache/commons/beanutils2/DefaultClassAccessor.java
 Tue Feb 12 20:22:00 2013
@@ -23,6 +23,8 @@ import static org.apache.commons.beanuti
 import static org.apache.commons.beanutils2.Assertions.checkNoneIsNull;
 import static org.apache.commons.beanutils2.Assertions.checkNotNull;
 
+import static java.lang.reflect.Modifier.isAbstract;
+
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 
@@ -50,19 +52,7 @@ final class DefaultClassAccessor<B>
      */
     public BeanAccessor<B> newInstance()
     {
-        try
-        {
-            B bean = beanClass.newInstance();
-            return new DefaultBeanAccessor<B>( bean );
-        }
-        catch ( InstantiationException e )
-        {
-            throw new BeanInstantiationException( beanClass, e );
-        }
-        catch ( IllegalAccessException e )
-        {
-            throw new ConstructorNotAccessibleException( beanClass, e );
-        }
+        return invokeConstructor();
     }
 
     // constructors
@@ -104,6 +94,7 @@ final class DefaultClassAccessor<B>
      */
     private BeanAccessor<B> invokeConstructor( boolean exact, Argument<?>... 
arguments )
     {
+        checkInstantiable();
         @SuppressWarnings( "unchecked" ) // type driven by beanClass
         Constructor<B> constructor = (Constructor<B>) constructorRegistry.get( 
exact,
                                                                                
beanClass,
@@ -125,6 +116,35 @@ final class DefaultClassAccessor<B>
         return new DefaultBeanAccessor<B>( bean );
     }
 
+    /**
+     * Checks if {@code beanClass} is instantiable and throws a {@link 
BeanInstantiationException} with an appropriate
+     * message otherwise.
+     */
+    private void checkInstantiable()
+    {
+        if ( beanClass.isInterface() )
+        {
+            throw new BeanInstantiationException( beanClass, "Type is an 
interface." );
+        }
+        if ( beanClass.isArray() )
+        {
+            throw new BeanInstantiationException( beanClass, "Type is an array 
class." );
+        }
+        if ( beanClass.isPrimitive() )
+        {
+            throw new BeanInstantiationException( beanClass, "Type is 
primitive." );
+        }
+        if ( beanClass.equals( Void.TYPE ) )
+        {
+            throw new BeanInstantiationException( beanClass, "Type represents 
void." );
+        }
+        // has to be the last check because primitives and array types are 
also abstract
+        if ( isAbstract( beanClass.getModifiers() ) )
+        {
+            throw new BeanInstantiationException( beanClass, "Type is 
abstract." );
+        }
+    }
+
     private B doInvokeConstructor( Constructor<B> constructor, Object[] 
parameterObjects )
     {
         try

Modified: 
commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java?rev=1445335&r1=1445334&r2=1445335&view=diff
==============================================================================
--- 
commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java
 (original)
+++ 
commons/sandbox/beanutils2/trunk/src/test/java/org/apache/commons/beanutils2/ConstructorsTestCase.java
 Tue Feb 12 20:22:00 2013
@@ -27,7 +27,9 @@ import static org.junit.Assert.assertNot
 import org.apache.commons.beanutils2.testbeans.AbstractTestBean;
 import org.apache.commons.beanutils2.testbeans.TestBean;
 import org.apache.commons.beanutils2.testbeans.ThrowingExceptionBean;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 
 /**
  * <p>
@@ -36,6 +38,10 @@ import org.junit.Test;
  */
 public class ConstructorsTestCase
 {
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
     // ------------------------------------------------ Individual Test Methods
 
     @Test
@@ -250,11 +256,64 @@ public class ConstructorsTestCase
         on( ThrowingExceptionBean.class ).invokeConstructor( argument( 
Byte.class, Byte.valueOf( (byte) 4711 ) ) );
     }
 
-    @Test( expected = BeanInstantiationException.class )
+    @Test
     public void invokeConstructorOnAbstract()
         throws Exception
     {
+        thrown.expect( BeanInstantiationException.class );
+        thrown.expectMessage( "abstract" );
         on( AbstractTestBean.class ).invokeConstructor();
     }
 
+    @Test
+    public void invokeConstructorOnInterface()
+        throws Exception
+    {
+        thrown.expect( BeanInstantiationException.class );
+        thrown.expectMessage( "interface" );
+        on( ClassAccessor.class ).invokeConstructor();
+    }
+
+    @Test
+    public void invokeConstructorOnArray()
+        throws Exception
+    {
+        thrown.expect( BeanInstantiationException.class );
+        thrown.expectMessage( "array" );
+        on( String[].class ).invokeConstructor();
+    }
+
+    @Test
+    public void invokeConstructorOnPrimitive()
+        throws Exception
+    {
+        thrown.expect( BeanInstantiationException.class );
+        thrown.expectMessage( "primitive" );
+        on( int.class ).invokeConstructor();
+    }
+
+    @Test
+    public void invokeConstructorOnVoid()
+        throws Exception
+    {
+        thrown.expect( BeanInstantiationException.class );
+        thrown.expectMessage( "void" );
+        on( void.class ).invokeConstructor();
+    }
+
+    @Test( expected = NoSuchConstructorException.class )
+    public void newInstanceWithoutDefaultConstructor()
+    {
+        on( NoDefaultConstructor.class ).newInstance();
+    }
+
+    public static class NoDefaultConstructor
+    {
+
+        NoDefaultConstructor( int i )
+        {
+            // do nothing here
+        }
+    }
+
 }


Reply via email to