Seam SVN: r9073 - trunk/src/test/unit/org/jboss/seam/test/unit.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-09-21 18:44:44 -0400 (Sun, 21 Sep 2008)
New Revision: 9073
Modified:
trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java
Log:
JBSEAM-3436
Modified: trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java 2008-09-21 21:00:08 UTC (rev 9072)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/InterceptorTest.java 2008-09-21 22:44:44 UTC (rev 9073)
@@ -237,12 +237,27 @@
ServletLifecycle.endApplication();
}
+ /**
+ * A hack for returning an exception from a thread
+ *
+ */
+ private class WrappedException {
+ Exception exception;
+ }
+
+ /**
+ * This test uses two threads to concurrently invoke the same method on the same component. It uses
+ * latches to control the progress of each thread to ensure that the bijection interceptor is
+ * correctly injecting/disinjecting the component at the right times.
+ *
+ * @throws Exception
+ */
@Test
public void testReentrantBijection() throws Exception
{
MockServletContext servletContext = new MockServletContext();
ServletLifecycle.beginApplication(servletContext);
- MockExternalContext externalContext = new MockExternalContext(servletContext);
+ final MockExternalContext externalContext = new MockExternalContext(servletContext);
Context appContext = new ApplicationContext( externalContext.getApplicationMap() );
appContext.set( Seam.getComponentName(Init.class), new Init() );
appContext.set( Seam.getComponentName(ConversationEntries.class) + ".component",
@@ -252,17 +267,10 @@
appContext.set( Seam.getComponentName(Foo.class) + ".component",
new Component(Foo.class, appContext) );
appContext.set( Seam.getComponentName(FooBar.class) + ".component",
- new Component(FooBar.class, appContext) );
-
- FacesLifecycle.beginRequest(externalContext);
- Manager.instance().setCurrentConversationId("1");
- FacesLifecycle.resumeConversation(externalContext);
- FacesLifecycle.setPhaseId(PhaseId.RENDER_RESPONSE);
+ new Component(FooBar.class, appContext) );
final Foo foo = new Foo();
final FooBar fooBar = new FooBar();
-
- Contexts.getSessionContext().set("foo", foo);
final BijectionInterceptor bi = new BijectionInterceptor();
bi.setComponent( new Component(FooBar.class, appContext) );
@@ -285,17 +293,27 @@
@Override public Method getMethod() { return m; }
@Override public Object[] getParameters() { return new Object[] { latchB }; }
};
-
+
+ final WrappedException thread1Exception = new WrappedException();
+ final WrappedException thread2Exception = new WrappedException();
+
new Thread(new Runnable() {
public void run() {
try
{
+ FacesLifecycle.beginRequest(externalContext);
+ Manager.instance().setCurrentConversationId("1");
+ FacesLifecycle.resumeConversation(externalContext);
+ FacesLifecycle.setPhaseId(PhaseId.RENDER_RESPONSE);
+
+ Contexts.getSessionContext().set("foo", foo);
+
Foo result = (Foo) bi.aroundInvoke( invocationA );
assert result == foo;
}
catch (Exception ex)
{
- throw new RuntimeException(ex);
+ thread1Exception.exception = ex;
}
finally
{
@@ -308,12 +326,19 @@
public void run() {
try
{
+ FacesLifecycle.beginRequest(externalContext);
+ Manager.instance().setCurrentConversationId("1");
+ FacesLifecycle.resumeConversation(externalContext);
+ FacesLifecycle.setPhaseId(PhaseId.RENDER_RESPONSE);
+
+ Contexts.getSessionContext().set("foo", foo);
+
Foo result = (Foo) bi.aroundInvoke( invocationB );
assert result == foo;
}
catch (Exception ex)
{
- throw new RuntimeException(ex);
+ thread2Exception.exception = ex;
}
finally
{
@@ -333,6 +358,9 @@
// Wait for invocationB
latchD.await();
+
+ if (thread1Exception.exception != null) throw thread1Exception.exception;
+ if (thread2Exception.exception != null) throw thread2Exception.exception;
}
@Test
16 years, 2 months
Seam SVN: r9072 - in trunk: examples/wicket/src/web/org/jboss/seam/example/wicket and 2 other directories.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-21 17:00:08 -0400 (Sun, 21 Sep 2008)
New Revision: 9072
Modified:
trunk/examples/wicket/src/action/org/jboss/seam/example/wicket/action/HotelBookingAction.java
trunk/examples/wicket/src/web/org/jboss/seam/example/wicket/Main.java
trunk/src/wicket/org/jboss/seam/wicket/SeamWebApplication.java
trunk/src/wicket/org/jboss/seam/wicket/WicketManager.java
trunk/src/wicket/org/jboss/seam/wicket/web/WicketRedirectFilter.java
Log:
JBSEAM-2992
Modified: trunk/examples/wicket/src/action/org/jboss/seam/example/wicket/action/HotelBookingAction.java
===================================================================
--- trunk/examples/wicket/src/action/org/jboss/seam/example/wicket/action/HotelBookingAction.java 2008-09-21 20:57:08 UTC (rev 9071)
+++ trunk/examples/wicket/src/action/org/jboss/seam/example/wicket/action/HotelBookingAction.java 2008-09-21 21:00:08 UTC (rev 9072)
@@ -48,6 +48,7 @@
public void selectHotel(Hotel hotel)
{
+ StatusMessages.instance().add("foo");
this.hotel = hotel;
}
@@ -89,7 +90,7 @@
public void confirm()
{
em.persist(booking);
- StatusMessages.instance().addToControl("body", "Thank you, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}");
+ StatusMessages.instance().add("Thank you, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}");
log.info("New booking: #{booking.id} for #{user.username}");
}
Modified: trunk/examples/wicket/src/web/org/jboss/seam/example/wicket/Main.java
===================================================================
--- trunk/examples/wicket/src/web/org/jboss/seam/example/wicket/Main.java 2008-09-21 20:57:08 UTC (rev 9071)
+++ trunk/examples/wicket/src/web/org/jboss/seam/example/wicket/Main.java 2008-09-21 21:00:08 UTC (rev 9072)
@@ -25,6 +25,7 @@
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.feedback.ContainerFeedbackMessageFilter;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
@@ -33,6 +34,7 @@
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.ComponentFeedbackPanel;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.PropertyModel;
@@ -78,7 +80,7 @@
hotelSearchForm = new HotelSearchForm("searchCriteria");
body.add(hotelSearchForm);
- messages = new ComponentFeedbackPanel("messages", body).setOutputMarkupId(true);
+ messages = new FeedbackPanel("messages", new ContainerFeedbackMessageFilter(this)).setOutputMarkupId(true);
body.add(messages);
/*
Modified: trunk/src/wicket/org/jboss/seam/wicket/SeamWebApplication.java
===================================================================
--- trunk/src/wicket/org/jboss/seam/wicket/SeamWebApplication.java 2008-09-21 20:57:08 UTC (rev 9071)
+++ trunk/src/wicket/org/jboss/seam/wicket/SeamWebApplication.java 2008-09-21 21:00:08 UTC (rev 9072)
@@ -77,24 +77,14 @@
IFormSubmitListener.INTERFACE.getName().equals(name) ||
ILinkListener.INTERFACE.getName().equals(name) ||
IBehaviorListener.INTERFACE.getName().equals(name) ||
- IOnChangeListener.INTERFACE.getName().equals(name) ))
+ IOnChangeListener.INTERFACE.getName().equals(name) ||
+ IRedirectListener.INTERFACE.getName().equals(name) ))
{
// TODO Do this nicely
StringBuilder stringBuilder = new StringBuilder(url);
stringBuilder.append("&" + Manager.instance().getConversationIdParameter() + "=" + Conversation.instance().getId());
url = stringBuilder.subSequence(0, stringBuilder.length());
}
- else if ( IRedirectListener.INTERFACE.getName().equals(name) )
- {
- if (!Manager.instance().isLongRunningConversation())
- {
- Manager.instance().beforeRedirect();
- }
-
- StringBuilder stringBuilder = new StringBuilder(url);
- stringBuilder.append("&" + Manager.instance().getConversationIdParameter() + "=" + Conversation.instance().getId());
- url = stringBuilder.subSequence(0, stringBuilder.length());
- }
return url;
}
Modified: trunk/src/wicket/org/jboss/seam/wicket/WicketManager.java
===================================================================
--- trunk/src/wicket/org/jboss/seam/wicket/WicketManager.java 2008-09-21 20:57:08 UTC (rev 9071)
+++ trunk/src/wicket/org/jboss/seam/wicket/WicketManager.java 2008-09-21 21:00:08 UTC (rev 9072)
@@ -6,6 +6,7 @@
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.ConversationPropagation;
import org.jboss.seam.core.Manager;
@Scope(ScopeType.EVENT)
@@ -15,32 +16,16 @@
public class WicketManager extends Manager
{
- private boolean controllingRedirect;
-
- public String appendConversationIdFromRedirectFilter(String url, String viewId)
+ public String appendConversationIdFromRedirectFilter(String url)
{
- boolean appendConversationId = !controllingRedirect;
- if (appendConversationId)
+ super.beforeRedirect();
+ if (ConversationPropagation.instance().getConversationId() != null)
{
- beforeRedirect(viewId);
- url = encodeConversationId(url, viewId);
+ url = encodeConversationIdParameter( url, getConversationIdParameter(), ConversationPropagation.instance().getConversationId() );
}
return url;
}
- /**
- * Temporarily promote a temporary conversation to
- * a long running conversation for the duration of
- * a browser redirect. After the redirect, the
- * conversation will be demoted back to a temporary
- * conversation. Handle any changes to the conversation
- * id, due to propagation via natural id.
- */
- public void beforeRedirect(String viewId)
- {
- // TODO - do something here!
- }
-
public static WicketManager instance()
{
return (WicketManager) Manager.instance();
Modified: trunk/src/wicket/org/jboss/seam/wicket/web/WicketRedirectFilter.java
===================================================================
--- trunk/src/wicket/org/jboss/seam/wicket/web/WicketRedirectFilter.java 2008-09-21 20:57:08 UTC (rev 9071)
+++ trunk/src/wicket/org/jboss/seam/wicket/web/WicketRedirectFilter.java 2008-09-21 21:00:08 UTC (rev 9072)
@@ -2,6 +2,7 @@
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.FRAMEWORK;
+import static org.jboss.seam.core.Manager.REDIRECT_FROM_MANAGER;
import java.io.IOException;
@@ -9,12 +10,17 @@
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.annotations.web.Filter;
+import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.web.AbstractFilter;
+import org.jboss.seam.wicket.WicketManager;
/**
* Disable the redirect filter when using Wicket (as JSF is an EE library, we
@@ -26,19 +32,32 @@
@Name("org.jboss.seam.web.redirectFilter")
@Install(precedence = FRAMEWORK, classDependencies="org.apache.wicket.Application")
@BypassInterceptors
+@Filter
public class WicketRedirectFilter extends AbstractFilter
{
-
-
- @Override
- public boolean isDisabled()
+
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException
{
- return true;
+ chain.doFilter( request, wrapResponse( (HttpServletResponse) response ) );
}
-
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
+
+ private static ServletResponse wrapResponse(HttpServletResponse response)
{
-
-
+ return new HttpServletResponseWrapper(response)
+ {
+ @Override
+ public void sendRedirect(String url) throws IOException
+ {
+ if ( Contexts.isEventContextActive() && !Contexts.getEventContext().isSet(REDIRECT_FROM_MANAGER) )
+ {
+ if ( Contexts.isConversationContextActive() )
+ {
+ url = WicketManager.instance().appendConversationIdFromRedirectFilter(url);
+ }
+ }
+ super.sendRedirect(url);
+ }
+ };
}
}
16 years, 2 months
Seam SVN: r9071 - trunk/src/main/org/jboss/seam/core.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-09-21 16:57:08 -0400 (Sun, 21 Sep 2008)
New Revision: 9071
Modified:
trunk/src/main/org/jboss/seam/core/Manager.java
Log:
Make method protected for use with Wicket
Modified: trunk/src/main/org/jboss/seam/core/Manager.java
===================================================================
--- trunk/src/main/org/jboss/seam/core/Manager.java 2008-09-21 06:38:44 UTC (rev 9070)
+++ trunk/src/main/org/jboss/seam/core/Manager.java 2008-09-21 20:57:08 UTC (rev 9071)
@@ -760,7 +760,7 @@
return encodeConversationIdParameter( url, cip.getParameterName(), cip.getParameterValue(conversationId) );
}
- private String encodeConversationIdParameter(String url, String paramName, String paramValue)
+ protected String encodeConversationIdParameter(String url, String paramName, String paramValue)
{
if ( Session.instance().isInvalid() || containsParameter(url, paramName) )
{
16 years, 2 months
Seam SVN: r9070 - in trunk/src: main/org/jboss/seam/navigation and 2 other directories.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 02:38:44 -0400 (Sun, 21 Sep 2008)
New Revision: 9070
Modified:
trunk/src/main/org/jboss/seam/navigation/Action.java
trunk/src/main/org/jboss/seam/navigation/Page.java
trunk/src/main/org/jboss/seam/navigation/Pages.java
trunk/src/main/org/jboss/seam/pages-2.1.xsd
trunk/src/test/unit/META-INF/pagesForPageActionsTest.xml
trunk/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java
Log:
JBSEAM-2469
Modified: trunk/src/main/org/jboss/seam/navigation/Action.java
===================================================================
--- trunk/src/main/org/jboss/seam/navigation/Action.java 2008-09-21 06:32:13 UTC (rev 9069)
+++ trunk/src/main/org/jboss/seam/navigation/Action.java 2008-09-21 06:38:44 UTC (rev 9070)
@@ -14,11 +14,12 @@
private MethodExpression methodExpression;
private ValueExpression valueExpression;
private String outcome;
+ private boolean onPostback = true;
- public boolean isExecutable()
+ public boolean isExecutable(boolean postback)
{
- return valueExpression==null ||
- Boolean.TRUE.equals( valueExpression.getValue() );
+ return (!postback || (postback && onPostback)) &&
+ (valueExpression == null || Boolean.TRUE.equals( valueExpression.getValue()));
}
public MethodExpression getMethodExpression()
@@ -47,4 +48,14 @@
{
this.outcome = outcome;
}
+
+ public boolean isOnPostback()
+ {
+ return onPostback;
+ }
+
+ public void setOnPostback(boolean onPostback)
+ {
+ this.onPostback = onPostback;
+ }
}
Modified: trunk/src/main/org/jboss/seam/navigation/Page.java
===================================================================
--- trunk/src/main/org/jboss/seam/navigation/Page.java 2008-09-21 06:32:13 UTC (rev 9069)
+++ trunk/src/main/org/jboss/seam/navigation/Page.java 2008-09-21 06:38:44 UTC (rev 9070)
@@ -276,7 +276,7 @@
for ( Action action: getActions() )
{
- if ( action.isExecutable() )
+ if ( action.isExecutable(facesContext.getRenderKit().getResponseStateManager().isPostback(facesContext)) )
{
String outcome = action.getOutcome();
String fromAction = outcome;
Modified: trunk/src/main/org/jboss/seam/navigation/Pages.java
===================================================================
--- trunk/src/main/org/jboss/seam/navigation/Pages.java 2008-09-21 06:32:13 UTC (rev 9069)
+++ trunk/src/main/org/jboss/seam/navigation/Pages.java 2008-09-21 06:38:44 UTC (rev 9070)
@@ -1209,12 +1209,12 @@
page.setEventType( eventElement.attributeValue("type") );
}
- Action action = parseAction(element, "action");
+ Action action = parseAction(element, "action", false);
if (action!=null) page.getActions().add(action);
List<Element> childElements = element.elements("action");
for (Element childElement: childElements)
{
- page.getActions().add( parseAction(childElement, "execute") );
+ page.getActions().add( parseAction(childElement, "execute", true) );
}
String bundle = element.attributeValue("bundle");
@@ -1239,7 +1239,7 @@
return page;
}
- private static Action parseAction(Element element, String actionAtt)
+ private static Action parseAction(Element element, String actionAtt, boolean conditionalsAllowed)
{
Action action = new Action();
String methodExpression = element.attributeValue(actionAtt);
@@ -1252,10 +1252,15 @@
{
action.setOutcome(methodExpression);
}
- String expression = element.attributeValue("if");
- if (expression!=null)
+
+ if (conditionalsAllowed)
{
- action.setValueExpression( Expressions.instance().createValueExpression(expression) );
+ String expression = element.attributeValue("if");
+ if (expression!=null)
+ {
+ action.setValueExpression( Expressions.instance().createValueExpression(expression) );
+ }
+ action.setOnPostback(!"false".equals(element.attributeValue("on-postback")));
}
return action;
}
Modified: trunk/src/main/org/jboss/seam/pages-2.1.xsd
===================================================================
--- trunk/src/main/org/jboss/seam/pages-2.1.xsd 2008-09-21 06:32:13 UTC (rev 9069)
+++ trunk/src/main/org/jboss/seam/pages-2.1.xsd 2008-09-21 06:38:44 UTC (rev 9070)
@@ -179,6 +179,7 @@
</xs:element>
<xs:attributeGroup name="attlist.action">
<xs:attribute name="if" type="pages:boolean-value-expression" />
+ <xs:attribute name="on-postback" default="true" type="pages:tf-boolean"/>
<xs:attribute name="execute" use="required" type="pages:method-expression" />
</xs:attributeGroup>
Modified: trunk/src/test/unit/META-INF/pagesForPageActionsTest.xml
===================================================================
--- trunk/src/test/unit/META-INF/pagesForPageActionsTest.xml 2008-09-21 06:32:13 UTC (rev 9069)
+++ trunk/src/test/unit/META-INF/pagesForPageActionsTest.xml 2008-09-21 06:38:44 UTC (rev 9070)
@@ -84,8 +84,13 @@
</rule>
</navigation>
</page>
+
+ <page view-id="/action-test06.xhtml">
+ <action execute="#{testActions.nonNullActionA}"/>
+ <action execute="#{testActions.nonNullActionB}" on-postback="false"/>
+ </page>
- <!-- The next two page nodes (action-test05*) demonstrate the old
+ <!-- The next two page nodes (action-test99*) demonstrate the old
behavior, where successive actions could trigger navigations on
different page nodes because the viewId changes mid-run -->
<page view-id="/action-test99a.xhtml">
Modified: trunk/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java 2008-09-21 06:32:13 UTC (rev 9069)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java 2008-09-21 06:38:44 UTC (rev 9070)
@@ -7,11 +7,13 @@
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.faces.FacesManager;
+import org.jboss.seam.mock.MockHttpServletRequest;
import org.jboss.seam.navigation.Pages;
import org.jboss.seam.test.unit.component.TestActions;
import org.testng.annotations.Test;
import javax.faces.context.FacesContext;
+import javax.faces.render.ResponseStateManager;
import java.util.List;
import java.util.Map;
@@ -66,6 +68,11 @@
assertActionCalls(testActions, new String[] { "nonNullActionA", "nonNullActionB" });
}
+ /**
+ * This test verifies that an action method with a null return can still match
+ * a navigation rule and short-circuit the remaining actions. The key is that
+ * a navigation rule is matched, not what the return value is.
+ */
@Test(enabled = true)
public void testShortCircuitOnNullOutcome()
{
@@ -83,7 +90,7 @@
* will short circuit the action calls.
*/
@Test(enabled = true)
- public void testShortCircuitOnFirstNonNullOutcome()
+ public void testShortCircuitOnNonNullOutcomeToSamePage()
{
FacesContext facesContext = FacesContext.getCurrentInstance();
TestActions testActions = TestActions.instance();
@@ -112,6 +119,23 @@
"Expecting a redirect to /pageA.xhtml but redirected to " + Contexts.getEventContext().get("lastRedirectViewId");
assert facesContext.getResponseComplete() == true : "The response should have been marked as complete";
}
+
+ /**
+ * Verify that only those actions without on-postback="false" are executed when the
+ * magic postback parameter (javax.faces.ViewState) is present in the request map.
+ */
+ @Test(enabled = true)
+ public void testPostbackConditionOnPageAction()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ simulatePostback(facesContext);
+ TestActions testActions = TestActions.instance();
+
+ facesContext.getViewRoot().setViewId("/action-test06.xhtml");
+ Pages.instance().preRender(facesContext);
+ assertViewId(facesContext, "/action-test06.xhtml");
+ assertActionCalls(testActions, new String[] { "nonNullActionA" });
+ }
/**
* This test is here (and disabled) to demonstrate the old behavior. All page
@@ -168,6 +192,13 @@
Contexts.getEventContext().remove(Component.getComponentName(TestActions.class));
}
+ private void simulatePostback(FacesContext facesContext)
+ {
+ MockHttpServletRequest request = (MockHttpServletRequest) facesContext.getExternalContext().getRequest();
+ request.getParameters().put(ResponseStateManager.VIEW_STATE_PARAM, new String[] { "true" });
+ assert facesContext.getRenderKit().getResponseStateManager().isPostback(facesContext) == true;
+ }
+
@Scope(ScopeType.EVENT)
@Name("org.jboss.seam.core.manager")
@BypassInterceptors
16 years, 2 months
Seam SVN: r9069 - in branches/community/Seam_2_0/src: main/org/jboss/seam/navigation and 2 other directories.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 02:32:13 -0400 (Sun, 21 Sep 2008)
New Revision: 9069
Modified:
branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Action.java
branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Page.java
branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Pages.java
branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.dtd
branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.xsd
branches/community/Seam_2_0/src/test/unit/META-INF/pagesForPageActionsTest.xml
branches/community/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java
Log:
JBSEAM-2469
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Action.java
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Action.java 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Action.java 2008-09-21 06:32:13 UTC (rev 9069)
@@ -14,11 +14,12 @@
private MethodExpression methodExpression;
private ValueExpression valueExpression;
private String outcome;
+ private boolean onPostback = true;
- public boolean isExecutable()
+ public boolean isExecutable(boolean postback)
{
- return valueExpression==null ||
- Boolean.TRUE.equals( valueExpression.getValue() );
+ return (!postback || (postback && onPostback)) &&
+ (valueExpression == null || Boolean.TRUE.equals( valueExpression.getValue()));
}
public MethodExpression getMethodExpression()
@@ -47,4 +48,14 @@
{
this.outcome = outcome;
}
+
+ public boolean isOnPostback()
+ {
+ return onPostback;
+ }
+
+ public void setOnPostback(boolean onPostback)
+ {
+ this.onPostback = onPostback;
+ }
}
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Page.java
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Page.java 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Page.java 2008-09-21 06:32:13 UTC (rev 9069)
@@ -252,7 +252,7 @@
for ( Action action: getActions() )
{
- if ( action.isExecutable() )
+ if ( action.isExecutable(facesContext.getRenderKit().getResponseStateManager().isPostback(facesContext)) )
{
String outcome = action.getOutcome();
String fromAction = outcome;
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Pages.java
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Pages.java 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/navigation/Pages.java 2008-09-21 06:32:13 UTC (rev 9069)
@@ -1074,12 +1074,12 @@
page.setEventType( eventElement.attributeValue("type") );
}
- Action action = parseAction(element, "action");
+ Action action = parseAction(element, "action", false);
if (action!=null) page.getActions().add(action);
List<Element> childElements = element.elements("action");
for (Element childElement: childElements)
{
- page.getActions().add( parseAction(childElement, "execute") );
+ page.getActions().add( parseAction(childElement, "execute", true) );
}
String bundle = element.attributeValue("bundle");
@@ -1104,7 +1104,7 @@
return page;
}
- private static Action parseAction(Element element, String actionAtt)
+ private static Action parseAction(Element element, String actionAtt, boolean conditionalsAllowed)
{
Action action = new Action();
String methodExpression = element.attributeValue(actionAtt);
@@ -1117,10 +1117,15 @@
{
action.setOutcome(methodExpression);
}
- String expression = element.attributeValue("if");
- if (expression!=null)
+
+ if (conditionalsAllowed)
{
- action.setValueExpression( Expressions.instance().createValueExpression(expression) );
+ String expression = element.attributeValue("if");
+ if (expression!=null)
+ {
+ action.setValueExpression( Expressions.instance().createValueExpression(expression) );
+ }
+ action.setOnPostback(!"false".equals(element.attributeValue("on-postback")));
}
return action;
}
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.dtd
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.dtd 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.dtd 2008-09-21 06:32:13 UTC (rev 9069)
@@ -41,6 +41,7 @@
<!ELEMENT action EMPTY>
<!ATTLIST action if CDATA #IMPLIED>
+<!ATTLIST action on-postback (true|false) "true">
<!ATTLIST action execute CDATA #REQUIRED>
<!ELEMENT restrict (#PCDATA)>
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.xsd
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.xsd 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/pages-2.0.xsd 2008-09-21 06:32:13 UTC (rev 9069)
@@ -119,6 +119,7 @@
</xs:element>
<xs:attributeGroup name="attlist.action">
<xs:attribute name="if"/>
+ <xs:attribute name="on-postback" type="xs:boolean" default="true"/>
<xs:attribute name="execute" use="required"/>
</xs:attributeGroup>
<xs:element name="restrict" type="xs:string"/>
Modified: branches/community/Seam_2_0/src/test/unit/META-INF/pagesForPageActionsTest.xml
===================================================================
--- branches/community/Seam_2_0/src/test/unit/META-INF/pagesForPageActionsTest.xml 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/test/unit/META-INF/pagesForPageActionsTest.xml 2008-09-21 06:32:13 UTC (rev 9069)
@@ -82,8 +82,13 @@
</rule>
</navigation>
</page>
+
+ <page view-id="/action-test06.xhtml">
+ <action execute="#{testActions.nonNullActionA}"/>
+ <action execute="#{testActions.nonNullActionB}" on-postback="false"/>
+ </page>
- <!-- The next two page nodes (action-test05*) demonstrate the old
+ <!-- The next two page nodes (action-test99*) demonstrate the old
behavior, where successive actions could trigger navigations on
different page nodes because the viewId changes mid-run -->
<page view-id="/action-test99a.xhtml">
Modified: branches/community/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java
===================================================================
--- branches/community/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java 2008-09-21 04:23:18 UTC (rev 9068)
+++ branches/community/Seam_2_0/src/test/unit/org/jboss/seam/test/unit/PageActionsTest.java 2008-09-21 06:32:13 UTC (rev 9069)
@@ -17,6 +17,7 @@
import org.jboss.seam.mock.MockApplication;
import org.jboss.seam.mock.MockExternalContext;
import org.jboss.seam.mock.MockFacesContext;
+import org.jboss.seam.mock.MockHttpServletRequest;
import org.jboss.seam.navigation.Pages;
import org.jboss.seam.test.unit.component.TestActions;
import org.jboss.seam.util.Conversions;
@@ -25,6 +26,8 @@
import org.testng.annotations.Test;
import javax.faces.context.FacesContext;
+import javax.faces.render.ResponseStateManager;
+
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -112,6 +115,11 @@
assertActionCalls(testActions, new String[] { "nonNullActionA", "nonNullActionB" });
}
+ /**
+ * This test verifies that an action method with a null return can still match
+ * a navigation rule and short-circuit the remaining actions. The key is that
+ * a navigation rule is matched, not what the return value is.
+ */
@Test(enabled = true)
public void testShortCircuitOnNullOutcome()
{
@@ -129,7 +137,7 @@
* will short circuit the action calls.
*/
@Test(enabled = true)
- public void testShortCircuitOnFirstNonNullOutcome()
+ public void testShortCircuitOnNonNullOutcomeToSamePage()
{
FacesContext facesContext = FacesContext.getCurrentInstance();
TestActions testActions = TestActions.instance();
@@ -158,6 +166,23 @@
"Expecting a redirect to /pageA.xhtml but redirected to " + Contexts.getEventContext().get("lastRedirectViewId");
assert facesContext.getResponseComplete() == true : "The response should have been marked as complete";
}
+
+ /**
+ * Verify that only those actions without on-postback="false" are executed when the
+ * magic postback parameter (javax.faces.ViewState) is present in the request map.
+ */
+ @Test(enabled = true)
+ public void testPostbackConditionOnPageAction()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ simulatePostback(facesContext);
+ TestActions testActions = TestActions.instance();
+
+ facesContext.getViewRoot().setViewId("/action-test06.xhtml");
+ Pages.instance().preRender(facesContext);
+ assertViewId(facesContext, "/action-test06.xhtml");
+ assertActionCalls(testActions, new String[] { "nonNullActionA" });
+ }
/**
* This test is here (and disabled) to demonstrate the old behavior. All page
@@ -236,6 +261,13 @@
appContext.set(Seam.getComponentName(clazz) + ".component", new Component(clazz));
}
+ private void simulatePostback(FacesContext facesContext)
+ {
+ MockHttpServletRequest request = (MockHttpServletRequest) facesContext.getExternalContext().getRequest();
+ request.getParameters().put(ResponseStateManager.VIEW_STATE_PARAM, new String[] { "true" });
+ assert facesContext.getRenderKit().getResponseStateManager().isPostback(facesContext) == true;
+ }
+
@Scope(ScopeType.EVENT)
@Name("org.jboss.seam.core.manager")
@BypassInterceptors
16 years, 2 months
Seam SVN: r9068 - branches/community/Seam_2_0.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 00:23:18 -0400 (Sun, 21 Sep 2008)
New Revision: 9068
Modified:
branches/community/Seam_2_0/build.xml
Log:
remove icefaces-staging when cleaning
Modified: branches/community/Seam_2_0/build.xml
===================================================================
--- branches/community/Seam_2_0/build.xml 2008-09-21 04:22:36 UTC (rev 9067)
+++ branches/community/Seam_2_0/build.xml 2008-09-21 04:23:18 UTC (rev 9068)
@@ -144,6 +144,7 @@
<delete dir="${ui.dir}/target" quiet="${quietclean}"/>
<delete dir="${doc.ref.dir}/target" quiet="${quietclean}" />
<delete dir="${doc.ref.dir}/tmp" quiet="${quietclean}" />
+ <delete dir="${seamgen.dir}/icefaces-staging" quiet="${quietclean}"/>
<cleanexample name="integration" path="${seam.dir}/src/test/integration" message="" />
</target>
16 years, 2 months
Seam SVN: r9067 - trunk.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 00:22:36 -0400 (Sun, 21 Sep 2008)
New Revision: 9067
Modified:
trunk/build.xml
Log:
remove icefaces-staging when cleaning
Modified: trunk/build.xml
===================================================================
--- trunk/build.xml 2008-09-21 04:22:12 UTC (rev 9066)
+++ trunk/build.xml 2008-09-21 04:22:36 UTC (rev 9067)
@@ -155,6 +155,7 @@
<delete dir="${bootstrap.dir}/tmp" quiet="${quietclean}" />
<delete dir="${bootstrap.dir}/data" quiet="${quietclean}" />
<delete dir="${ui.dir}/target" quiet="${quietclean}"/>
+ <delete dir="${seamgen.dir}/icefaces-staging" quiet="${quietclean}"/>
<cleanexample name="integration" path="${seam.dir}/src/test/integration" message="" />
</target>
16 years, 2 months
Seam SVN: r9066 - trunk/src/gen/org/jboss/seam/tool.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 00:22:12 -0400 (Sun, 21 Sep 2008)
New Revision: 9066
Modified:
trunk/src/gen/org/jboss/seam/tool/Util.java
Log:
JBSEAM-2348
Modified: trunk/src/gen/org/jboss/seam/tool/Util.java
===================================================================
--- trunk/src/gen/org/jboss/seam/tool/Util.java 2008-09-21 04:21:38 UTC (rev 9065)
+++ trunk/src/gen/org/jboss/seam/tool/Util.java 2008-09-21 04:22:12 UTC (rev 9066)
@@ -3,6 +3,9 @@
import java.util.HashSet;
import java.util.Set;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.ToOne;
+
public class Util
{
public String lower(String name)
@@ -17,4 +20,8 @@
{
return new HashSet();
}
+ public boolean isToOne(Property property)
+ {
+ return (property.getValue() != null) && (property.getValue() instanceof ToOne);
+ }
}
16 years, 2 months
Seam SVN: r9065 - in branches/community/Seam_2_0: ui/src/main/java/org/jboss/seam/ui/validator and 1 other directory.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 00:21:38 -0400 (Sun, 21 Sep 2008)
New Revision: 9065
Modified:
branches/community/Seam_2_0/doc/Seam_Reference_Guide/en-US/Validation.xml
branches/community/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java
Log:
JBSEAM-3438, including documentation
Modified: branches/community/Seam_2_0/doc/Seam_Reference_Guide/en-US/Validation.xml
===================================================================
--- branches/community/Seam_2_0/doc/Seam_Reference_Guide/en-US/Validation.xml 2008-09-21 04:21:16 UTC (rev 9064)
+++ branches/community/Seam_2_0/doc/Seam_Reference_Guide/en-US/Validation.xml 2008-09-21 04:21:38 UTC (rev 9065)
@@ -151,14 +151,31 @@
<para>
Now we need to do something about displaying feedback to the
user when validation fails. Currently we are displaying all
- messages at the top of the form. What we would really like to
- do is display the message next to the field with the error
- (this is possible in plain JSF), highlight the field and
- label (this is not possible) and, for good measure, display
- some image next to the field (also not possible). We also
- want to display a little colored asterisk next to the label
- for each required form field.
+ messages at the top of the form. In order for the user to correlate the message with an input, you need to define a label using the standard <literal>label</literal> attribute on the input component.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[<h:inputText value="#{location.zip}" required="true" label="Zip:">
+ <s:validate/>
+</h:inputText>]]></programlisting>
+
+ <para>
+ You can then inject this value into the message string using
+ the placeholder {0} (the first and only parameter passed to a
+ JSF message for a Hiberate Validator restriction). See the
+ internationalization section for more information regarding
+ where to define these messages.
+ </para>
+
+ <programlisting>validator.length={0} length must be between {min} and {max}</programlisting>
+ <para>
+ What we would really like to do, though, is display the message
+ next to the field with the error (this is possible in plain
+ JSF), highlight the field and label (this is not possible) and,
+ for good measure, display some image next to the field (also
+ not possible). We also want to display a little colored
+ asterisk next to the label for each required form field. Using
+ this approach, the identifying label is not necessary.
</para>
<para>
@@ -246,7 +263,7 @@
</h:form>]]></programlisting>
<para>
- It's better style to define explicit ids for
+ It's better style to define explicit ids for
important controls on the page, especially if you want to do
automated testing for the UI, using some toolkit like
Selenium. If you don't provide explicit ids, JSF will generate
@@ -276,13 +293,13 @@
</h:form>]]></programlisting>
- <para>
- And what if you want to specify a different message to be
- displayed when validation fails? You can use the Seam message
- bundle (and all it's goodies like el expressions inside the message,
- and per-view message bundles) with the Hibernate Validator:
- </para>
-
+ <para>
+ And what if you want to specify a different message to be
+ displayed when validation fails? You can use the Seam message
+ bundle (and all it's goodies like el expressions inside the message,
+ and per-view message bundles) with the Hibernate Validator:
+ </para>
+
<programlisting role="JAVA"><![CDATA[public class Location {
private String name;
private String zip;
@@ -294,10 +311,10 @@
@ZipCode(message="#{messages['location.zipCode.invalid']}")
public String getZip() { return zip; }
public void setZip(String z) { zip = z; }
-}]]></programlisting>
+}]]></programlisting>
<programlisting>
location.zipCode.invalid = The zip code is not valid for #{location.name}
</programlisting>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: branches/community/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java
===================================================================
--- branches/community/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java 2008-09-21 04:21:16 UTC (rev 9064)
+++ branches/community/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java 2008-09-21 04:21:38 UTC (rev 9065)
@@ -38,19 +38,19 @@
{
Throwable cause = ele.getCause();
if (cause==null) cause = ele;
- throw new ValidatorException( createMessage(cause), cause );
+ throw new ValidatorException(createMessage(cause), cause);
}
if ( invalidValues!=null && invalidValues.length>0 )
{
- throw new ValidatorException( createMessage(invalidValues) );
+ throw new ValidatorException(createMessage(invalidValues, resolveLabel(facesContext, component)));
}
}
}
- private FacesMessage createMessage(InvalidValue[] invalidValues)
+ private FacesMessage createMessage(InvalidValue[] invalidValues, Object label)
{
- return FacesMessages.createFacesMessage( FacesMessage.SEVERITY_ERROR, invalidValues[0].getMessage() );
+ return FacesMessages.createFacesMessage(FacesMessage.SEVERITY_ERROR, invalidValues[0].getMessage(), label);
}
private FacesMessage createMessage(Throwable cause)
@@ -58,4 +58,17 @@
return new FacesMessage(FacesMessage.SEVERITY_ERROR, "model validation failed:" + cause.getMessage(), null);
}
+ private Object resolveLabel(FacesContext facesContext, UIComponent component) {
+ Object lbl = component.getAttributes().get("label");
+ if (lbl == null || (lbl instanceof String && ((String) lbl).length() == 0))
+ {
+ lbl = component.getValueExpression("label");
+ }
+ if (lbl == null)
+ {
+ lbl = component.getClientId(facesContext);
+ }
+ return lbl;
+ }
+
}
16 years, 2 months
Seam SVN: r9064 - in trunk: ui/src/main/java/org/jboss/seam/ui/validator and 1 other directory.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-09-21 00:21:16 -0400 (Sun, 21 Sep 2008)
New Revision: 9064
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Validation.xml
trunk/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java
Log:
JBSEAM-3438, including documentation
Modified: trunk/doc/Seam_Reference_Guide/en-US/Validation.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Validation.xml 2008-09-21 04:20:24 UTC (rev 9063)
+++ trunk/doc/Seam_Reference_Guide/en-US/Validation.xml 2008-09-21 04:21:16 UTC (rev 9064)
@@ -151,14 +151,31 @@
<para>
Now we need to do something about displaying feedback to the
user when validation fails. Currently we are displaying all
- messages at the top of the form. What we would really like to
- do is display the message next to the field with the error
- (this is possible in plain JSF), highlight the field and
- label (this is not possible) and, for good measure, display
- some image next to the field (also not possible). We also
- want to display a little colored asterisk next to the label
- for each required form field.
+ messages at the top of the form. In order for the user to correlate the message with an input, you need to define a label using the standard <literal>label</literal> attribute on the input component.
+ </para>
+
+ <programlisting role="XHTML"><![CDATA[<h:inputText value="#{location.zip}" required="true" label="Zip:">
+ <s:validate/>
+</h:inputText>]]></programlisting>
+
+ <para>
+ You can then inject this value into the message string using
+ the placeholder {0} (the first and only parameter passed to a
+ JSF message for a Hiberate Validator restriction). See the
+ internationalization section for more information regarding
+ where to define these messages.
+ </para>
+
+ <programlisting>validator.length={0} length must be between {min} and {max}</programlisting>
+ <para>
+ What we would really like to do, though, is display the message
+ next to the field with the error (this is possible in plain
+ JSF), highlight the field and label (this is not possible) and,
+ for good measure, display some image next to the field (also
+ not possible). We also want to display a little colored
+ asterisk next to the label for each required form field. Using
+ this approach, the identifying label is not necessary.
</para>
<para>
@@ -246,7 +263,7 @@
</h:form>]]></programlisting>
<para>
- It's better style to define explicit ids for
+ It's better style to define explicit ids for
important controls on the page, especially if you want to do
automated testing for the UI, using some toolkit like
Selenium. If you don't provide explicit ids, JSF will generate
@@ -276,13 +293,13 @@
</h:form>]]></programlisting>
- <para>
- And what if you want to specify a different message to be
- displayed when validation fails? You can use the Seam message
- bundle (and all it's goodies like el expressions inside the message,
- and per-view message bundles) with the Hibernate Validator:
- </para>
-
+ <para>
+ And what if you want to specify a different message to be
+ displayed when validation fails? You can use the Seam message
+ bundle (and all it's goodies like el expressions inside the message,
+ and per-view message bundles) with the Hibernate Validator:
+ </para>
+
<programlisting role="JAVA"><![CDATA[public class Location {
private String name;
private String zip;
@@ -294,10 +311,10 @@
@ZipCode(message="#{messages['location.zipCode.invalid']}")
public String getZip() { return zip; }
public void setZip(String z) { zip = z; }
-}]]></programlisting>
+}]]></programlisting>
<programlisting>
location.zipCode.invalid = The zip code is not valid for #{location.name}
</programlisting>
-</chapter>
\ No newline at end of file
+</chapter>
Modified: trunk/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java
===================================================================
--- trunk/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java 2008-09-21 04:20:24 UTC (rev 9063)
+++ trunk/ui/src/main/java/org/jboss/seam/ui/validator/ModelValidator.java 2008-09-21 04:21:16 UTC (rev 9064)
@@ -38,19 +38,19 @@
{
Throwable cause = ele.getCause();
if (cause==null) cause = ele;
- throw new ValidatorException( createMessage(cause), cause );
+ throw new ValidatorException(createMessage(cause), cause);
}
if ( invalidValues!=null && invalidValues.length>0 )
{
- throw new ValidatorException( createMessage(invalidValues) );
+ throw new ValidatorException(createMessage(invalidValues, resolveLabel(facesContext, component)));
}
}
}
- private FacesMessage createMessage(InvalidValue[] invalidValues)
+ private FacesMessage createMessage(InvalidValue[] invalidValues, Object label)
{
- return FacesMessages.createFacesMessage( FacesMessage.SEVERITY_ERROR, invalidValues[0].getMessage() );
+ return FacesMessages.createFacesMessage(FacesMessage.SEVERITY_ERROR, invalidValues[0].getMessage(), label);
}
private FacesMessage createMessage(Throwable cause)
@@ -58,4 +58,17 @@
return new FacesMessage(FacesMessage.SEVERITY_ERROR, "model validation failed:" + cause.getMessage(), null);
}
+ private Object resolveLabel(FacesContext facesContext, UIComponent component) {
+ Object lbl = component.getAttributes().get("label");
+ if (lbl == null || (lbl instanceof String && ((String) lbl).length() == 0))
+ {
+ lbl = component.getValueExpression("label");
+ }
+ if (lbl == null)
+ {
+ lbl = component.getClientId(facesContext);
+ }
+ return lbl;
+ }
+
}
16 years, 2 months