Author: hlship
Date: Wed Apr 30 18:22:14 2008
New Revision: 652415

URL: http://svn.apache.org/viewvc?rev=652415&view=rev
Log:
TAPESTRY-2401: NullPointerExceptions inside component bindings need to do a 
better job of explaining what was null

Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java?rev=652415&r1=652414&r2=652415&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java
 Wed Apr 30 18:22:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
 
 import org.apache.tapestry.PropertyConduit;
 import org.apache.tapestry.ioc.AnnotationProvider;
-import org.apache.tapestry.services.PropertyConduitSource;
+import org.apache.tapestry.ioc.internal.util.Defense;
 
 import java.lang.annotation.Annotation;
 
 /**
- * Base class for [EMAIL PROTECTED] PropertyConduit} instances created by the 
[EMAIL PROTECTED] PropertyConduitSource}.
+ * Base class for [EMAIL PROTECTED] org.apache.tapestry.PropertyConduit} 
instances created by the [EMAIL PROTECTED]
+ * org.apache.tapestry.services.PropertyConduitSource}.
  */
 public abstract class BasePropertyConduit implements PropertyConduit
 {
@@ -31,9 +32,12 @@
 
     private final String _description;
 
-    public BasePropertyConduit(final Class propertyType,
-                               final AnnotationProvider annotationProvider, 
final String description)
+    public BasePropertyConduit(Class propertyType, AnnotationProvider 
annotationProvider, String description)
     {
+        Defense.notNull(propertyType, "propertyType");
+        Defense.notNull(annotationProvider, "annotationProvider");
+        Defense.notBlank(description, "description");
+
         _propertyType = propertyType;
         _annotationProvider = annotationProvider;
         _description = description;

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java?rev=652415&r1=652414&r2=652415&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java
 Wed Apr 30 18:22:14 2008
@@ -253,6 +253,10 @@
         builder.addln("%s root = (%<s) $1;", 
ClassFabUtils.toJavaClassName(rootClass));
         String previousStep = "root";
 
+        builder.addln(
+                "if (root == null) throw new NullPointerException(\"Root 
object of property expression '%s' is null.\");",
+                expression);
+
         Class activeType = rootClass;
         ReadInfo readInfo = null;
 
@@ -312,6 +316,15 @@
 
                 builder.addln(";");
             }
+            else
+            {
+                // Perform a null check on intermediate terms.
+                if (i < lastIndex - 1)
+                {
+                    builder.addln("if (%s == null) throw new 
NullPointerException(%s.nullTerm(\"%s\", \"%s\", root));",
+                                  thisStep, getClass().getName(), term, 
expression);
+                }
+            }
 
             activeType = wrappedType;
             previousStep = thisStep;
@@ -491,4 +504,10 @@
 
         throw new 
NoSuchMethodException(ServicesMessages.noSuchMethod(activeType, methodName));
     }
+
+    public static String nullTerm(String term, String expression, Object root)
+    {
+        return String.format("Property '%s' (within property expression '%s', 
of %s) is null.",
+                             term, expression, root);
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java?rev=652415&r1=652414&r2=652415&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java
 Wed Apr 30 18:22:14 2008
@@ -142,4 +142,52 @@
         assertSame(conduit.getPropertyType(), String.class);
     }
 
+    @Test
+    public void null_root_object()
+    {
+        PropertyConduit conduit = _source.create(StringHolderBean.class, 
"value.get()");
+
+        try
+        {
+            conduit.get(null);
+            unreachable();
+        }
+        catch (NullPointerException ex)
+        {
+            assertEquals(ex.getMessage(), "Root object of property expression 
'value.get()' is null.");
+        }
+    }
+
+    @Test
+    public void null_property_in_chain()
+    {
+        PropertyConduit conduit = _source.create(CompositeBean.class, 
"simple.lastName");
+
+        CompositeBean bean = new CompositeBean();
+        bean.setSimple(null);
+
+        try
+        {
+            conduit.get(bean);
+            unreachable();
+        }
+        catch (NullPointerException ex)
+        {
+            assertMessageContains(ex, "Property 'simple' (within property 
expression 'simple.lastName', of",
+                                  ") is null.");
+        }
+    }
+
+    @Test
+    public void last_term_may_be_null()
+    {
+        PropertyConduit conduit = _source.create(CompositeBean.class, 
"simple.firstName");
+
+        CompositeBean bean = new CompositeBean();
+
+        bean.getSimple().setFirstName(null);
+
+        assertNull(conduit.get(bean));
+    }
+
 }


Reply via email to