From 67782381c8d672f867d42edb4d9b05757d764e23 Mon Sep 17 00:00:00 2001 From: Jeremy Grelle Date: Thu, 5 Jun 2008 16:38:12 +0000 Subject: [PATCH] Tests and fixes for SWF-719 and SWF-723. --- .../faces/webflow/JsfViewFactory.java | 20 ++++-- .../faces/webflow/JsfViewFactoryTests.java | 72 +++++++++++++++++++ 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java index 3fbb00f2..af2b65b1 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java @@ -18,6 +18,7 @@ package org.springframework.faces.webflow; import java.util.Iterator; import javax.faces.application.ViewHandler; +import javax.faces.component.EditableValueHolder; import javax.faces.component.UIComponent; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; @@ -88,7 +89,7 @@ public class JsfViewFactory implements ViewFactory { } UIViewRoot viewRoot = facesContext.getViewRoot(); viewRoot.setLocale(context.getExternalContext().getLocale()); - processComponentBinding(facesContext, viewRoot); + processTree(facesContext, viewRoot); view = createJsfView(facesContext.getViewRoot(), lifecycle, context); view.setRestored(true); } else { @@ -99,7 +100,7 @@ public class JsfViewFactory implements ViewFactory { } view = createJsfView(viewRoot, lifecycle, context); facesContext.setViewRoot(view.getViewRoot()); - processComponentBinding(facesContext, view.getViewRoot()); + processTree(facesContext, view.getViewRoot()); view.setRestored(true); } else { if (logger.isDebugEnabled()) { @@ -164,15 +165,24 @@ public class JsfViewFactory implements ViewFactory { } } - private void processComponentBinding(FacesContext context, UIComponent component) { + /** + * Walk the component tree to perform any required per-component operations. + * + * @param context + * @param component + */ + private void processTree(FacesContext context, UIComponent component) { + if (component instanceof EditableValueHolder) { + ((EditableValueHolder) component).setValid(true); + } ValueBinding binding = component.getValueBinding("binding"); if (binding != null) { binding.setValue(context, component); } - Iterator it = component.getChildren().iterator(); + Iterator it = component.getFacetsAndChildren(); while (it.hasNext()) { UIComponent child = (UIComponent) it.next(); - processComponentBinding(context, child); + processTree(context, child); } } } diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java index 2c988a60..fcc49ec7 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewFactoryTests.java @@ -6,6 +6,9 @@ import java.util.List; import javax.faces.FacesException; import javax.faces.application.ViewHandler; +import javax.faces.component.UIInput; +import javax.faces.component.UIOutput; +import javax.faces.component.UIPanel; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; @@ -121,6 +124,10 @@ public class JsfViewFactoryTests extends TestCase { UIViewRoot existingRoot = new UIViewRoot(); existingRoot.setViewId(VIEW_ID); + UIInput input = new UIInput(); + input.setId("invalidInput"); + input.setValid(false); + existingRoot.getChildren().add(input); ((MockViewHandler) viewHandler).setRestoreView(existingRoot); EasyMock.replay(new Object[] { context }); @@ -131,6 +138,49 @@ public class JsfViewFactoryTests extends TestCase { assertTrue("A JsfView was expected", restoredView instanceof JsfView); assertEquals("View name did not match", VIEW_ID, ((JsfView) restoredView).getViewRoot().getViewId()); assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent()); + assertTrue("The input component's valid flag was not reset", input.isValid()); + } + + /** + * View already exists in flash scope and must be restored and the lifecycle executed, no event signaled + */ + public final void testGetView_RestoreWithBindings() { + + lifecycle = new NoExecutionLifecycle(jsfMock.lifecycle()); + factory = new JsfViewFactory(parser.parseExpression(VIEW_ID, new FluentParserContext().template().evaluate( + RequestContext.class).expectResult(String.class)), lifecycle); + + UIViewRoot existingRoot = new UIViewRoot(); + existingRoot.setViewId(VIEW_ID); + UIPanel panel = new UIPanel(); + panel.setId("panel1"); + UIOutput output = new UIOutput(); + output.setValueBinding("binding", jsfMock.facesContext().getApplication() + .createValueBinding("#{myBean.output}")); + output.setId("output1"); + UIInput input = new UIInput(); + input.setValueBinding("binding", jsfMock.facesContext().getApplication().createValueBinding("#{myBean.input}")); + input.setId("input1"); + + existingRoot.getChildren().add(panel); + panel.getFacets().put("label", output); + panel.getChildren().add(input); + + TestBean testBean = new TestBean(); + jsfMock.externalContext().getRequestMap().put("myBean", testBean); + + ((MockViewHandler) viewHandler).setRestoreView(existingRoot); + + EasyMock.replay(new Object[] { context }); + + View restoredView = factory.getView(context); + + assertNotNull("A View was not restored", restoredView); + assertTrue("A JsfView was expected", restoredView instanceof JsfView); + assertEquals("View name did not match", VIEW_ID, ((JsfView) restoredView).getViewRoot().getViewId()); + assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent()); + assertSame("The UIInput binding was not restored properly", input, testBean.getInput()); + assertSame("The faceted UIOutput binding was not restored properly", output, testBean.getOutput()); } /** @@ -251,4 +301,26 @@ public class JsfViewFactoryTests extends TestCase { throw new UnsupportedOperationException("Auto-generated method stub"); } } + + protected class TestBean { + + UIOutput output; + UIInput input; + + public UIOutput getOutput() { + return output; + } + + public void setOutput(UIOutput output) { + this.output = output; + } + + public UIInput getInput() { + return input; + } + + public void setInput(UIInput input) { + this.input = input; + } + } }