From 3d174c21a265aac05655502172e4440511b05922 Mon Sep 17 00:00:00 2001 From: Jeremy Grelle Date: Thu, 14 Feb 2008 14:50:14 +0000 Subject: [PATCH] SWF-448 - Remove specification of "renderIds" in Spring Faces components in favor of specifying components to render as part of flow definition logic. --- .../faces/ui/AjaxViewRoot.java | 68 +++++++++++-------- .../faces/ui/AjaxViewRootTests.java | 44 ++++++++++-- 2 files changed, 77 insertions(+), 35 deletions(-) diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java b/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java index 27802843..a759b586 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java @@ -13,6 +13,7 @@ import javax.faces.component.UIForm; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; +import javax.faces.el.ValueBinding; import javax.faces.event.AbortProcessingException; import javax.faces.event.FacesEvent; import javax.faces.event.PhaseId; @@ -31,8 +32,6 @@ public class AjaxViewRoot extends DelegatingViewRoot { public static final String PROCESS_IDS_PARAM = "processIds"; - public static final String RENDER_IDS_PARAM = "renderIds"; - protected static final String FORM_RENDERED = "formRendered"; protected static final String PROCESS_ALL = "*"; @@ -43,8 +42,14 @@ public class AjaxViewRoot extends DelegatingViewRoot { private String[] renderIds; + private static final String RENDER_IDS_EXPRESSION = "#{renderIds}"; + + private final ValueBinding renderIdsExpr; + public AjaxViewRoot(UIViewRoot original) { super(original); + renderIdsExpr = FacesContext.getCurrentInstance().getApplication().createValueBinding(RENDER_IDS_EXPRESSION); + original.setId(createUniqueId()); swapChildren(original, this); setId(original.getId() + "_ajax"); } @@ -63,9 +68,8 @@ public class AjaxViewRoot extends DelegatingViewRoot { * @see org.springframework.faces.webflow.DelegatingViewRoot#encodeAll(javax.faces.context.FacesContext) */ public void encodeAll(FacesContext context) throws IOException { - processRequestParams(context); - for (int i = 0; i < renderIds.length; i++) { - String renderId = renderIds[i]; + for (int i = 0; i < getRenderIds().length; i++) { + String renderId = getRenderIds()[i]; ContextCallback callback = new ContextCallback() { public void invokeContextCallback(FacesContext context, UIComponent target) { try { @@ -111,8 +115,8 @@ public class AjaxViewRoot extends DelegatingViewRoot { } private String findContainingFormId(FacesContext context) { - for (int i = 0; i < renderIds.length; i++) { - UIComponent component = context.getViewRoot().findComponent(renderIds[i]); + for (int i = 0; i < getRenderIds().length; i++) { + UIComponent component = context.getViewRoot().findComponent(getRenderIds()[i]); while (!(component instanceof UIViewRoot)) { component = component.getParent(); if (component instanceof UIForm) { @@ -136,9 +140,8 @@ public class AjaxViewRoot extends DelegatingViewRoot { * @see org.springframework.faces.webflow.DelegatingViewRoot#processDecodes(javax.faces.context.FacesContext) */ public void processDecodes(FacesContext context) { - processRequestParams(context); - for (int i = 0; i < processIds.length; i++) { - String processId = processIds[i]; + for (int i = 0; i < getProcessIds().length; i++) { + String processId = getProcessIds()[i]; ContextCallback callback = new ContextCallback() { public void invokeContextCallback(FacesContext context, UIComponent target) { target.processDecodes(context); @@ -149,21 +152,6 @@ public class AjaxViewRoot extends DelegatingViewRoot { broadCastEvents(context, PhaseId.APPLY_REQUEST_VALUES); } - private void processRequestParams(FacesContext context) { - - String processIdsParam = (String) context.getExternalContext().getRequestParameterMap().get(PROCESS_IDS_PARAM); - if (StringUtils.hasText(processIdsParam) && processIdsParam.contains("*")) { - processIds = new String[] { context.getViewRoot().getClientId(context) }; - } else { - processIds = StringUtils.delimitedListToStringArray(processIdsParam, ",", " "); - processIds = removeNestedChildren(context, processIds); - } - - String renderIdsParam = (String) context.getExternalContext().getRequestParameterMap().get(RENDER_IDS_PARAM); - renderIds = StringUtils.delimitedListToStringArray(renderIdsParam, ",", " "); - renderIds = removeNestedChildren(context, renderIds); - } - private String[] removeNestedChildren(FacesContext context, String[] ids) { List idList = Arrays.asList(ids); final List trimmedIds = new ArrayList(idList); @@ -189,8 +177,8 @@ public class AjaxViewRoot extends DelegatingViewRoot { * @see org.springframework.faces.webflow.DelegatingViewRoot#processUpdates(javax.faces.context.FacesContext) */ public void processUpdates(FacesContext context) { - for (int i = 0; i < processIds.length; i++) { - String processId = processIds[i]; + for (int i = 0; i < getProcessIds().length; i++) { + String processId = getProcessIds()[i]; ContextCallback callback = new ContextCallback() { public void invokeContextCallback(FacesContext context, UIComponent target) { target.processUpdates(context); @@ -206,8 +194,8 @@ public class AjaxViewRoot extends DelegatingViewRoot { * @see org.springframework.faces.webflow.DelegatingViewRoot#processValidators(javax.faces.context.FacesContext) */ public void processValidators(FacesContext context) { - for (int i = 0; i < processIds.length; i++) { - String processId = processIds[i]; + for (int i = 0; i < getProcessIds().length; i++) { + String processId = getProcessIds()[i]; ContextCallback callback = new ContextCallback() { public void invokeContextCallback(FacesContext context, UIComponent target) { target.processValidators(context); @@ -261,10 +249,32 @@ public class AjaxViewRoot extends DelegatingViewRoot { } protected String[] getProcessIds() { + if (processIds == null) { + FacesContext context = FacesContext.getCurrentInstance(); + String processIdsParam = (String) context.getExternalContext().getRequestParameterMap().get( + PROCESS_IDS_PARAM); + if (StringUtils.hasText(processIdsParam) && processIdsParam.contains(PROCESS_ALL)) { + processIds = new String[] { getOriginalViewRoot().getClientId(context) }; + } else { + processIds = StringUtils.delimitedListToStringArray(processIdsParam, ",", " "); + processIds = removeNestedChildren(context, processIds); + } + } return processIds; } protected String[] getRenderIds() { + if (renderIds == null) { + FacesContext context = FacesContext.getCurrentInstance(); + + String renderIdsValue = (String) renderIdsExpr.getValue(context); + if (StringUtils.hasText(renderIdsValue)) { + renderIds = StringUtils.delimitedListToStringArray(renderIdsValue, ",", " "); + renderIds = removeNestedChildren(context, getRenderIds()); + } else { + renderIds = getProcessIds(); + } + } return renderIds; } diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java b/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java index 2671c08a..7b1a7d57 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java @@ -1,23 +1,32 @@ package org.springframework.faces.ui; -import javax.faces.component.UICommand; +import java.io.IOException; +import java.io.StringWriter; + import javax.faces.component.UIForm; import javax.faces.component.UIPanel; import javax.faces.component.UIViewRoot; import javax.faces.render.RenderKitFactory; -import org.springframework.faces.webflow.JSFMockHelper; - import junit.framework.TestCase; +import org.apache.shale.test.mock.MockResponseWriter; +import org.springframework.faces.webflow.JSFMockHelper; +import org.springframework.faces.webflow.MockViewHandler; +import org.springframework.util.StringUtils; + public class AjaxViewRootTests extends TestCase { JSFMockHelper jsf = new JSFMockHelper(); UIViewRoot testTree = new UIViewRoot(); + private StringWriter output = new StringWriter(); + protected void setUp() throws Exception { jsf.setUp(); + jsf.facesContext().getApplication().setViewHandler(new MockViewHandler()); + jsf.facesContext().setResponseWriter(new MockResponseWriter(output, null, null)); UIForm form = new UIForm(); form.setId("foo"); @@ -25,7 +34,7 @@ public class AjaxViewRootTests extends TestCase { UIPanel panel = new UIPanel(); panel.setId("bar"); form.getChildren().add(panel); - UICommand command = new UICommand(); + ProgressiveCommandButton command = new ProgressiveCommandButton(); command.setId("baz"); panel.getChildren().add(command); @@ -40,14 +49,37 @@ public class AjaxViewRootTests extends TestCase { public void testProcessDecodes() { jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz"); - jsf.externalContext().getRequestParameterMap().put("renderIds", "foo:bar, foo:baz"); AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree); ajaxRoot.processDecodes(jsf.facesContext()); assertEquals(1, ajaxRoot.getProcessIds().length); - assertEquals(1, ajaxRoot.getRenderIds().length); } + public void testEncodeAll_NoRenderIds() throws IOException { + jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz"); + + AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree); + + ajaxRoot.encodeAll(jsf.facesContext()); + + assertEquals(1, ajaxRoot.getProcessIds().length); + assertEquals(1, ajaxRoot.getRenderIds().length); + assertEquals(StringUtils.arrayToCommaDelimitedString(ajaxRoot.getProcessIds()), StringUtils + .arrayToCommaDelimitedString(ajaxRoot.getRenderIds())); + } + + public void testEncodeAll_RenderIdsExpr() throws IOException { + + jsf.externalContext().getRequestMap().put("renderIds", "foo:bar,foo:baz"); + + AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree); + + ajaxRoot.encodeAll(jsf.facesContext()); + + assertEquals(1, ajaxRoot.getRenderIds().length); + + assertEquals("foo:bar", StringUtils.arrayToCommaDelimitedString(ajaxRoot.getRenderIds())); + } }