diff --git a/build-spring-webflow/ivysettings.xml b/build-spring-webflow/ivysettings.xml
new file mode 100644
index 00000000..41938115
--- /dev/null
+++ b/build-spring-webflow/ivysettings.xml
@@ -0,0 +1,17 @@
+
+
+ * A subclass of AjaxViewRoot for use with JSF 2.0. + *
+ * + *+ * Note that these methods should ideally be in DelegatingViewRoot.java. However, due to some introspection done by the + * JSF runtime that would make it impossible to use in JSF 1.2 because some of the delegate methods contain JSF 2.0 + * specific types and cause ClassNotFoundExceptions. + *
+ * + * @author Phil Webb + */ +public class AjaxJsf2ViewRoot extends AjaxViewRoot { + + public AjaxJsf2ViewRoot(UIViewRoot original) { + super(original); + if (JsfVersion.isAtLeastJsf20()) { + setId(createUniqueId()); + } + } + + public void addClientBehavior(String eventName, ClientBehavior behavior) { + getOriginalViewRoot().addClientBehavior(eventName, behavior); + } + + public void addComponentResource(FacesContext context, UIComponent componentResource) { + getOriginalViewRoot().addComponentResource(context, componentResource); + } + + public void addComponentResource(FacesContext context, UIComponent componentResource, String target) { + getOriginalViewRoot().addComponentResource(context, componentResource, target); + } + + public void broadcastEvents(FacesContext context, PhaseId phaseId) { + getOriginalViewRoot().broadcastEvents(context, phaseId); + } + + public void clearInitialState() { + getOriginalViewRoot().clearInitialState(); + } + + public String createUniqueId(FacesContext context, String seed) { + return getOriginalViewRoot().createUniqueId(context, seed); + } + + public Map getClientBehaviors() { + return getOriginalViewRoot().getClientBehaviors(); + } + + public String getClientId() { + return getOriginalViewRoot().getClientId(); + } + + public List getComponentResources(FacesContext context, String target) { + return getOriginalViewRoot().getComponentResources(context, target); + } + + public String getDefaultEventName() { + return getOriginalViewRoot().getDefaultEventName(); + } + + public Collection getEventNames() { + return getOriginalViewRoot().getEventNames(); + } + + public List getListenersForEventClass(Class eventClass) { + return getOriginalViewRoot().getListenersForEventClass(eventClass); + } + + public UIComponent getNamingContainer() { + return getOriginalViewRoot().getNamingContainer(); + } + + public List getPhaseListeners() { + return getOriginalViewRoot().getPhaseListeners(); + } + + public Map getResourceBundleMap() { + return getOriginalViewRoot().getResourceBundleMap(); + } + + public List getViewListenersForEventClass(Class systemEvent) { + return getOriginalViewRoot().getViewListenersForEventClass(systemEvent); + } + + public Map getViewMap() { + return getOriginalViewRoot().getViewMap(); + } + + public Map getViewMap(boolean create) { + return getOriginalViewRoot().getViewMap(create); + } + + public boolean initialStateMarked() { + return getOriginalViewRoot().initialStateMarked(); + } + + public void markInitialState() { + getOriginalViewRoot().markInitialState(); + } + + public boolean isInView() { + return getOriginalViewRoot().isInView(); + } + + public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { + getOriginalViewRoot().processEvent(event); + } + + public void removeComponentResource(FacesContext context, UIComponent componentResource) { + getOriginalViewRoot().removeComponentResource(context, componentResource); + } + + public void removeComponentResource(FacesContext context, UIComponent componentResource, String target) { + getOriginalViewRoot().removeComponentResource(context, componentResource, target); + } + + public void setInView(boolean isInView) { + getOriginalViewRoot().setInView(isInView); + } + + public void subscribeToEvent(Class eventClass, ComponentSystemEventListener componentListener) { + getOriginalViewRoot().subscribeToEvent(eventClass, componentListener); + } + + public void subscribeToViewEvent(Class systemEvent, SystemEventListener listener) { + getOriginalViewRoot().subscribeToViewEvent(systemEvent, listener); + } + + public void unsubscribeFromEvent(Class eventClass, ComponentSystemEventListener componentListener) { + getOriginalViewRoot().unsubscribeFromEvent(eventClass, componentListener); + } + + public void unsubscribeFromViewEvent(Class systemEvent, SystemEventListener listener) { + getOriginalViewRoot().unsubscribeFromViewEvent(systemEvent, listener); + } + + public boolean visitTree(VisitContext context, VisitCallback callback) { + return getOriginalViewRoot().visitTree(context, callback); + } + +} diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java b/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java index f339def7..29a197b6 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java @@ -71,7 +71,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot { * @see javax.faces.component.UIViewRoot#createUniqueId() */ public String createUniqueId() { - return original.createUniqueId(); + return (original != null) ? original.createUniqueId() : null; } /** @@ -409,7 +409,10 @@ public abstract class DelegatingViewRoot extends UIViewRoot { * @see javax.faces.component.UIComponentBase#setId(java.lang.String) */ public void setId(String id) { - original.setId(id); + // Test for null to deal with JSF setId on constructor + if (original != null) { + original.setId(id); + } } /** diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java b/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java index e1e202b5..9a18032d 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java @@ -2,7 +2,9 @@ package org.springframework.faces.webflow; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.io.Writer; import java.net.MalformedURLException; import java.net.URL; import java.security.Principal; @@ -12,6 +14,7 @@ import java.util.Map; import java.util.Set; import javax.faces.context.ExternalContext; +import javax.faces.context.Flash; class ExternalContextWrapper extends ExternalContext { @@ -188,4 +191,111 @@ class ExternalContextWrapper extends ExternalContext { public void setResponseCharacterEncoding(String encoding) { delegate.setResponseCharacterEncoding(encoding); } + + // --------------- JSF 2.0 Pass-through delegate methods ------------------// + + public String getContextName() { + return delegate.getContextName(); + } + + public void addResponseCookie(String name, String value, Map properties) { + delegate.addResponseCookie(name, value, properties); + } + + public Flash getFlash() { + return delegate.getFlash(); + } + + public String getMimeType(String file) { + return delegate.getMimeType(file); + } + + public String getRequestScheme() { + return delegate.getRequestScheme(); + } + + public String getRequestServerName() { + return delegate.getRequestServerName(); + } + + public int getRequestServerPort() { + return delegate.getRequestServerPort(); + } + + public String getRealPath(String path) { + return delegate.getRealPath(path); + } + + public int getRequestContentLength() { + return delegate.getRequestContentLength(); + } + + public OutputStream getResponseOutputStream() throws IOException { + return delegate.getResponseOutputStream(); + } + + public Writer getResponseOutputWriter() throws IOException { + return delegate.getResponseOutputWriter(); + } + + public void setResponseContentType(String contentType) { + delegate.setResponseContentType(contentType); + } + + public void invalidateSession() { + delegate.invalidateSession(); + } + + public void setResponseHeader(String name, String value) { + delegate.setResponseHeader(name, value); + } + + public void addResponseHeader(String name, String value) { + delegate.addResponseHeader(name, value); + } + + public void setResponseBufferSize(int size) { + delegate.setResponseBufferSize(size); + } + + public int getResponseBufferSize() { + return delegate.getResponseBufferSize(); + } + + public boolean isResponseCommitted() { + return delegate.isResponseCommitted(); + } + + public void responseReset() { + delegate.responseReset(); + } + + public void responseSendError(int statusCode, String message) throws IOException { + delegate.responseSendError(statusCode, message); + } + + public void setResponseStatus(int statusCode) { + delegate.setResponseStatus(statusCode); + } + + public void responseFlushBuffer() throws IOException { + delegate.responseFlushBuffer(); + } + + public void setResponseContentLength(int length) { + delegate.setResponseContentLength(length); + } + + public String encodeBookmarkableURL(String baseUrl, Map parameters) { + return delegate.encodeBookmarkableURL(baseUrl, parameters); + } + + public String encodeRedirectURL(String baseUrl, Map parameters) { + return delegate.encodeRedirectURL(baseUrl, parameters); + } + + public String encodePartialActionURL(String url) { + return delegate.encodePartialActionURL(url); + } + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java index 073665fc..3d99f735 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java @@ -48,4 +48,8 @@ public class FlowApplicationFactory extends ApplicationFactory { delegate.setApplication(application); } + public ApplicationFactory getWrapped() { + return delegate; + } + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java index 48ec0f87..a0e2f4d3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java @@ -17,17 +17,23 @@ package org.springframework.faces.webflow; import java.lang.reflect.Method; import java.util.Iterator; +import java.util.List; +import java.util.Map; import javax.el.ELContext; import javax.faces.FactoryFinder; import javax.faces.application.Application; import javax.faces.application.FacesMessage; +import javax.faces.application.ProjectStage; import javax.faces.component.UIViewRoot; +import javax.faces.context.ExceptionHandler; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.context.FacesContextFactory; +import javax.faces.context.PartialViewContext; import javax.faces.context.ResponseStream; import javax.faces.context.ResponseWriter; +import javax.faces.event.PhaseId; import javax.faces.lifecycle.Lifecycle; import javax.faces.render.RenderKit; @@ -199,6 +205,64 @@ public class FlowFacesContext extends FacesContext { return delegate; } + // --------------- JSF 2.0 Pass-through delegate methods ------------------// + + public Map getAttributes() { + return delegate.getAttributes(); + } + + public PartialViewContext getPartialViewContext() { + return delegate.getPartialViewContext(); + } + + public List getMessageList() { + return delegate.getMessageList(); + } + + public List getMessageList(String clientId) { + return delegate.getMessageList(clientId); + } + + public boolean isPostback() { + return delegate.isPostback(); + } + + public PhaseId getCurrentPhaseId() { + return delegate.getCurrentPhaseId(); + } + + public void setCurrentPhaseId(PhaseId currentPhaseId) { + delegate.setCurrentPhaseId(currentPhaseId); + } + + public ExceptionHandler getExceptionHandler() { + return delegate.getExceptionHandler(); + } + + public boolean isProcessingEvents() { + return delegate.isProcessingEvents(); + } + + public boolean isProjectStage(ProjectStage stage) { + return delegate.isProjectStage(stage); + } + + public boolean isValidationFailed() { + return delegate.isValidationFailed(); + } + + public void setExceptionHandler(ExceptionHandler exceptionHandler) { + delegate.setExceptionHandler(exceptionHandler); + } + + public void setProcessingEvents(boolean processingEvents) { + delegate.setProcessingEvents(processingEvents); + } + + public void validationFailed() { + delegate.validationFailed(); + } + // ------------------ Private helper methods ----------------------// private class FlowExternalContext extends ExternalContextWrapper { diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java index 39662bbd..bc7b7875 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java @@ -156,6 +156,7 @@ public class FlowViewStateManager extends StateManager { } UIViewRoot viewRoot = restoreTreeStructure(context, viewId, renderKitId); if (viewRoot != null) { + context.setViewRoot(viewRoot); restoreComponentState(context, viewRoot, renderKitId); } return viewRoot; diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java index 0e92ce8d..61bc7e82 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java @@ -21,7 +21,6 @@ import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import javax.faces.lifecycle.Lifecycle; -import org.springframework.util.ReflectionUtils; import org.springframework.webflow.execution.RequestContextHolder; /** @@ -31,18 +30,6 @@ import org.springframework.webflow.execution.RequestContextHolder; */ public class JsfUtils { - private static final boolean JSF_12; - - private static final String JSF_12_METHOD = "getELContext"; - - static { - if (ReflectionUtils.findMethod(FacesContext.class, JSF_12_METHOD) != null) { - JSF_12 = true; - } else { - JSF_12 = false; - } - } - public static void notifyAfterListeners(PhaseId phaseId, Lifecycle lifecycle, FacesContext context) { PhaseEvent afterPhaseEvent = new PhaseEvent(context, phaseId, lifecycle); for (int i = 0; i < lifecycle.getPhaseListeners().length; i++) { @@ -80,7 +67,7 @@ public class JsfUtils { } public static boolean isAtLeastJsf12() { - return JSF_12; + return JsfVersion.isAtLeastJsf12(); } public static boolean isPortlet(FacesContext context) { diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfVersion.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfVersion.java new file mode 100644 index 00000000..85e7c65e --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfVersion.java @@ -0,0 +1,68 @@ +/* + * Copyright 2004-2010 the original author or authors. + * + * 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.springframework.faces.webflow; + +import javax.faces.context.FacesContext; + +import org.springframework.util.ReflectionUtils; + +/** + * Internal helper class to find the version of JSF in use at runtime. + * + * @author Phil Webb + */ +public class JsfVersion { + + /** + * JSF Version 1.1 + */ + public static final int JSF_11 = 0; + + /** + * JSF Version 1.2 + */ + public static final int JSF_12 = 1; + + /** + * JSF Version 2.0 + */ + public static final int JSF_20 = 2; + + private static final int jsfVersion; + + static { + if (ReflectionUtils.findMethod(FacesContext.class, "isPostback") != null) { + jsfVersion = JsfVersion.JSF_20; + } else if (ReflectionUtils.findMethod(FacesContext.class, "getELContext") != null) { + jsfVersion = JsfVersion.JSF_12; + } else { + jsfVersion = JsfVersion.JSF_11; + } + } + + public static int getJsfVersion() { + return jsfVersion; + } + + public static boolean isAtLeastJsf20() { + return jsfVersion >= JSF_20; + } + + public static boolean isAtLeastJsf12() { + return jsfVersion >= JSF_12; + } + +} \ No newline at end of file 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 db663754..44e62be7 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 @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.binding.expression.Expression; +import org.springframework.faces.ui.AjaxJsf2ViewRoot; import org.springframework.faces.ui.AjaxViewRoot; import org.springframework.js.ajax.SpringJavascriptAjaxHandler; import org.springframework.webflow.context.ExternalContext; @@ -136,7 +137,8 @@ public class JsfViewFactory implements ViewFactory { private JsfView createJsfView(UIViewRoot root, Lifecycle lifecycle, RequestContext context) { if (isSpringJavascriptAjaxRequest(context.getExternalContext())) { - return new JsfView(new AjaxViewRoot(root), lifecycle, context); + AjaxViewRoot viewRoot = (JsfVersion.isAtLeastJsf20()) ? new AjaxJsf2ViewRoot(root) : new AjaxViewRoot(root); + return new JsfView(viewRoot, lifecycle, context); } else { return new JsfView(root, lifecycle, context); } diff --git a/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java b/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java index 60e19e5a..07ff011f 100644 --- a/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java @@ -12,14 +12,20 @@ import javax.faces.event.AbortProcessingException; import javax.faces.event.ActionEvent; import javax.faces.event.ActionListener; +import junit.framework.TestCase; + +import org.springframework.faces.webflow.JSFMockHelper; import org.springframework.util.ReflectionUtils; import com.sun.facelets.component.UIRepeat; -import junit.framework.TestCase; - public class SelectionTrackingActionListenerTests extends TestCase { + /** + * JSF Mock Helper + */ + private JSFMockHelper jsfMockHelper = new JSFMockHelper(); + /** * The JSF view to simulate */ @@ -40,7 +46,8 @@ public class SelectionTrackingActionListenerTests extends TestCase { */ private ActionListener selectionTrackingListener = new SelectionTrackingActionListener(delegateListener); - public void setUp() { + public void setUp() throws Exception { + jsfMockHelper.setUp(); viewToTest = new UIViewRoot(); List rows = new ArrayList(); rows.add(new TestRowData()); @@ -49,6 +56,10 @@ public class SelectionTrackingActionListenerTests extends TestCase { dataModel = new OneSelectionTrackingListDataModel(rows); } + protected void tearDown() throws Exception { + jsfMockHelper.tearDown(); + } + public void testProcessActionWithUIData() { UIData dataTable = new UIData(); 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 746d721b..5f709753 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 @@ -10,7 +10,7 @@ import javax.faces.render.RenderKitFactory; import junit.framework.TestCase; -import org.apache.shale.test.mock.MockResponseWriter; +import org.apache.myfaces.test.mock.MockResponseWriter; import org.springframework.faces.webflow.JSFMockHelper; import org.springframework.faces.webflow.MockViewHandler; import org.springframework.util.StringUtils; diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java b/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java index 2954fbac..93e1ec4c 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java @@ -7,7 +7,7 @@ import javax.faces.component.UIParameter; import junit.framework.TestCase; -import org.apache.shale.test.mock.MockResponseWriter; +import org.apache.myfaces.test.mock.MockResponseWriter; import org.springframework.faces.webflow.JSFMockHelper; public class ProgressiveCommandLinkRendererTests extends TestCase { diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java b/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java index bd1ec147..dd49babe 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java @@ -5,7 +5,7 @@ import java.io.StringWriter; import junit.framework.TestCase; -import org.apache.shale.test.mock.MockResponseWriter; +import org.apache.myfaces.test.mock.MockResponseWriter; import org.springframework.faces.webflow.JSFMockHelper; public class FlowResourceHelperTests extends TestCase { diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JSFMockHelper.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JSFMockHelper.java index f510d3fd..548c3868 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/JSFMockHelper.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JSFMockHelper.java @@ -1,30 +1,37 @@ package org.springframework.faces.webflow; +import java.net.URL; +import java.net.URLClassLoader; + import javax.faces.FactoryFinder; import javax.faces.application.Application; +import javax.faces.application.ApplicationFactory; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.context.FacesContextFactory; import javax.faces.lifecycle.LifecycleFactory; import javax.faces.render.RenderKitFactory; -import org.apache.shale.test.base.AbstractJsfTestCase; -import org.apache.shale.test.mock.MockApplication; -import org.apache.shale.test.mock.MockExternalContext; -import org.apache.shale.test.mock.MockHttpServletRequest; -import org.apache.shale.test.mock.MockHttpServletResponse; -import org.apache.shale.test.mock.MockHttpSession; -import org.apache.shale.test.mock.MockLifecycle; -import org.apache.shale.test.mock.MockLifecycleFactory; -import org.apache.shale.test.mock.MockRenderKit; -import org.apache.shale.test.mock.MockServletConfig; -import org.apache.shale.test.mock.MockServletContext; +import org.apache.myfaces.test.base.AbstractJsfTestCase; +import org.apache.myfaces.test.mock.MockApplicationFactory; +import org.apache.myfaces.test.mock.MockExternalContext; +import org.apache.myfaces.test.mock.MockHttpServletRequest; +import org.apache.myfaces.test.mock.MockHttpServletResponse; +import org.apache.myfaces.test.mock.MockHttpSession; +import org.apache.myfaces.test.mock.MockPartialViewContextFactory; +import org.apache.myfaces.test.mock.MockRenderKit; +import org.apache.myfaces.test.mock.MockRenderKitFactory; +import org.apache.myfaces.test.mock.MockServletConfig; +import org.apache.myfaces.test.mock.MockServletContext; +import org.apache.myfaces.test.mock.lifecycle.MockLifecycle; +import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory; /** * Helper for using the mock JSF environment provided by shale-test inside unit tests that do not extend * {@link AbstractJsfTestCase} - * @author Jeremy Grelle * + * @author Jeremy Grelle + * @author Phil Webb */ public class JSFMockHelper { @@ -88,17 +95,21 @@ public class JSFMockHelper { private static class JSFMock extends AbstractJsfTestCase { + private ClassLoader threadContextClassLoader; + public JSFMock() { super("JSFMock"); } - FacesContextFactory facesContextFactory; FacesContext facesContext; + FacesContextFactory facesContextFactory; public void setUp() throws Exception { - // Thread.currentThread().setContextClassLoader( - // new URLClassLoader(new URL[0], this.getClass().getClassLoader())); + // Set up a new thread context class loader + threadContextClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader( + new URLClassLoader(new URL[0], this.getClass().getClassLoader())); // Set up Servlet API Objects servletContext = new MockServletContext(); @@ -110,20 +121,12 @@ public class JSFMockHelper { response = new MockHttpServletResponse(); // Set up JSF API Objects - FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, - "org.apache.shale.test.mock.MockApplicationFactory"); - FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY, - "org.springframework.faces.webflow.MockBaseFacesContextFactory"); - /* - * FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY, - * "org.apache.shale.test.mock.MockFacesContextFactory"); - */ - FactoryFinder - .setFactory(FactoryFinder.LIFECYCLE_FACTORY, "org.apache.shale.test.mock.MockLifecycleFactory"); - FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, - "org.apache.shale.test.mock.MockRenderKitFactory"); - - application = new MockApplication(); + FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName()); + FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY, MockBaseFacesContextFactory.class.getName()); + FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY, MockLifecycleFactory.class.getName()); + FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); + FactoryFinder.setFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY, MockPartialViewContextFactory.class + .getName()); externalContext = new MockExternalContext(servletContext, request, response); lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); lifecycle = (MockLifecycle) lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE); @@ -134,6 +137,9 @@ public class JSFMockHelper { root.setViewId("/viewId"); root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT); facesContext.setViewRoot(root); + ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder + .getFactory(FactoryFinder.APPLICATION_FACTORY); + application = (org.apache.myfaces.test.mock.MockApplication) applicationFactory.getApplication(); RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder .getFactory(FactoryFinder.RENDER_KIT_FACTORY); renderKit = new MockRenderKit(); @@ -157,9 +163,11 @@ public class JSFMockHelper { session = null; FactoryFinder.releaseFactories(); + Thread.currentThread().setContextClassLoader(threadContextClassLoader); + threadContextClassLoader = null; } - public MockApplication application() { + public org.apache.myfaces.test.mock.MockApplication application() { return application; } diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java index bbbd8199..1516b078 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfViewTests.java @@ -14,8 +14,8 @@ import javax.faces.lifecycle.Lifecycle; import junit.framework.TestCase; -import org.apache.shale.test.mock.MockResponseWriter; -import org.apache.shale.test.mock.MockStateManager; +import org.apache.myfaces.test.mock.MockResponseWriter; +import org.apache.myfaces.test.mock.MockStateManager; import org.easymock.EasyMock; import org.springframework.faces.ui.AjaxViewRoot; import org.springframework.webflow.core.collection.MutableAttributeMap; @@ -130,7 +130,7 @@ public class JsfViewTests extends TestCase { try { view.render(); - } catch (FacesException ex) { + } catch (Exception ex) { assertNull("The FacesContext was not released", FacesContext.getCurrentInstance()); } } diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContext.java b/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContext.java index 23c76725..7b4fbe08 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContext.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContext.java @@ -1,14 +1,16 @@ package org.springframework.faces.webflow; +import java.util.Map; + import javax.faces.FactoryFinder; import javax.faces.application.Application; import javax.faces.application.ApplicationFactory; import javax.faces.context.ExternalContext; import javax.faces.lifecycle.Lifecycle; -import org.apache.shale.test.mock.MockFacesContext12; +import org.apache.myfaces.test.mock.MockFacesContext20; -public class MockBaseFacesContext extends MockFacesContext12 { +public class MockBaseFacesContext extends MockFacesContext20 { private Application application; @@ -24,6 +26,10 @@ public class MockBaseFacesContext extends MockFacesContext12 { super(externalContext, lifecycle); } + public Map getAttributes() { + return super.getAttributes(); + } + public Application getApplication() { if (application == null) { ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContextFactory.java b/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContextFactory.java index 6c2e5e82..b832ee58 100644 --- a/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContextFactory.java +++ b/spring-faces/src/test/java/org/springframework/faces/webflow/MockBaseFacesContextFactory.java @@ -9,7 +9,7 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.shale.test.mock.MockExternalContext; +import org.apache.myfaces.test.mock.MockExternalContext; public class MockBaseFacesContextFactory extends FacesContextFactory { diff --git a/spring-faces/template.mf b/spring-faces/template.mf index 25f50c68..76ac0df9 100644 --- a/spring-faces/template.mf +++ b/spring-faces/template.mf @@ -13,7 +13,7 @@ Import-Template: javax.el;version="[1.0.0, 2.0.0)", javax.servlet;version="[2.4.0, 3.0.0)", javax.servlet.http;version="[2.4.0, 3.0.0)", - javax.faces.*;version="[1.2.0, 2.0.0)", + javax.faces.*;version="[1.2.0, 3.0.0)", org.ajax4jsf.*;version="[1.1.1, 2.0.0)";resolution:=optional, com.sun.facelets.*;version="[1.1.0, 2.0.0)";resolution:=optional, org.w3c.dom;version="0" diff --git a/spring-webflow-samples/booking-faces/build.xml b/spring-webflow-samples/booking-faces/build.xml index 89925390..f1d81986 100755 --- a/spring-webflow-samples/booking-faces/build.xml +++ b/spring-webflow-samples/booking-faces/build.xml @@ -4,10 +4,12 @@