Author: kmenard
Date: Tue Aug 19 18:14:18 2008
New Revision: 687213
URL: http://svn.apache.org/viewvc?rev=687213&view=rev
Log:
Fixed TAPESTRY-2592: BeanEditor should provide a "BeanEditContext" into the
environment. (or PropertyEditContext should include the bean class).
Patch from Robert Zeigler, slightly modified to match existing code formatting.
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanEditContext.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/BeanEditorTest.java
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
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=687213&r1=687212&r2=687213&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
Tue Aug 19 18:14:18 2008
@@ -14,6 +14,7 @@
package org.apache.tapestry5.corelib.components;
+import java.lang.annotation.Annotation;
import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Parameter;
@@ -24,12 +25,15 @@
import org.apache.tapestry5.internal.beaneditor.BeanModelUtils;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.services.BeanEditContext;
import org.apache.tapestry5.services.BeanModelSource;
+import org.apache.tapestry5.services.Environment;
import org.apache.tapestry5.services.FormSupport;
/**
* A component that generates a user interface for editing the properties of a
bean. This is the central component of
* the [EMAIL PROTECTED] BeanEditForm}, and utilizes a [EMAIL PROTECTED]
PropertyEditor} for much of its functionality.
+ * This component places a [EMAIL PROTECTED] BeanEditContext} into the
environment.
*/
@SupportsInformalParameters
public class BeanEditor
@@ -50,6 +54,24 @@
}
}
+ static class CleanupEnvironment implements ComponentAction<BeanEditor>
+ {
+ private static final long serialVersionUID = 6867226962459227016L;
+
+ public void execute(BeanEditor component)
+ {
+ component.cleanupEnvironment();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "BeanEditor.CleanupEnvironment";
+ }
+ }
+
+ private static final ComponentAction<BeanEditor> 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
@@ -112,6 +134,9 @@
@Inject
private ComponentResources resources;
+ @Inject
+ private Environment environment;
+
@Environmental
private FormSupport formSupport;
@@ -131,7 +156,16 @@
{
formSupport.storeAndExecute(this, new Prepare());
}
+
+ void cleanupRender()
+ {
+ formSupport.storeAndExecute(this, CLEANUP_ENVIRONMENT);
+ }
+ /**
+ * Used to initialize the model if necessary, to instantiate the object
being edited if necessary,
+ * and to push the BeanEditContext into the environment.
+ */
void doPrepare()
{
if (model == null)
@@ -161,13 +195,33 @@
}
}
+ BeanEditContext context = new BeanEditContext()
+ {
+ public Class<?> getBeanClass()
+ {
+ return model.getBeanType();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> type)
+ {
+ return getBeanClass().getAnnotation(type);
+ }
+ };
+
+ environment.push(BeanEditContext.class, context);
+ }
+
+ void cleanupEnvironment()
+ {
+ environment.pop(BeanEditContext.class);
}
// For testing
- void inject(ComponentResources resources, PropertyOverrides overrides,
BeanModelSource source)
+ void inject(ComponentResources resources, PropertyOverrides overrides,
BeanModelSource source, Environment environment)
{
this.resources = resources;
this.overrides = overrides;
+ this.environment = environment;
modelSource = source;
}
}
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanEditContext.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanEditContext.java?rev=687213&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanEditContext.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanEditContext.java
Tue Aug 19 18:14:18 2008
@@ -0,0 +1,29 @@
+// 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.services;
+
+import org.apache.tapestry5.ioc.AnnotationProvider;
+
+/**
+ * Defines a context for editing a bean via [EMAIL PROTECTED]
org.apache.tapestry5.corelib.components.BeanEditor}.
+ * This value is made available at render time via the [EMAIL PROTECTED]
org.apache.tapestry5.annotations.Environmental} annotation.
+ */
+public interface BeanEditContext extends AnnotationProvider
+{
+ /**
+ * @return The class of the bean under edit.
+ */
+ Class<?> getBeanClass();
+}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/BeanEditorTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/BeanEditorTest.java?rev=687213&r1=687212&r2=687213&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/BeanEditorTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/BeanEditorTest.java
Tue Aug 19 18:14:18 2008
@@ -14,6 +14,8 @@
package org.apache.tapestry5.corelib.components;
+import java.lang.annotation.Annotation;
+
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.PropertyOverrides;
import org.apache.tapestry5.beaneditor.BeanModel;
@@ -21,8 +23,12 @@
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.services.BeanEditContext;
import org.apache.tapestry5.services.BeanModelSource;
+import org.apache.tapestry5.services.Environment;
import org.apache.tapestry5.test.TapestryTestCase;
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
import org.testng.annotations.Test;
public class BeanEditorTest extends TapestryTestCase
@@ -36,6 +42,7 @@
RegistrationData data = new RegistrationData();
Messages messages = mockMessages();
PropertyOverrides overrides = mockPropertyOverrides();
+ Environment env = EasyMock.createNiceMock(Environment.class);
train_getBoundType(resources, "object", RegistrationData.class);
@@ -46,10 +53,11 @@
expect(model.newInstance()).andReturn(data);
replay();
+ EasyMock.replay(env);
BeanEditor component = new BeanEditor();
- component.inject(resources, overrides, source);
+ component.inject(resources, overrides, source,env);
component.doPrepare();
@@ -69,6 +77,7 @@
Throwable exception = new RuntimeException("Fall down go boom.");
PropertyOverrides overrides = mockPropertyOverrides();
Messages messages = mockMessages();
+ Environment env = EasyMock.createNiceMock(Environment.class);
train_getOverrideMessages(overrides, messages);
@@ -85,10 +94,11 @@
expect(model.getBeanType()).andReturn(Runnable.class);
replay();
+ EasyMock.replay(env);
BeanEditor component = new BeanEditor();
- component.inject(resources, overrides, source);
+ component.inject(resources, overrides, source,env);
try
{
@@ -106,4 +116,89 @@
verify();
}
+
+ private static BeanEditContext contextEq()
+ {
+ EasyMock.reportMatcher(new IArgumentMatcher()
+ {
+ public void appendTo(StringBuffer buf)
+ {
+ buf.append("BeanEditContextEq(RegistrationData.class)");
+ }
+
+ public boolean matches(Object argument)
+ {
+ return (argument instanceof BeanEditContext) &&
+ ((BeanEditContext)argument).getBeanClass() ==
RegistrationData.class;
+ }
+ });
+
+ return null;
+ }
+
+ @Test
+ public void beaneditcontext_pushed_to_environment()
+ {
+ ComponentResources resources = mockComponentResources();
+ BeanModelSource source = mockBeanModelSource();
+ BeanModel model = mockBeanModel();
+ Environment env = mockEnvironment();
+ RegistrationData data = new RegistrationData();
+ Messages messages = mockMessages();
+ PropertyOverrides overrides = mockPropertyOverrides();
+
+ train_getBoundType(resources, "object", RegistrationData.class);
+
+ train_create(source, RegistrationData.class, true, messages, model);
+
+ train_getOverrideMessages(overrides, messages);
+
+ expect(model.newInstance()).andReturn(data);
+ expect(model.getBeanType()).andReturn(RegistrationData.class);
+
+ BeanEditContext ctxt = new BeanEditContext()
+ {
+ public Class<?> getBeanClass()
+ {
+ return RegistrationData.class;
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> type)
+ {
+ return null;
+ }
+ };
+
+ expect(env.push(EasyMock.eq(BeanEditContext.class),
contextEq())).andReturn(ctxt);
+ replay();
+
+ BeanEditor component = new BeanEditor();
+
+ component.inject(resources, overrides, source,env);
+
+ component.doPrepare();
+
+ verify();
+ }
+
+ @Test
+ public void beaneditcontext_popped_from_environment()
+ {
+ ComponentResources resources = mockComponentResources();
+ BeanModelSource source = mockBeanModelSource();
+ Environment env = mockEnvironment();
+ PropertyOverrides overrides = mockPropertyOverrides();
+
+ expect(env.pop(BeanEditContext.class)).andReturn(null);
+
+ replay();
+
+ BeanEditor component = new BeanEditor();
+
+ component.inject(resources, overrides, source,env);
+
+ component.cleanupEnvironment();
+
+ verify();
+ }
}
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=687213&r1=687212&r2=687213&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
Tue Aug 19 18:14:18 2008
@@ -16,6 +16,7 @@
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.mixins.RenderDisabled;
+import org.apache.tapestry5.integration.app1.data.RegistrationData;
import org.apache.tapestry5.integration.app1.pages.RenderErrorDemo;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.ClasspathResource;
@@ -2175,4 +2176,13 @@
assertTextPresent(
"Field flashDemo of class
org.apache.tapestry5.integration.app1.pages.FieldAnnotationConflict is already
claimed by @org.apache.tapestry5.annotations.InjectPage and can not be claimed
by @org.apache.tapestry5.annotations.Parameter.");
}
+
+ /**
+ * TAPESTRY-2592
+ */
+ public void bean_editor_pushes_bean_edit_context()
+ {
+ start("BeanEditor BeanEditContext");
+ assertTextPresent("Bean class from context is: " +
RegistrationData.class.getName());
+ }
}
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=687213&r1=687212&r2=687213&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
Tue Aug 19 18:14:18 2008
@@ -272,7 +272,9 @@
new Item("methodadvicedemo", "Method Advice Demo", "Advising
component methods."),
- new Item("HasBodyDemo", "Has Body Demo", "Verify the hasBody()
method of ComponentResources")
+ new Item("HasBodyDemo", "Has Body Demo", "Verify the hasBody()
method of ComponentResources"),
+ new Item("BeanEditorBeanEditContext", "BeanEditor BeanEditContext",
+ "BeanEditContext is pushed into enviroment by
BeanEditor.")
);
static