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));
+ }
+
}