You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/06/23 20:05:37 UTC
svn commit: r670691 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/corelib/components/
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/internal/structure/
main/java/org/apache/tapestry5...
Author: hlship
Date: Mon Jun 23 11:05:36 2008
New Revision: 670691
URL: http://svn.apache.org/viewvc?rev=670691&view=rev
Log:
TAPESTRY-2471: Parameter fields that are updated during component event processing (such as a form submit) may not clear their values at the end of the request
TAPESTRY-2460: Nested BeanEditors (where the block parameter for a property to one BeanEditor contains another BeanEditor) results in a StackOverflowException
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanDisplay.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanEditor.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Person.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanEditor.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanDisplay.java Mon Jun 23 11:05:36 2008
@@ -96,6 +96,13 @@
@Property(write = false)
private ComponentResources overrides;
+ /**
+ * A comma-separated list of property names to be added to the {@link org.apache.tapestry5.beaneditor.BeanModel}.
+ */
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String add;
+
+
@Inject
private ComponentDefaultProvider defaultProvider;
@@ -121,7 +128,7 @@
if (model == null) model = modelSource.create(object.getClass(), false, overrides
.getContainerResources());
- BeanModelUtils.modify(model, null, include, exclude, reorder);
+ BeanModelUtils.modify(model, add, include, exclude, reorder);
}
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java Mon Jun 23 11:05:36 2008
@@ -29,17 +29,19 @@
* A component that creates an entire form editing the properties of a particular bean. Inspired by <a
* href="http://www.trailsframework.org/">Trails</a> and <a href="http://beanform.sourceforge.net/">BeanForm</a> (both
* for Tapestry 4). Generates a simple UI for editing the properties of a JavaBean, with the flavor of UI for each
- * property (text field, checkbox, drop down list) determined from the property type, and the order and validation for
- * the properties determined from annotations on the property's getter and setter methods.
+ * property (text field, checkbox, drop down list) determined from the property type (or by other means, such as an
+ * annotation), and the order and validation for the properties determined from annotations on the property's getter and
+ * setter methods.
* <p/>
* You may add <t:parameter>s to the component; when the name matches (case insensitive) the name of a property,
* then the corresponding Block is renderered, rather than any of the built in property editor blocks. This allows you
* to override specific properties with your own customized UI, for cases where the default UI is insufficient, or no
* built-in editor type is appropriate.
*
- * @see BeanModel
- * @see BeanModelSource
- * @see PropertyEditor
+ * @see org.apache.tapestry5.beaneditor.BeanModel
+ * @see org.apache.tapestry5.services.BeanModelSource
+ * @see org.apache.tapestry5.corelib.components.PropertyEditor
+ * @see org.apache.tapestry5.beaneditor.DataType
*/
@SupportsInformalParameters
public class BeanEditForm implements ClientElement, FormValidationControl
@@ -72,6 +74,12 @@
private String include;
/**
+ * A comma-separated list of property names to be added to the {@link org.apache.tapestry5.beaneditor.BeanModel}.
+ */
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String add;
+
+ /**
* A comma-separated list of property names to be removed from the {@link org.apache.tapestry5.beaneditor.BeanModel}.
* The names are case-insensitive.
*/
@@ -142,7 +150,7 @@
model = beanModelSource.create(beanType, true, resources.getContainerResources());
}
- BeanModelUtils.modify(model, null, include, exclude, reorder);
+ BeanModelUtils.modify(model, add, include, exclude, reorder);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java Mon Jun 23 11:05:36 2008
@@ -67,7 +67,6 @@
* Only these properties will be retained, and the properties will also be reordered. The names are
* case-insensitive.
*/
- @SuppressWarnings("unused")
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String include;
@@ -87,6 +86,13 @@
private String reorder;
/**
+ * A comma-separated list of property names to be added to the {@link org.apache.tapestry5.beaneditor.BeanModel}.
+ */
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String add;
+
+
+ /**
* The model that identifies the parameters to be edited, their order, and every other aspect. If not specified, a
* default bean model will be created from the type of the object bound to the object parameter.
*/
@@ -149,7 +155,7 @@
model = modelSource.create(type, true, overrides.getContainerResources());
}
- BeanModelUtils.modify(model, null, include, exclude, reorder);
+ BeanModelUtils.modify(model, add, include, exclude, reorder);
// The only problem here is that if the bound property is backed by a persistent field, it
// is assigned (and stored to the session, and propagated around the cluster) first,
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/PropertyEditor.java Mon Jun 23 11:05:36 2008
@@ -67,8 +67,16 @@
{
component.cleanupEnvironment();
}
+
+ @Override
+ public String toString()
+ {
+ return "PropertyEditor.CleanupEnvironment";
+ }
}
+ private static final ComponentAction CLEANUP_ENVIRONMENT = new CleanupEnvironment();
+
/**
* The object to be edited by the BeanEditor. This will be read when the component renders and updated when the form
* for the component is submitted. Typically, the container will listen for a "prepare" event, in order to ensure
@@ -213,7 +221,7 @@
// Removes the PropertyEditContext after this component (including the editor block)
// has rendered.
- formSupport.storeAndExecute(this, new CleanupEnvironment());
+ formSupport.storeAndExecute(this, CLEANUP_ENVIRONMENT);
}
/**
@@ -231,8 +239,14 @@
String dataType = propertyModel.getDataType();
+ if (dataType == null)
+ throw new RuntimeException(
+ String.format("The data type for property '%s' of %s is null.", propertyModel.getPropertyName(),
+ object));
+
try
{
+
return beanBlockSource.getEditBlock(dataType);
}
catch (RuntimeException ex)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java Mon Jun 23 11:05:36 2008
@@ -18,6 +18,7 @@
import org.apache.tapestry5.EventContext;
import org.apache.tapestry5.internal.structure.PageResources;
import org.apache.tapestry5.runtime.ComponentEvent;
+import org.slf4j.Logger;
public class ComponentEventImpl extends EventImpl implements ComponentEvent
{
@@ -31,16 +32,16 @@
/**
* @param eventType non blank string used to identify the type of event that was triggered
- * @param originatingComponentId the id of the component that triggered the event (this will likely need to change
- * somewhat)
+ * @param originatingComponentId the id of the component that triggered the event
* @param context provides access to parameter values
* @param handler invoked when a non-null return value is obtained from an event handler method
* @param pageResources provides access to common resources and services
+ * @param logger used to log method invocations
*/
public ComponentEventImpl(String eventType, String originatingComponentId, EventContext context,
- ComponentEventCallback handler, PageResources pageResources)
+ ComponentEventCallback handler, PageResources pageResources, Logger logger)
{
- super(handler);
+ super(handler, logger);
this.eventType = eventType;
this.originatingComponentId = originatingComponentId;
@@ -48,6 +49,14 @@
this.context = context;
}
+
+ @Override
+ public String toString()
+ {
+ return String.format("ComponentEvent[%s from %s]", eventType,
+ originatingComponentId.length() == 0 ? "(self)" : originatingComponentId);
+ }
+
public boolean matches(String eventType, String componentId, int parameterCount)
{
return this.eventType.equalsIgnoreCase(
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java Mon Jun 23 11:05:36 2008
@@ -17,6 +17,7 @@
import org.apache.tapestry5.ComponentEventCallback;
import static org.apache.tapestry5.ioc.internal.util.Defense.notNull;
import org.apache.tapestry5.runtime.Event;
+import org.slf4j.Logger;
public class EventImpl implements Event
{
@@ -26,9 +27,16 @@
private final ComponentEventCallback handler;
- public EventImpl(ComponentEventCallback handler)
+ private final Logger logger;
+
+ /**
+ * @param handler informed of return values from methods, deems when the event is aborted
+ * @param logger used to log method invocations
+ */
+ public EventImpl(ComponentEventCallback handler, Logger logger)
{
this.handler = notNull(handler, "handler");
+ this.logger = logger;
}
public boolean isAborted()
@@ -38,6 +46,9 @@
public void setMethodDescription(String methodDescription)
{
+ if (logger.isDebugEnabled())
+ logger.debug("Invoking: " + methodDescription);
+
this.methodDescription = methodDescription;
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java Mon Jun 23 11:05:36 2008
@@ -176,7 +176,7 @@
public void render(final MarkupWriter writer, RenderQueue queue)
{
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -205,7 +205,7 @@
public void render(final MarkupWriter writer, RenderQueue queue)
{
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -234,7 +234,7 @@
public void render(final MarkupWriter writer, final RenderQueue queue)
{
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -263,7 +263,7 @@
public void render(final MarkupWriter writer, RenderQueue queue)
{
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -294,7 +294,7 @@
public void render(final MarkupWriter writer, final RenderQueue queue)
{
final RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -325,7 +325,7 @@
public void render(final MarkupWriter writer, final RenderQueue queue)
{
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -365,12 +365,14 @@
private final PageResources pageResources;
+ private final Logger logger;
+
private final RenderCommand cleanupRender = new RenderCommand()
{
public void render(final MarkupWriter writer, RenderQueue queue)
{
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -466,7 +468,7 @@
elementAtSetup = writer.getElement();
RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler);
+ final Event event = new EventImpl(handler, logger);
ComponentCallback callback = new ComponentCallback()
{
@@ -570,6 +572,8 @@
completeId, nestedId, instantiator);
coreComponent = coreResources.getComponent();
+
+ logger = coreResources.getLogger();
}
/**
@@ -1019,8 +1023,13 @@
{
try
{
+ Logger logger = component.getLogger();
+
ComponentEvent event = new ComponentEventImpl(currentEventType, componentId, currentContext, wrapped,
- pageResources);
+ pageResources, logger);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatch event: " + event);
result |= component.dispatchEvent(event);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java Mon Jun 23 11:05:36 2008
@@ -111,8 +111,7 @@
String invariantFieldName = transformation.addField(Modifier.PRIVATE, "boolean", fieldName + "_invariant");
- BodyBuilder builder = new BodyBuilder();
- builder.begin();
+ BodyBuilder builder = new BodyBuilder().begin();
addDefaultBindingSetup(parameterName, defaultPrefix, defaultBinding, resourcesFieldName, transformation,
builder);
@@ -143,8 +142,15 @@
builder.addln("%s = false;", cachedFieldName);
builder.end();
- transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, builder
- .toString());
+ // Clean up after the component renders.
+
+ String body = builder.toString();
+
+ transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, body);
+
+ // And again, when the page is detached (TAPESTRY-2460)
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE, builder.toString());
}
return invariantFieldName;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml Mon Jun 23 11:05:36 2008
@@ -4,8 +4,7 @@
<div class="t-beaneditor">
- <t:beaneditor t:id="editor" object="object" remove="inherit:remove"
- reorder="inherit:reorder" model="model" overrides="this"/>
+ <t:beaneditor t:id="editor" object="object" model="model" overrides="this"/>
<div class="t-beaneditor-row">
<input type="submit" class="t-beaneditor-submit" value="${submitLabel}"/>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanDisplay.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanDisplay.tml?rev=670691&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanDisplay.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanDisplay.tml Mon Jun 23 11:05:36 2008
@@ -0,0 +1,15 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>Nested BeanDisplay</h1>
+
+ <p>Demonstrates a BeanEditor as the property editor inside a BeanEditForm.</p>
+
+ <t:beandisplay object="parent" add="child">
+
+ <t:parameter name="child">
+ <t:beandisplay object="parent.child"/>
+ </t:parameter>
+
+ </t:beandisplay>
+
+</html>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanEditor.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanEditor.tml?rev=670691&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanEditor.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NestedBeanEditor.tml Mon Jun 23 11:05:36 2008
@@ -0,0 +1,19 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>Nested BeanEditor</h1>
+
+ <p>Demonstrates a BeanEditor as the property editor inside a BeanEditForm.</p>
+
+ <t:beaneditform object="parent" add="child">
+
+ <t:parameter name="child">
+
+ <div class="t-beaneditor" style="margin-left: 45px;">
+ <h2>Child</h2>
+ <t:beaneditor object="parent.child"/>
+ </div>
+ </t:parameter>
+
+ </t:beaneditform>
+
+</html>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Mon Jun 23 11:05:36 2008
@@ -1823,7 +1823,7 @@
assertText("activePageName", "music/Details");
}
-
+
/**
* TAPESTRY-2235
*/
@@ -1837,9 +1837,9 @@
clickAndWait("link=Wake Me Up (Copy)");
assertText("activePageName", "music/Details2");
-
+
assertText("//div[@class='t-beandisplay-value title']", "Wake Me Up");
-
+
assertText("//div[@class='t-beandisplay-value artist']", "Norah Jones");
}
@@ -2058,4 +2058,25 @@
assertText("output-text", "yrtsepaT");
}
+
+ // TAPESTRY-2460
+
+ @Test
+ public void nested_bean_editor_and_bean_display()
+ {
+ start("Nested BeanEditor");
+
+ type("name", "Parent");
+ type("age", "60");
+
+ type("name_0", "Child");
+ type("age_0", "40");
+
+ clickAndWait(SUBMIT);
+
+ assertText("//div[@id='content']//h1", "Nested BeanDisplay");
+
+ // As usual, Selenium is fighting me in terms of extracting data, so the above check just ensures
+ // we made it past the form submit without error.
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Person.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Person.java?rev=670691&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Person.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/data/Person.java Mon Jun 23 11:05:36 2008
@@ -0,0 +1,58 @@
+// Copyright 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.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.data;
+
+import org.apache.tapestry5.beaneditor.Validate;
+
+public class Person
+{
+ @Validate("required,minlength=5")
+ private String name;
+
+ @Validate("required,min=1")
+ private int age;
+
+ private Person child;
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public int getAge()
+ {
+ return age;
+ }
+
+ public void setAge(int age)
+ {
+ this.age = age;
+ }
+
+ public Person getChild()
+ {
+ return child;
+ }
+
+ public void setChild(Person child)
+ {
+ this.child = child;
+ }
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java?rev=670691&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java Mon Jun 23 11:05:36 2008
@@ -0,0 +1,33 @@
+// Copyright 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.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.data.Person;
+
+public class NestedBeanDisplay
+{
+ @Persist
+ @Property
+ private Person parent;
+
+ Object initialize(Person person)
+ {
+ parent = person;
+
+ return this;
+ }
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanEditor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanEditor.java?rev=670691&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanEditor.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanEditor.java Mon Jun 23 11:05:36 2008
@@ -0,0 +1,39 @@
+// Copyright 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.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.InjectPage;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.data.Person;
+
+public class NestedBeanEditor
+{
+ @Property
+ private Person parent;
+
+ @InjectPage
+ private NestedBeanDisplay display;
+
+ void onPrepare()
+ {
+ parent = new Person();
+ parent.setChild(new Person());
+ }
+
+ Object onSuccess()
+ {
+ return display.initialize(parent);
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java Mon Jun 23 11:05:36 2008
@@ -61,6 +61,10 @@
}
private static final List<Item> ITEMS = CollectionFactory.newList(
+
+ new Item("nestedbeaneditor", "Nested BeanEditor",
+ "BeanEditor as override for property editor in BeanEditForm"),
+
new Item("actionpage", "Action Page", "tests fixture for ActionLink component"),
new Item("cleancachedemo", "Clean Cache Demo", "cache cleared properly during Ajax calls"),
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java Mon Jun 23 11:05:36 2008
@@ -20,6 +20,7 @@
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.runtime.ComponentEvent;
+import org.slf4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -50,7 +51,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
assertTrue(event.matches("eventType", "someId", 0));
assertFalse(event.matches("foo", "someId", 0));
@@ -68,7 +69,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
assertTrue(event.matches("EVENTTYPE", "someid", 0));
@@ -85,7 +86,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
assertTrue(event.matches("eventType", "someId", 0));
@@ -104,7 +105,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
assertTrue(event.matches("eventtype", "SOMEID", 0));
@@ -126,7 +127,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources, null);
assertSame(event.coerceContext(0, "java.lang.Integer"), value);
@@ -138,12 +139,15 @@
{
ComponentEventCallback handler = mockComponentEventHandler();
EventContext context = mockEventContext();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_getCount(context, 0);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, logger);
event.setMethodDescription("foo.Bar.baz()");
@@ -166,6 +170,9 @@
ComponentEventCallback handler = mockComponentEventHandler();
EventContext context = mockEventContext();
PageResources resources = mockPageResources();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_toClass(resources, Integer.class.getName(), Integer.class);
@@ -175,7 +182,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources, logger);
event.setMethodDescription("foo.Bar.baz()");
@@ -200,6 +207,9 @@
{
Object result = new Object();
String methodDescription = "foo.Bar.baz()";
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
ComponentEventCallback handler = mockComponentEventHandler();
@@ -207,7 +217,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null, logger);
event.setMethodDescription(methodDescription);
@@ -226,12 +236,15 @@
Object result = new Object();
String methodDescription = "foo.Bar.baz()";
ComponentEventCallback handler = mockComponentEventHandler();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_handleResult(handler, result, false);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null, logger);
event.setMethodDescription(methodDescription);
@@ -246,10 +259,13 @@
public void store_null_result_does_not_abort_or_invoke_handler()
{
ComponentEventCallback handler = mockComponentEventHandler();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null, logger);
event.setMethodDescription("foo.Bar.baz()");
@@ -266,12 +282,15 @@
{
Object result = new Object();
ComponentEventCallback handler = mockComponentEventHandler();
+ Logger logger = mockLogger();
+
+ expect(logger.isDebugEnabled()).andStubReturn(false);
expect(handler.handleResult(result)).andReturn(true);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null, logger);
event.setMethodDescription("foo.Bar.baz()");
event.storeResult(result);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java Mon Jun 23 11:05:36 2008
@@ -28,6 +28,7 @@
import org.apache.tapestry5.model.ParameterModel;
import org.apache.tapestry5.runtime.Component;
import org.easymock.EasyMock;
+import org.slf4j.Logger;
import org.testng.annotations.Test;
public class ComponentPageElementImplTest extends InternalBaseTestCase
@@ -50,11 +51,15 @@
Component component = mockComponent();
ComponentModel model = mockComponentModel();
TypeCoercer coercer = mockTypeCoercer();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
replay();
+
ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
ComponentResources resources = cpe.getComponentResources();
@@ -80,9 +85,12 @@
ComponentModel model = mockComponentModel();
TypeCoercer coercer = mockTypeCoercer();
Block block = mockBlock();
+ Logger logger = mockLogger();
Instantiator ins = newInstantiator(component, model);
+ train_getLogger(model, logger);
+
replay();
ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
@@ -106,9 +114,12 @@
ComponentModel model = mockComponentModel();
Binding binding = mockBinding();
TypeCoercer coercer = mockTypeCoercer();
+ Logger logger = mockLogger();
Instantiator ins = newInstantiator(component, model);
+ train_getLogger(model, logger);
+
train_getParameterModel(model, "barney", null);
train_getSupportsInformalParameters(model, true);
@@ -137,6 +148,9 @@
TypeCoercer coercer = mockTypeCoercer();
Block block1 = mockBlock();
Block block2 = mockBlock();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -169,6 +183,9 @@
Binding binding = mockBinding();
TypeCoercer coercer = mockTypeCoercer();
ParameterModel pmodel = mockParameterModel();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -196,6 +213,9 @@
ComponentModel model = mockComponentModel();
ParameterModel pmodel = mockParameterModel();
TypeCoercer coercer = mockTypeCoercer();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -225,6 +245,9 @@
ParameterModel pmodel = mockParameterModel();
Location l = mockLocation();
TypeCoercer coercer = mockTypeCoercer();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -276,6 +299,9 @@
Binding binding = mockBinding();
TypeCoercer coercer = mockTypeCoercer();
ParameterModel pmodel = mockParameterModel();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -305,6 +331,9 @@
ComponentModel model = mockComponentModel();
Binding binding = mockBinding();
PageResources resources = mockPageResources();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
train_getSupportsInformalParameters(model, true);
@@ -338,6 +367,9 @@
ComponentModel model = mockComponentModel();
PageResources resources = mockPageResources();
Binding binding = mockBinding();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -369,6 +401,9 @@
Component component = mockComponent();
ComponentModel model = mockComponentModel();
TypeCoercer coercer = mockTypeCoercer();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
Instantiator ins2 = newInstantiator(component, model);
@@ -401,6 +436,9 @@
ComponentPageElement childElement = mockComponentPageElement();
Component childComponent = mockComponent();
TypeCoercer coercer = mockTypeCoercer();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
@@ -432,6 +470,9 @@
ComponentPageElement child2 = mockComponentPageElement();
TypeCoercer coercer = mockTypeCoercer();
Location l = mockLocation();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(pageComponent, model);
@@ -470,6 +511,9 @@
final String mixinClassName = "foo.Bar";
Component mixin = mockComponent();
ComponentModel mixinModel = mockComponentModel();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
Instantiator mixinIns = newInstantiator(mixin, mixinModel);
@@ -496,6 +540,9 @@
TypeCoercer coercer = mockTypeCoercer();
Component mixin = mockComponent();
ComponentModel mixinModel = mockComponentModel();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
Instantiator mixinIns = newInstantiator(mixin, mixinModel);
@@ -532,6 +579,9 @@
Component mixin = mockComponent();
TypeCoercer coercer = mockTypeCoercer();
Binding binding = mockBinding();
+ Logger logger = mockLogger();
+
+ train_getLogger(model, logger);
Instantiator ins = newInstantiator(component, model);
Instantiator mixinInstantiator = newInstantiator(mixin, mixinModel);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties?rev=670691&r1=670690&r2=670691&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties Mon Jun 23 11:05:36 2008
@@ -23,8 +23,5 @@
log4j.category.org.apache.tapestry5.integration.app1=debug
-log4j.category.org.apache.tapestry5.corelib.components.AjaxFormLoop=debug
-log4j.category.org.apache.tapestry5.corelib.components.Form=debug
-log4j.category.org.apache.tapestry5.corelib.components.FormFragment=debug
-log4j.category.org.apache.tapestry5.corelib.components.FormInjector=debug
+# log4j.category.org.apache.tapestry5.corelib.components=debug