You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/09/17 20:08:17 UTC

svn commit: r289837 - in /jakarta/tapestry/trunk: ./ examples/Workbench/src/java/org/apache/tapestry/workbench/chart/ framework/src/java/org/apache/tapestry/ framework/src/java/org/apache/tapestry/enhance/ framework/src/test/org/apache/tapestry/ framew...

Author: hlship
Date: Sat Sep 17 11:08:09 2005
New Revision: 289837

URL: http://svn.apache.org/viewcvs?rev=289837&view=rev
Log:
TAPESTRY-642: Injections that cause bad casts need better reporting

Modified:
    jakarta/tapestry/trunk/examples/Workbench/src/java/org/apache/tapestry/workbench/chart/ChartPage.java
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryMessages.java
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryStrings2.properties
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryUtils.java
    jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/enhance/InjectComponentWorker.java
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/BaseComponentTestCase.java
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/TestTapestryUtils.java
    jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/enhance/TestInjectComponentWorker.java
    jakarta/tapestry/trunk/status.xml

Modified: jakarta/tapestry/trunk/examples/Workbench/src/java/org/apache/tapestry/workbench/chart/ChartPage.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/Workbench/src/java/org/apache/tapestry/workbench/chart/ChartPage.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/examples/Workbench/src/java/org/apache/tapestry/workbench/chart/ChartPage.java (original)
+++ jakarta/tapestry/trunk/examples/Workbench/src/java/org/apache/tapestry/workbench/chart/ChartPage.java Sat Sep 17 11:08:09 2005
@@ -31,6 +31,7 @@
 import org.jCharts.chartData.PieChartDataSet;
 import org.jCharts.nonAxisChart.PieChart2D;
 import org.jCharts.properties.ChartProperties;
+import org.jCharts.properties.LegendAreaProperties;
 import org.jCharts.properties.LegendProperties;
 import org.jCharts.properties.PieChart2DProperties;
 import org.jCharts.test.TestDataGenerator;
@@ -168,7 +169,7 @@
     {
         LegendProperties legendProperties = new LegendProperties();
         legendProperties.setNumColumns(2);
-        legendProperties.setPlacement(LegendProperties.RIGHT);
+        legendProperties.setPlacement(LegendAreaProperties.RIGHT);
         ChartProperties chartProperties = new ChartProperties();
         chartProperties.setBackgroundPaint(Color.decode("#ffffcc"));
 

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryMessages.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryMessages.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryMessages.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryMessages.java Sat Sep 17 11:08:09 2005
@@ -61,8 +61,15 @@
         return _formatter.format("provided-by-enhancement", methodName);
     }
 
-    public static String attemptToChangeContainedComponent(IComponent component)
+    static String attemptToChangeContainedComponent(IComponent component)
     {
-        return _formatter.format("attempt-to-change-contained-component", component.getExtendedId());
+        return _formatter
+                .format("attempt-to-change-contained-component", component.getExtendedId());
+    }
+
+    static String componentWrongType(IComponent component, Class expectedType)
+    {
+        return _formatter.format("component-wrong-type", component.getExtendedId(), expectedType
+                .getName());
     }
 }

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryStrings2.properties
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryStrings2.properties?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryStrings2.properties (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryStrings2.properties Sat Sep 17 11:08:09 2005
@@ -21,3 +21,4 @@
 provided-by-enhancement=Method {0}() is not implemented. An implementation of this method should be provided via runtime class enhancement.
 no-form=Component {0} must be enclosed by a form, but no Form component has been stored into the request cycle.
 attempt-to-change-contained-component=Attempt to change containedComponent property of component {0}, which is not allowed.
+component-wrong-type=Component {0} is not assignable to type {1}.
\ No newline at end of file

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryUtils.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryUtils.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/TapestryUtils.java Sat Sep 17 11:08:09 2005
@@ -19,6 +19,7 @@
 
 import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.HiveMind;
+import org.apache.hivemind.Location;
 import org.apache.hivemind.util.Defense;
 
 /**
@@ -263,7 +264,7 @@
 
     /**
      * Converts a clientId into a client-side DOM reference; i.e.
-     * <code>document.getElementById('<i>id</i>')</code>.  
+     * <code>document.getElementById('<i>id</i>')</code>.
      */
 
     public static String buildClientElementReference(String clientId)
@@ -271,5 +272,36 @@
         Defense.notNull(clientId, "clientId");
 
         return "document.getElementById('" + clientId + "')";
+    }
+
+    /**
+     * Used by some generated code; obtains a component and ensures it is of the correct type.
+     */
+
+    public static IComponent getComponent(IComponent container, String componentId,
+            Class expectedType, Location location)
+    {
+        Defense.notNull(container, "container");
+        Defense.notNull(componentId, "componentId");
+        Defense.notNull(expectedType, "expectedType");
+        // Don't always have a location
+
+        IComponent component = null;
+
+        try
+        {
+            component = container.getComponent(componentId);
+        }
+        catch (Exception ex)
+        {
+            throw new ApplicationRuntimeException(ex.getMessage(), location, ex);
+        }
+
+        if (!expectedType.isAssignableFrom(component.getClass()))
+            throw new ApplicationRuntimeException(TapestryMessages.componentWrongType(
+                    component,
+                    expectedType), location, null);
+
+        return component;
     }
 }

Modified: jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/enhance/InjectComponentWorker.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/enhance/InjectComponentWorker.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/enhance/InjectComponentWorker.java (original)
+++ jakarta/tapestry/trunk/framework/src/java/org/apache/tapestry/enhance/InjectComponentWorker.java Sat Sep 17 11:08:09 2005
@@ -18,9 +18,11 @@
 
 import org.apache.hivemind.ErrorLog;
 import org.apache.hivemind.Location;
+import org.apache.hivemind.service.BodyBuilder;
 import org.apache.hivemind.service.ClassFabUtils;
 import org.apache.hivemind.util.Defense;
 import org.apache.tapestry.IComponent;
+import org.apache.tapestry.TapestryUtils;
 import org.apache.tapestry.spec.IComponentSpecification;
 import org.apache.tapestry.spec.IContainedComponent;
 
@@ -62,7 +64,8 @@
         }
     }
 
-    public void injectComponent(EnhancementOperation op, String componentId, String propertyName, Location location)
+    public void injectComponent(EnhancementOperation op, String componentId, String propertyName,
+            Location location)
     {
         Defense.notNull(op, "op");
         Defense.notNull(componentId, "componentId");
@@ -73,17 +76,28 @@
         op.claimReadonlyProperty(propertyName);
 
         String fieldName = "_$" + propertyName;
+        String classField = op.getClassReference(propertyType);
+        String locationField = op.addInjectedField(
+                fieldName + "$location",
+                Location.class,
+                location);
 
         op.addField(fieldName, propertyType);
 
         EnhanceUtils.createSimpleAccessor(op, fieldName, propertyName, propertyType, location);
 
-        // I.e. _$fred = (IComponent) getComponent("fred");
+        // I.e. _$fred = (IComponent) TapestryUtils.getComponent(this, "fred", IComponent.class,
+        // location)
 
-        String code = fieldName + " = (" + ClassFabUtils.getJavaClassName(propertyType)
-                + ") getComponent(\"" + componentId + "\");";
+        BodyBuilder builder = new BodyBuilder();
 
-        op.extendMethodImplementation(IComponent.class, EnhanceUtils.FINISH_LOAD_SIGNATURE, code);
+        builder.add("{0} = ({1}) ", fieldName, ClassFabUtils.getJavaClassName(propertyType));
+        builder.add("{0}#getComponent(this, ", TapestryUtils.class.getName());
+        builder.addQuoted(componentId);
+        builder.add(", {0}, {1});", classField, locationField);
+
+        op.extendMethodImplementation(IComponent.class, EnhanceUtils.FINISH_LOAD_SIGNATURE, builder
+                .toString());
     }
 
     public void setErrorLog(ErrorLog errorLog)

Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/BaseComponentTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/BaseComponentTestCase.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/BaseComponentTestCase.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/BaseComponentTestCase.java Sat Sep 17 11:08:09 2005
@@ -29,6 +29,11 @@
 import org.easymock.MockControl;
 
 /**
+ * Base class for testing components, or testing classes that operate on components. Simplifies
+ * creating much of the infrastructure around the components.
+ * <p>
+ * This class may eventually be part of the Tapestry distribution.
+ * 
  * @author Howard M. Lewis Ship
  * @since 4.0
  */
@@ -332,5 +337,11 @@
     protected IBinding newBinding()
     {
         return (IBinding) newMock(IBinding.class);
+    }
+
+    protected void trainGetComponent(IComponent container, String componentId, IComponent containee)
+    {
+        container.getComponent(componentId);
+        getControl(container).setReturnValue(containee);
     }
 }

Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/TestTapestryUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/TestTapestryUtils.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/TestTapestryUtils.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/TestTapestryUtils.java Sat Sep 17 11:08:09 2005
@@ -16,7 +16,6 @@
 
 import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.Location;
-import org.apache.hivemind.test.HiveMindTestCase;
 import org.easymock.MockControl;
 
 /**
@@ -25,39 +24,18 @@
  * @author Howard M. Lewis Ship
  * @since 4.0
  */
-public class TestTapestryUtils extends HiveMindTestCase
+public class TestTapestryUtils extends BaseComponentTestCase
 {
-    private IRequestCycle newCycle()
-    {
-        return (IRequestCycle) newMock(IRequestCycle.class);
-    }
 
     private IRequestCycle newCycle(String key, Object attribute)
     {
-        MockControl control = newControl(IRequestCycle.class);
-        IRequestCycle cycle = (IRequestCycle) control.getMock();
+        IRequestCycle cycle = newCycle();
 
-        cycle.getAttribute(key);
-        control.setReturnValue(attribute);
+        trainGetAttribute(cycle, key, attribute);
 
         return cycle;
     }
 
-    private IForm newForm()
-    {
-        return (IForm) newMock(IForm.class);
-    }
-
-    private PageRenderSupport newPageRenderSupport()
-    {
-        return (PageRenderSupport) newMock(PageRenderSupport.class);
-    }
-
-    private IComponent newComponent()
-    {
-        return (IComponent) newMock(IComponent.class);
-    }
-
     public void testStoreUniqueAttributeSuccess()
     {
         Object newInstance = new Object();
@@ -284,5 +262,72 @@
     {
         assertEquals("document.getElementById('foo')", TapestryUtils
                 .buildClientElementReference("foo"));
+    }
+
+    public void testGetComponent()
+    {
+        IComponent container = newComponent();
+        IComponent containee = newComponent();
+
+        trainGetComponent(container, "fred", containee);
+
+        replayControls();
+
+        assertSame(containee, TapestryUtils.getComponent(container, "fred", IComponent.class, null));
+
+        verifyControls();
+    }
+
+    public void testGetComponentWrongType()
+    {
+        IComponent container = newComponent();
+        IComponent containee = newComponent();
+        Location l = newLocation();
+
+        trainGetComponent(container, "fred", containee);
+        trainGetExtendedId(containee, "Flintstone/fred");
+
+        replayControls();
+
+        try
+        {
+            TapestryUtils.getComponent(container, "fred", String.class, l);
+            unreachable();
+        }
+        catch (ApplicationRuntimeException ex)
+        {
+            assertEquals("Component Flintstone/fred is not assignable to type java.lang.String.", ex.getMessage());
+            assertSame(l, ex.getLocation());
+        }
+
+        verifyControls();
+
+    }
+
+    public void testGetComponentDoesNotExist()
+    {
+        IComponent container = newComponent();
+        Location l = newLocation();
+
+        Throwable t = new RuntimeException("Poof!");
+
+        container.getComponent("fred");
+        getControl(container).setThrowable(t);
+
+        replayControls();
+
+        try
+        {
+            TapestryUtils.getComponent(container, "fred", IComponent.class, l);
+            unreachable();
+        }
+        catch (ApplicationRuntimeException ex)
+        {
+            assertEquals("Poof!", ex.getMessage());
+            assertSame(l, ex.getLocation());
+            assertSame(t, ex.getRootCause());
+        }
+
+        verifyControls();
     }
 }

Modified: jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/enhance/TestInjectComponentWorker.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/enhance/TestInjectComponentWorker.java?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/enhance/TestInjectComponentWorker.java (original)
+++ jakarta/tapestry/trunk/framework/src/test/org/apache/tapestry/enhance/TestInjectComponentWorker.java Sat Sep 17 11:08:09 2005
@@ -68,32 +68,67 @@
         verifyControls();
     }
 
+    protected EnhancementOperation newEnhancementOperation()
+    {
+        return (EnhancementOperation) newMock(EnhancementOperation.class);
+    }
+
+    protected void trainGetPropertyType(EnhancementOperation op, String propertyName,
+            Class propertyType)
+    {
+        op.getPropertyType(propertyName);
+        getControl(op).setReturnValue(propertyType);
+    }
+
+    protected void trainGetAccessorMethodName(EnhancementOperation op, String propertyName,
+            String methodName)
+    {
+        op.getAccessorMethodName(propertyName);
+        getControl(op).setReturnValue(methodName);
+    }
+
+    protected void trainGetClassReference(EnhancementOperation op, Class clazz, String reference)
+    {
+        op.getClassReference(clazz);
+        getControl(op).setReturnValue(reference);
+    }
+
+    protected void trainAddInjectedField(EnhancementOperation op, String fieldName,
+            Class fieldType, Object fieldValue, String uniqueFieldName)
+    {
+        op.addInjectedField(fieldName, fieldType, fieldValue);
+        getControl(op).setReturnValue(uniqueFieldName);
+    }
+
     public void testSuccess()
     {
         Location l = newLocation();
         IComponentSpecification spec = newSpec("fred", "barney", l);
-        MockControl control = newControl(EnhancementOperation.class);
-        EnhancementOperation op = (EnhancementOperation) control.getMock();
+        EnhancementOperation op = newEnhancementOperation();
 
-        op.getPropertyType("barney");
-        control.setReturnValue(IComponent.class);
+        trainGetPropertyType(op, "barney", IComponent.class);
 
         op.claimReadonlyProperty("barney");
 
+        trainGetClassReference(op, IComponent.class, "_$IComponent$class");
+        trainAddInjectedField(op, "_$barney$location", Location.class, l, "_$$location");
+
         op.addField("_$barney", IComponent.class);
 
-        op.getAccessorMethodName("barney");
-        control.setReturnValue("getBarney");
+        trainGetAccessorMethodName(op, "barney", "getBarney");
 
         op.addMethod(
                 Modifier.PUBLIC,
                 new MethodSignature(IComponent.class, "getBarney", null, null),
-                "return _$barney;", l);
+                "return _$barney;",
+                l);
 
         op.extendMethodImplementation(
                 IComponent.class,
                 EnhanceUtils.FINISH_LOAD_SIGNATURE,
-                "_$barney = (org.apache.tapestry.IComponent) getComponent(\"fred\");");
+                "_$barney = (org.apache.tapestry.IComponent) "
+                        + "org.apache.tapestry.TapestryUtils#getComponent"
+                        + "(this, \"fred\", _$IComponent$class, _$$location);");
 
         replayControls();
 

Modified: jakarta/tapestry/trunk/status.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/status.xml?rev=289837&r1=289836&r2=289837&view=diff
==============================================================================
--- jakarta/tapestry/trunk/status.xml (original)
+++ jakarta/tapestry/trunk/status.xml Sat Sep 17 11:08:09 2005
@@ -70,6 +70,7 @@
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-595">Resource prefixes not honored inside &lt;page&gt;'s specification-path attribute</action>
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-569">WebResponse does not expose a way to set headers</action>
       <action type="fix" dev="HLS" fixes-bug="TAPESTRY-349">Search path for managed bean classes</action>
+      <action type="fix" dev="HLS" fixes-bug="TAPESTRY-642">Injections that cause bad casts need better reporting</action>
     </release>
     <release version="4.0-beta-6" date="Sep 7 2005">
       <action type="update" dev="HLS" due-to="Henri Yandell">Convert Tapestry repository from CVS to SVN</action>



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org