From 7acf169250b921a3272dbbe1699d0ae8faa1085a Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Fri, 25 Apr 2008 00:54:49 +0000 Subject: [PATCH] addressed cyclical dependency with view package --- ...owBuilderServicesBeanDefinitionParser.java | 2 +- .../engine/builder/ViewFactoryCreator.java | 6 +- .../builder/model/FlowModelFlowBuilder.java | 2 +- .../builder/DelegatingFlowViewResolver.java | 59 +++++ .../InternalResourceFlowViewResolver.java} | 53 +---- .../webflow/mvc/builder/MvcEnvironment.java | 41 ++++ .../mvc/builder/MvcViewFactoryCreator.java | 118 ++++++++++ .../webflow/mvc/portlet/PortletMvcView.java | 7 +- .../mvc/portlet/PortletMvcViewFactory.java | 46 ++++ .../webflow/mvc/servlet/ServletMvcView.java | 6 +- .../mvc/servlet/ServletMvcViewFactory.java | 46 ++++ .../{MvcView.java => AbstractMvcView.java} | 4 +- .../mvc/view/AbstractMvcViewFactory.java | 64 +++++ .../webflow/mvc/view/BindingModel.java | 4 +- .../webflow/mvc/view/FlowViewResolver.java | 30 +++ .../mvc/view/MvcViewFactoryCreator.java | 68 ------ .../mvc/view/ViewResolvingMvcViewFactory.java | 85 ------- .../webflow/test/MockViewFactoryCreator.java | 2 +- ...lderServicesBeanDefinitionParserTests.java | 4 +- .../mvc/portlet/PortletMvcViewTests.java | 4 +- .../mvc/servlet/ServletMvcViewTests.java | 4 +- .../webflow/mvc/view/MvcViewFactoryTests.java | 221 ------------------ .../webflow/mvc/view/MvcViewTests.java | 12 +- 23 files changed, 443 insertions(+), 445 deletions(-) create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/DelegatingFlowViewResolver.java rename spring-webflow/src/main/java/org/springframework/webflow/mvc/{view/InternalFlowResourceMvcViewFactory.java => builder/InternalResourceFlowViewResolver.java} (56%) create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcEnvironment.java create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcViewFactory.java create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcViewFactory.java rename spring-webflow/src/main/java/org/springframework/webflow/mvc/view/{MvcView.java => AbstractMvcView.java} (99%) create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java create mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/view/FlowViewResolver.java delete mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcViewFactoryCreator.java delete mode 100644 spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java delete mode 100644 spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java index 7509910a..e65a0440 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java @@ -26,7 +26,7 @@ import org.springframework.binding.format.registry.DefaultFormatterRegistry; import org.springframework.util.StringUtils; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import org.springframework.webflow.expression.DefaultExpressionParserFactory; -import org.springframework.webflow.mvc.view.MvcViewFactoryCreator; +import org.springframework.webflow.mvc.builder.MvcViewFactoryCreator; import org.w3c.dom.Element; /** diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java index 6772440d..033690cc 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java @@ -30,12 +30,12 @@ public interface ViewFactoryCreator { /** * Create a view factory capable of creating {@link View} objects that can render the view template with the * provided identifier. - * @param viewIdExpression an expression that resolves the id of the view template + * @param viewName an expression that resolves the name of the view template * @param expressionParser an optional expression parser to use to resolve view expressions * @param formatterRegistry an optional formatter registry to use to format text values * @return the view factory */ - public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser, + public ViewFactory createViewFactory(Expression viewName, ExpressionParser expressionParser, FormatterRegistry formatterRegistry); /** @@ -43,5 +43,5 @@ public interface ViewFactoryCreator { * @param viewStateId the view state id * @return the default view id */ - public String getViewIdByConvention(String viewStateId); + public String getViewNameByConvention(String viewStateId); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java index 0810b53e..a39b1bbd 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java @@ -588,7 +588,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { if (endState) { return null; } else { - view = getLocalContext().getViewFactoryCreator().getViewIdByConvention(stateId); + view = getLocalContext().getViewFactoryCreator().getViewNameByConvention(stateId); Expression viewId = getLocalContext().getExpressionParser().parseExpression(view, new FluentParserContext().template().evaluate(RequestContext.class).expectResult(String.class)); return createViewFactory(viewId); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/DelegatingFlowViewResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/DelegatingFlowViewResolver.java new file mode 100644 index 00000000..5d996462 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/DelegatingFlowViewResolver.java @@ -0,0 +1,59 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.builder; + +import java.util.Iterator; +import java.util.List; + +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.mvc.view.FlowViewResolver; + +/** + * View factory implementation that delegates to the Spring-configured view resolver chain to resolve the Spring MVC + * view implementation to render. + * + * @author Keith Donald + */ +public class DelegatingFlowViewResolver implements FlowViewResolver { + + private List viewResolvers; + + /** + * Creates a new flow view resolver that delegates to + * @param viewResolvers + */ + public DelegatingFlowViewResolver(List viewResolvers) { + this.viewResolvers = viewResolvers; + } + + public View resolveView(String viewName, RequestContext context) { + for (Iterator it = viewResolvers.iterator(); it.hasNext();) { + ViewResolver viewResolver = (ViewResolver) it.next(); + try { + View view = viewResolver.resolveViewName(viewName, context.getExternalContext().getLocale()); + if (view != null) { + return view; + } + } catch (Exception e) { + throw new IllegalStateException("Exception resolving view with name '" + viewName + "'", e); + } + } + return null; + } + +} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/InternalResourceFlowViewResolver.java similarity index 56% rename from spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java rename to spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/InternalResourceFlowViewResolver.java index 4596d610..8e539470 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/InternalResourceFlowViewResolver.java @@ -13,56 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.webflow.mvc.view; +package org.springframework.webflow.mvc.builder; -import org.springframework.binding.expression.Expression; -import org.springframework.binding.expression.ExpressionParser; -import org.springframework.binding.format.FormatterRegistry; import org.springframework.context.ApplicationContext; import org.springframework.core.io.ContextResource; import org.springframework.core.io.Resource; import org.springframework.util.ClassUtils; +import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.InternalResourceView; import org.springframework.web.servlet.view.JstlView; -import org.springframework.webflow.context.portlet.PortletExternalContext; import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.execution.View; -import org.springframework.webflow.execution.ViewFactory; -import org.springframework.webflow.mvc.portlet.PortletMvcView; -import org.springframework.webflow.mvc.servlet.ServletMvcView; +import org.springframework.webflow.mvc.view.FlowViewResolver; /** * View factory implementation that creates a Spring-MVC Internal Resource view to render a flow-relative view resource * such as a JSP or Velocity template. * @author Keith Donald */ -class InternalFlowResourceMvcViewFactory implements ViewFactory { +public class InternalResourceFlowViewResolver implements FlowViewResolver { private static final boolean JSTL_PRESENT = ClassUtils.isPresent("javax.servlet.jsp.jstl.fmt.LocalizationContext"); - private Expression viewIdExpression; - - private ExpressionParser expressionParser; - - private FormatterRegistry formatterRegistry; - - public InternalFlowResourceMvcViewFactory(Expression viewIdExpression, ExpressionParser expressionParser, - FormatterRegistry formatterRegistry) { - this.viewIdExpression = viewIdExpression; - this.expressionParser = expressionParser; - this.formatterRegistry = formatterRegistry; - } - - public View getView(RequestContext context) { - String viewId = (String) viewIdExpression.getValue(context); - if (viewId.startsWith("/")) { - return getViewInternal(viewId, context, context.getActiveFlow().getApplicationContext()); + public View resolveView(String viewName, RequestContext context) { + if (viewName.startsWith("/")) { + return getViewInternal(viewName, context, context.getActiveFlow().getApplicationContext()); } else { ApplicationContext flowContext = context.getActiveFlow().getApplicationContext(); if (flowContext == null) { throw new IllegalStateException("A Flow ApplicationContext is required to resolve Flow View Resources"); } - Resource viewResource = flowContext.getResource(viewId); + Resource viewResource = flowContext.getResource(viewName); if (!(viewResource instanceof ContextResource)) { throw new IllegalStateException( "A ContextResource is required to get relative view paths within this context"); @@ -76,27 +56,14 @@ class InternalFlowResourceMvcViewFactory implements ViewFactory { if (JSTL_PRESENT) { JstlView view = new JstlView(viewPath); view.setApplicationContext(flowContext); - return createMvcView(view, context); + return view; } else { InternalResourceView view = new InternalResourceView(viewPath); view.setApplicationContext(flowContext); - return createMvcView(view, context); + return view; } } else { throw new IllegalArgumentException("Unsupported view type " + viewPath + " only types supported are [.jsp]"); } } - - private MvcView createMvcView(org.springframework.web.servlet.View view, RequestContext context) { - MvcView mvcView; - if (context.getExternalContext() instanceof PortletExternalContext) { - mvcView = new PortletMvcView(view, context); - } else { - mvcView = new ServletMvcView(view, context); - } - mvcView.setExpressionParser(expressionParser); - mvcView.setFormatterRegistry(formatterRegistry); - return mvcView; - } - } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcEnvironment.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcEnvironment.java new file mode 100644 index 00000000..a691a707 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcEnvironment.java @@ -0,0 +1,41 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.builder; + +import org.springframework.core.enums.StaticLabeledEnum; + +/** + * Supported Spring Web MVC environments. + * + * @author Keith Donald + */ +public class MvcEnvironment extends StaticLabeledEnum { + + /** + * Servlet MVC. + */ + public static final MvcEnvironment SERVLET = new MvcEnvironment(0, "servlet"); + + /** + * Portlet MVC. + */ + public static final MvcEnvironment PORTLET = new MvcEnvironment(0, "portlet"); + + private MvcEnvironment(int code, String label) { + super(code, label); + } + +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java new file mode 100644 index 00000000..63fd60e9 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java @@ -0,0 +1,118 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.builder; + +import java.util.List; + +import org.springframework.binding.expression.Expression; +import org.springframework.binding.expression.ExpressionParser; +import org.springframework.binding.format.FormatterRegistry; +import org.springframework.web.servlet.View; +import org.springframework.webflow.engine.builder.ViewFactoryCreator; +import org.springframework.webflow.execution.ViewFactory; +import org.springframework.webflow.mvc.portlet.PortletMvcViewFactory; +import org.springframework.webflow.mvc.servlet.ServletMvcViewFactory; +import org.springframework.webflow.mvc.view.FlowViewResolver; + +/** + * View factory creator implementation that produces View Factories that create native Spring MVC-based views. + * + * This class is used by a flow builder in a Spring MVC environment to configure view factories on flows that render + * Spring MVC-based views. + * + * This class supports rendering views resolved by existing Spring MVC-based resolver infrastructure, or, if no such + * infrastructure is configured, JSP resources relative to the flow definition being built. + * + * @author Keith Donald + * @author Scott Andrews + */ +public class MvcViewFactoryCreator implements ViewFactoryCreator { + + private MvcEnvironment environment; + + private String defaultViewSuffix = ".jsp"; + + private FlowViewResolver flowViewResolver = new InternalResourceFlowViewResolver(); + + /** + * Returns the configured mvc environment. + * @return the mvc environment + */ + public MvcEnvironment getEnvironment() { + return environment; + } + + /** + * Sets the configured mvc environment. + * @param environment the mvc environment. + */ + public void setEnvironment(MvcEnvironment environment) { + this.environment = environment; + } + + /** + * Returns the default view suffix when selecting views by convention. Default is .jsp. + * @return the default view suffix + */ + public String getDefaultViewSuffix() { + return defaultViewSuffix; + } + + /** + * Sets the default suffix for view names when selecting views by convention. Default is .jsp. + * @param defaultViewSuffix the default view suffix + */ + public void setDefaultViewSuffix(String defaultViewSuffix) { + this.defaultViewSuffix = defaultViewSuffix; + } + + /** + * Sets the view resolvers that will be used to resolve views selected by flows. If multiple resolvers are to be + * used, the resolvers should be ordered in the manner they should be applied. + * @param viewResolvers the view resolver list + */ + public void setViewResolvers(List viewResolvers) { + this.flowViewResolver = new DelegatingFlowViewResolver(viewResolvers); + } + + /** + * Set to fully customize how the flow system resolves Spring MVC {@link View} objects. + * @param flowViewResolver the flow view resolver + */ + public void setFlowViewResolver(FlowViewResolver flowViewResolver) { + this.flowViewResolver = flowViewResolver; + } + + public ViewFactory createViewFactory(Expression viewName, ExpressionParser expressionParser, + FormatterRegistry formatterRegistry) { + if (environment == null || environment == MvcEnvironment.SERVLET) { + return new ServletMvcViewFactory(viewName, flowViewResolver, expressionParser, formatterRegistry); + } else if (environment == MvcEnvironment.PORTLET) { + return new PortletMvcViewFactory(viewName, flowViewResolver, expressionParser, formatterRegistry); + } else { + throw new IllegalStateException("Environment not supported " + environment); + } + } + + public String getViewNameByConvention(String viewStateId) { + if (flowViewResolver instanceof DelegatingFlowViewResolver) { + return viewStateId; + } else { + return viewStateId + defaultViewSuffix; + } + } + +} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java index bb6f3acf..12cb0309 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java @@ -26,14 +26,15 @@ import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewRendererServlet; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.mvc.view.MvcView; +import org.springframework.webflow.mvc.view.AbstractMvcView; /** * Spring Web Portlet MVC view implementation. + * * @author Keith Donald * @author Scott Andrews */ -public class PortletMvcView extends MvcView { +public class PortletMvcView extends AbstractMvcView { /** * Creates a new portlet view. @@ -44,7 +45,7 @@ public class PortletMvcView extends MvcView { super(view, context); } - public void doRender(Map model) throws Exception { + protected void doRender(Map model) throws Exception { RequestContext context = getRequestContext(); ExternalContext externalContext = context.getExternalContext(); View view = getView(); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcViewFactory.java new file mode 100644 index 00000000..16eedb40 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcViewFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.portlet; + +import org.springframework.binding.expression.Expression; +import org.springframework.binding.expression.ExpressionParser; +import org.springframework.binding.format.FormatterRegistry; +import org.springframework.web.servlet.View; +import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.mvc.view.AbstractMvcView; +import org.springframework.webflow.mvc.view.AbstractMvcViewFactory; +import org.springframework.webflow.mvc.view.FlowViewResolver; + +/** + * Creates Portlet MVC views. + * + * @author Keith Donald + */ +public class PortletMvcViewFactory extends AbstractMvcViewFactory { + + public PortletMvcViewFactory(Expression viewName, FlowViewResolver viewResolver, ExpressionParser expressionParser, + FormatterRegistry formatterRegistry) { + super(viewName, viewResolver, expressionParser, formatterRegistry); + } + + protected AbstractMvcView createMvcView(View view, RequestContext context) { + PortletMvcView mvcView = new PortletMvcView(view, context); + mvcView.setExpressionParser(getExpressionParser()); + mvcView.setFormatterRegistry(getFormatterRegistry()); + return mvcView; + } + +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java index ba3cd1d2..092df049 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java @@ -22,13 +22,13 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.mvc.view.MvcView; +import org.springframework.webflow.mvc.view.AbstractMvcView; /** * Creates a new Spring Web Servlet MVC view. * @author Keith Donald */ -public class ServletMvcView extends MvcView { +public class ServletMvcView extends AbstractMvcView { /** * Creates a new servlet view. @@ -39,7 +39,7 @@ public class ServletMvcView extends MvcView { super(view, context); } - public void doRender(Map model) throws Exception { + protected void doRender(Map model) throws Exception { RequestContext context = getRequestContext(); ExternalContext externalContext = context.getExternalContext(); HttpServletRequest request = (HttpServletRequest) externalContext.getNativeRequest(); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcViewFactory.java new file mode 100644 index 00000000..cabbac54 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcViewFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.servlet; + +import org.springframework.binding.expression.Expression; +import org.springframework.binding.expression.ExpressionParser; +import org.springframework.binding.format.FormatterRegistry; +import org.springframework.web.servlet.View; +import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.mvc.view.AbstractMvcView; +import org.springframework.webflow.mvc.view.AbstractMvcViewFactory; +import org.springframework.webflow.mvc.view.FlowViewResolver; + +/** + * Creates Servlet MVC views. + * + * @author Keith Donald + */ +public class ServletMvcViewFactory extends AbstractMvcViewFactory { + + public ServletMvcViewFactory(Expression viewName, FlowViewResolver viewResolver, ExpressionParser expressionParser, + FormatterRegistry formatterRegistry) { + super(viewName, viewResolver, expressionParser, formatterRegistry); + } + + protected AbstractMvcView createMvcView(View view, RequestContext context) { + ServletMvcView mvcView = new ServletMvcView(view, context); + mvcView.setExpressionParser(getExpressionParser()); + mvcView.setFormatterRegistry(getFormatterRegistry()); + return mvcView; + } + +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java similarity index 99% rename from spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java rename to spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java index 924a61a5..eac9d49b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java @@ -58,7 +58,7 @@ import org.springframework.webflow.expression.DefaultExpressionParserFactory; * * @author Keith Donald */ -public abstract class MvcView implements View { +public abstract class AbstractMvcView implements View { private static final MappingResultsCriteria PROPERTY_NOT_FOUND_ERROR = new PropertyNotFoundError(); @@ -83,7 +83,7 @@ public abstract class MvcView implements View { * @param view the Spring MVC view to render * @param requestContext the current flow request context */ - public MvcView(org.springframework.web.servlet.View view, RequestContext requestContext) { + public AbstractMvcView(org.springframework.web.servlet.View view, RequestContext requestContext) { this.view = view; this.requestContext = requestContext; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java new file mode 100644 index 00000000..6ddb7926 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java @@ -0,0 +1,64 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.view; + +import org.springframework.binding.expression.Expression; +import org.springframework.binding.expression.ExpressionParser; +import org.springframework.binding.format.FormatterRegistry; +import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.execution.View; +import org.springframework.webflow.execution.ViewFactory; + +/** + * Base class for mvc view factories. + * + * @author Keith Donald + */ +public abstract class AbstractMvcViewFactory implements ViewFactory { + + private Expression viewName; + + private FlowViewResolver viewResolver; + + private ExpressionParser expressionParser; + + private FormatterRegistry formatterRegistry; + + public AbstractMvcViewFactory(Expression viewName, FlowViewResolver viewResolver, + ExpressionParser expressionParser, FormatterRegistry formatterRegistry) { + this.viewName = viewName; + this.viewResolver = viewResolver; + this.expressionParser = expressionParser; + this.formatterRegistry = formatterRegistry; + } + + protected ExpressionParser getExpressionParser() { + return expressionParser; + } + + protected FormatterRegistry getFormatterRegistry() { + return formatterRegistry; + } + + public View getView(RequestContext context) { + String viewName = (String) this.viewName.getValue(context); + org.springframework.web.servlet.View view = viewResolver.resolveView(viewName, context); + return createMvcView(view, context); + } + + protected abstract AbstractMvcView createMvcView(org.springframework.web.servlet.View view, RequestContext context); + +} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java index cee167e8..7ab9da71 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java @@ -43,7 +43,7 @@ import org.springframework.validation.ObjectError; * * This class is a Spring Errors adapter, basically, for use with spring form and bind tags. * - * @see MvcView + * @see AbstractMvcView * * @author Keith Donald */ @@ -82,7 +82,7 @@ public class BindingModel extends AbstractErrors { /** * Sets the results of a data mapping attempt onto the bound model object from the view. - * @see MvcView#processUserEvent() + * @see AbstractMvcView#processUserEvent() * @param results */ public void setMappingResults(MappingResults results) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/FlowViewResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/FlowViewResolver.java new file mode 100644 index 00000000..f4499cb0 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/FlowViewResolver.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004-2008 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.webflow.mvc.view; + +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.webflow.execution.RequestContext; + +/** + * A Web Flow version of the View Resolver interface. Used to resolve a MVC view from flow state. + * + * @author Keith Donald + * @see ViewResolver + */ +public interface FlowViewResolver { + public View resolveView(String viewName, RequestContext context); +} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcViewFactoryCreator.java deleted file mode 100644 index 034a2bca..00000000 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcViewFactoryCreator.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2004-2008 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.webflow.mvc.view; - -import java.util.List; - -import org.springframework.binding.expression.Expression; -import org.springframework.binding.expression.ExpressionParser; -import org.springframework.binding.format.FormatterRegistry; -import org.springframework.webflow.engine.builder.ViewFactoryCreator; -import org.springframework.webflow.execution.ViewFactory; - -/** - * View factory creator implementation that produces View Factories that create native Spring MVC-based views. - * - * This class is used by a flow builder in a Spring MVC environment to configure view factories on flows that render - * Spring MVC-based views. - * - * This class supports rendering views resolved by existing Spring MVC-based resolver infrastructure, or, if no such - * infrastructure is configured, JSP resources relative to the flow definition being built. - * - * @author Keith Donald - * @author Scott Andrews - */ -public class MvcViewFactoryCreator implements ViewFactoryCreator { - - private List viewResolvers; - - /** - * Sets the view resolvers that will be used to resolve views selected by flows. If multiple resolvers are to be - * used, the resolvers should be ordered in the manner they should be applied. - * @param viewResolvers the view resolver list - */ - public void setViewResolvers(List viewResolvers) { - this.viewResolvers = viewResolvers; - } - - public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser, - FormatterRegistry formatterRegistry) { - if (viewResolvers != null) { - return new ViewResolvingMvcViewFactory(viewIdExpression, expressionParser, formatterRegistry, viewResolvers); - } else { - return new InternalFlowResourceMvcViewFactory(viewIdExpression, expressionParser, formatterRegistry); - } - } - - public String getViewIdByConvention(String viewStateId) { - if (viewResolvers != null) { - return viewStateId; - } else { - return viewStateId + ".jsp"; - } - } - -} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java deleted file mode 100644 index 938cebf1..00000000 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004-2008 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.webflow.mvc.view; - -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.springframework.binding.expression.Expression; -import org.springframework.binding.expression.ExpressionParser; -import org.springframework.binding.format.FormatterRegistry; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.webflow.context.portlet.PortletExternalContext; -import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.execution.View; -import org.springframework.webflow.execution.ViewFactory; -import org.springframework.webflow.mvc.portlet.PortletMvcView; -import org.springframework.webflow.mvc.servlet.ServletMvcView; - -/** - * View factory implementation that delegates to the Spring-configured view resolver chain to resolve the Spring MVC - * view implementation to render. - * @author Keith Donald - */ -class ViewResolvingMvcViewFactory implements ViewFactory { - - private Expression viewIdExpression; - - private ExpressionParser expressionParser; - - private FormatterRegistry formatterRegistry; - - private List viewResolvers; - - public ViewResolvingMvcViewFactory(Expression viewIdExpression, ExpressionParser expressionParser, - FormatterRegistry formatterRegistry, List viewResolvers) { - this.viewIdExpression = viewIdExpression; - this.expressionParser = expressionParser; - this.formatterRegistry = formatterRegistry; - this.viewResolvers = viewResolvers; - } - - public View getView(RequestContext context) { - String viewName = (String) viewIdExpression.getValue(context); - MvcView view; - if (context.getExternalContext() instanceof PortletExternalContext) { - view = new PortletMvcView(resolveView(viewName), context); - } else { - view = new ServletMvcView(resolveView(viewName), context); - } - view.setExpressionParser(expressionParser); - view.setFormatterRegistry(formatterRegistry); - return view; - } - - protected org.springframework.web.servlet.View resolveView(String viewName) { - for (Iterator it = viewResolvers.iterator(); it.hasNext();) { - ViewResolver viewResolver = (ViewResolver) it.next(); - try { - Locale locale = LocaleContextHolder.getLocale(); - org.springframework.web.servlet.View view = viewResolver.resolveViewName(viewName, locale); - if (view != null) { - return view; - } - } catch (Exception e) { - throw new IllegalStateException("Exception resolving view with name '" + viewName + "'", e); - } - } - return null; - } -} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java index 8178cab1..23b7236f 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java @@ -39,7 +39,7 @@ class MockViewFactoryCreator implements ViewFactoryCreator { return new MockViewFactory(viewIdExpression); } - public String getViewIdByConvention(String viewStateId) { + public String getViewNameByConvention(String viewStateId) { return viewStateId; } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java index 10abf23e..b12f60bf 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java @@ -14,7 +14,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.webflow.engine.builder.ViewFactoryCreator; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import org.springframework.webflow.execution.ViewFactory; -import org.springframework.webflow.mvc.view.MvcViewFactoryCreator; +import org.springframework.webflow.mvc.builder.MvcViewFactoryCreator; public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase { @@ -49,7 +49,7 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase { throw new UnsupportedOperationException("Auto-generated method stub"); } - public String getViewIdByConvention(String viewStateId) { + public String getViewNameByConvention(String viewStateId) { return viewStateId; } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java index a608d87d..b64cfccc 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java @@ -15,7 +15,7 @@ import org.springframework.mock.web.portlet.MockPortletContext; import org.springframework.mock.web.portlet.MockRenderRequest; import org.springframework.mock.web.portlet.MockRenderResponse; import org.springframework.web.servlet.ViewRendererServlet; -import org.springframework.webflow.mvc.view.MvcView; +import org.springframework.webflow.mvc.view.AbstractMvcView; import org.springframework.webflow.test.MockFlowExecutionKey; import org.springframework.webflow.test.MockRequestContext; @@ -39,7 +39,7 @@ public class PortletMvcViewTests extends TestCase { context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = (org.springframework.web.servlet.View) EasyMock .createMock(org.springframework.web.servlet.View.class); - MvcView view = new PortletMvcView(mvcView, context); + AbstractMvcView view = new PortletMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.render(); assertNotNull(request.getAttribute(ViewRendererServlet.VIEW_ATTRIBUTE)); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/ServletMvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/ServletMvcViewTests.java index cfc63abc..b5e22ed2 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/ServletMvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/ServletMvcViewTests.java @@ -19,7 +19,7 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.View; import org.springframework.webflow.mvc.servlet.ServletMvcView; -import org.springframework.webflow.mvc.view.MvcView; +import org.springframework.webflow.mvc.view.AbstractMvcView; import org.springframework.webflow.test.MockFlowExecutionKey; import org.springframework.webflow.test.MockRequestContext; @@ -50,7 +50,7 @@ public class ServletMvcViewTests extends TestCase { context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); - MvcView view = new ServletMvcView(mvcView, context); + AbstractMvcView view = new ServletMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.render(); assertTrue(renderCalled); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java deleted file mode 100644 index 63e6a88a..00000000 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java +++ /dev/null @@ -1,221 +0,0 @@ -package org.springframework.webflow.mvc.view; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.Locale; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import junit.framework.TestCase; - -import org.springframework.binding.expression.Expression; -import org.springframework.binding.expression.support.StaticExpression; -import org.springframework.context.support.StaticApplicationContext; -import org.springframework.core.io.AbstractResource; -import org.springframework.core.io.ContextResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.util.ClassUtils; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.webflow.execution.Event; -import org.springframework.webflow.execution.View; -import org.springframework.webflow.execution.ViewFactory; -import org.springframework.webflow.test.GeneratedFlowExecutionKey; -import org.springframework.webflow.test.MockExternalContext; -import org.springframework.webflow.test.MockRequestContext; - -public class MvcViewFactoryTests extends TestCase { - private MvcViewFactoryCreator creator; - private StaticApplicationContext applicationContext; - - protected void setUp() { - creator = new MvcViewFactoryCreator(); - applicationContext = new StaticApplicationContext(); - applicationContext.refresh(); - } - - public void testGetViewNoFlowApplicationContext() { - Expression viewId = new StaticExpression("flowrelativeview.jsp"); - InternalFlowResourceMvcViewFactory factory = new InternalFlowResourceMvcViewFactory(viewId, null, null); - MockRequestContext context = new MockRequestContext(); - try { - factory.getView(context); - fail("Expected illegal state"); - } catch (IllegalStateException e) { - // expected; - } - } - - public void testGetViewNoFlowApplicationContextAbsolutePath() { - Expression viewId = new StaticExpression("/absoluteview.jsp"); - InternalFlowResourceMvcViewFactory factory = new InternalFlowResourceMvcViewFactory(viewId, null, null); - MockRequestContext context = new MockRequestContext(); - assertNotNull(factory.getView(context)); - } - - public void testNoResolversGetResource() throws Exception { - ResourceLoader viewResourceLoader = new ResourceLoader() { - public ClassLoader getClassLoader() { - return ClassUtils.getDefaultClassLoader(); - } - - public Resource getResource(String name) { - return new TestContextResource("/parent/" + name); - } - }; - applicationContext.setResourceLoader(viewResourceLoader); - Expression viewId = new StaticExpression("myview.jsp"); - ViewFactory viewFactory = creator.createViewFactory(viewId, null, null); - MockRequestContext context = new MockRequestContext(); - context.getRootFlow().setApplicationContext(applicationContext); - MockExternalContext externalContext = new MockExternalContext(); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - externalContext.setNativeRequest(request); - externalContext.setNativeResponse(response); - context.setExternalContext(externalContext); - context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); - View view = viewFactory.getView(context); - assertEquals(false, view.hasFlowEvent()); - view.render(); - assertEquals("/parent/myview.jsp", response.getForwardedUrl()); - } - - public void testViewResolversGetResource() throws Exception { - MockViewResolver viewResolver = new MockViewResolver("myview"); - creator.setViewResolvers(Collections.singletonList(viewResolver)); - Expression viewId = new StaticExpression("myview"); - ViewFactory viewFactory = creator.createViewFactory(viewId, null, null); - MockRequestContext context = new MockRequestContext(); - MockExternalContext externalContext = new MockExternalContext(); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - externalContext.setNativeRequest(request); - externalContext.setNativeResponse(response); - context.setExternalContext(externalContext); - context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); - View view = viewFactory.getView(context); - assertEquals(false, view.hasFlowEvent()); - view.render(); - assertEquals("myview", response.getForwardedUrl()); - } - - public void testRestoreView() throws Exception { - ResourceLoader viewResourceLoader = new ResourceLoader() { - public ClassLoader getClassLoader() { - return ClassUtils.getDefaultClassLoader(); - } - - public Resource getResource(String name) { - return new TestContextResource("/parent/" + name); - } - }; - applicationContext.setResourceLoader(viewResourceLoader); - Expression viewId = new StaticExpression("myview.jsp"); - ViewFactory viewFactory = creator.createViewFactory(viewId, null, null); - MockRequestContext context = new MockRequestContext(); - context.getRootFlow().setApplicationContext(applicationContext); - MockExternalContext externalContext = new MockExternalContext(); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - externalContext.putRequestParameter("_eventId", "foo"); - externalContext.setNativeRequest(request); - externalContext.setNativeResponse(response); - context.setExternalContext(externalContext); - context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); - View view = viewFactory.getView(context); - view.processUserEvent(); - assertEquals(true, view.hasFlowEvent()); - Event e = view.getFlowEvent(); - assertEquals(view, e.getSource()); - assertEquals("foo", e.getId()); - view.render(); - assertEquals("/parent/myview.jsp", response.getForwardedUrl()); - } - - public void testRestoreViewButtonEventIdFormat() throws Exception { - ResourceLoader viewResourceLoader = new ResourceLoader() { - public ClassLoader getClassLoader() { - return ClassUtils.getDefaultClassLoader(); - } - - public Resource getResource(String name) { - return new TestContextResource("/parent/" + name); - } - }; - applicationContext.setResourceLoader(viewResourceLoader); - Expression viewId = new StaticExpression("myview.jsp"); - ViewFactory viewFactory = creator.createViewFactory(viewId, null, null); - MockRequestContext context = new MockRequestContext(); - context.getRootFlow().setApplicationContext(applicationContext); - MockExternalContext externalContext = new MockExternalContext(); - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - externalContext.putRequestParameter("_eventId_foo", "true"); - externalContext.setNativeRequest(request); - externalContext.setNativeResponse(response); - context.setExternalContext(externalContext); - context.getMockFlowExecutionContext().setKey(new GeneratedFlowExecutionKey()); - View view = viewFactory.getView(context); - view.processUserEvent(); - assertEquals(true, view.hasFlowEvent()); - Event e = view.getFlowEvent(); - assertEquals(view, e.getSource()); - assertEquals("foo", e.getId()); - view.render(); - assertEquals("/parent/myview.jsp", response.getForwardedUrl()); - } - - private static class MockViewResolver implements ViewResolver { - - private String expectedViewName; - - public MockViewResolver(String expectedViewName) { - this.expectedViewName = expectedViewName; - } - - public org.springframework.web.servlet.View resolveViewName(String viewName, Locale arg1) throws Exception { - assertEquals(expectedViewName, viewName); - return new MockView(); - } - - class MockView implements org.springframework.web.servlet.View { - boolean renderCalled; - - public String getContentType() { - return "text/html"; - } - - public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { - request.getRequestDispatcher(expectedViewName).forward(request, response); - renderCalled = true; - } - } - - } - - private static class TestContextResource extends AbstractResource implements ContextResource { - private String path; - - public TestContextResource(String path) { - this.path = path; - } - - public String getDescription() { - return "test context resource"; - } - - public InputStream getInputStream() throws IOException { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - public String getPathWithinContext() { - return path; - } - } -} \ No newline at end of file diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java index bf1ef615..63f10507 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java @@ -54,7 +54,7 @@ public class MvcViewTests extends TestCase { context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); - MvcView view = new MockMvcView(mvcView, context); + AbstractMvcView view = new MockMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.render(); assertTrue(renderCalled); @@ -82,7 +82,7 @@ public class MvcViewTests extends TestCase { context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); - MvcView view = new MockMvcView(mvcView, context); + AbstractMvcView view = new MockMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.render(); assertEquals(context.getFlowScope().get("bindBean"), model.get("bindBean")); @@ -100,7 +100,7 @@ public class MvcViewTests extends TestCase { context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); - MvcView view = new MockMvcView(mvcView, context); + AbstractMvcView view = new MockMvcView(mvcView, context); view.processUserEvent(); assertFalse(view.hasFlowEvent()); assertNull(view.getFlowEvent()); @@ -114,7 +114,7 @@ public class MvcViewTests extends TestCase { context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); - MvcView view = new MockMvcView(mvcView, context); + AbstractMvcView view = new MockMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.processUserEvent(); assertTrue(view.hasFlowEvent()); @@ -138,7 +138,7 @@ public class MvcViewTests extends TestCase { context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = new MockView(); - MvcView view = new MockMvcView(mvcView, context); + AbstractMvcView view = new MockMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.processUserEvent(); assertTrue(view.hasFlowEvent()); @@ -152,7 +152,7 @@ public class MvcViewTests extends TestCase { assertEquals("foo", bindBean.getBeanProperty().getName()); } - private class MockMvcView extends MvcView { + private class MockMvcView extends AbstractMvcView { public MockMvcView(View view, RequestContext context) { super(view, context);