Shortest path to tests running with Spring Framework 5
Upgrade to Java 8+ Remove Portlet, Tiles2, and Hibernate 3 + 4 support Issue: SWF-1692
This commit is contained in:
29
build.gradle
29
build.gradle
@@ -24,8 +24,8 @@ configure(subprojects.findAll {it.name != "spring-build-src"}) { subproject ->
|
||||
apply plugin: "merge"
|
||||
apply from: "${rootProject.projectDir}/publish-maven.gradle"
|
||||
|
||||
sourceCompatibility=1.6
|
||||
targetCompatibility=1.6
|
||||
sourceCompatibility=1.8
|
||||
targetCompatibility=1.8
|
||||
|
||||
[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:none"]
|
||||
|
||||
@@ -75,13 +75,12 @@ configure(subprojects.findAll {
|
||||
}
|
||||
|
||||
subproject.ext {
|
||||
springVersion = "4.3.0.RELEASE"
|
||||
springVersion = "5.0.0.M4"
|
||||
springSecurityVersion = "4.1.0.RELEASE"
|
||||
slf4jVersion = "1.7.21"
|
||||
log4jVersion = "1.2.17"
|
||||
tiles2Version = "2.2.2"
|
||||
tiles3Version = "3.0.5"
|
||||
hibernate4Version = "4.3.11.Final"
|
||||
hibernate5Version = "5.2.6.Final"
|
||||
|
||||
}
|
||||
|
||||
@@ -171,16 +170,6 @@ project("spring-js") {
|
||||
compile("org.springframework:spring-web:$springVersion")
|
||||
compile("org.springframework:spring-webmvc:$springVersion")
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("org.apache.tiles:tiles-api:$tiles2Version")
|
||||
optional("org.apache.tiles:tiles-core:$tiles2Version") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
}
|
||||
optional("org.apache.tiles:tiles-jsp:$tiles2Version") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
}
|
||||
optional("org.apache.tiles:tiles-servlet:$tiles2Version") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
}
|
||||
testCompile("javax.servlet:jstl:1.2") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
}
|
||||
@@ -249,18 +238,16 @@ project("spring-webflow") {
|
||||
compile("org.springframework:spring-webmvc:$springVersion")
|
||||
provided("javax.el:javax.el-api:2.2.5")
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
provided("javax.portlet:portlet-api:2.0")
|
||||
provided("junit:junit:3.8.2")
|
||||
optional("org.hibernate:hibernate-core:$hibernate4Version") {
|
||||
optional("org.hibernate:hibernate-core:$hibernate5Version") {
|
||||
exclude group: "org.slf4j", module: "slf4j-api"
|
||||
}
|
||||
optional("org.slf4j:slf4j-api:$slf4jVersion")
|
||||
optional("org.springframework.security:spring-security-core:$springSecurityVersion")
|
||||
optional("org.springframework:spring-orm:$springVersion")
|
||||
optional("org.springframework:spring-tx:$springVersion")
|
||||
optional("org.springframework:spring-webmvc-portlet:$springVersion")
|
||||
testCompile("javax.validation:validation-api:1.0.0.GA")
|
||||
testCompile("org.hibernate:hibernate-entitymanager:$hibernate4Version") {
|
||||
testCompile("org.hibernate:hibernate-entitymanager:$hibernate5Version") {
|
||||
exclude group: "org.slf4j", module: "slf4j-api"
|
||||
}
|
||||
testCompile("org.hibernate:hibernate-validator:4.3.2.Final")
|
||||
@@ -287,7 +274,6 @@ project("spring-faces") {
|
||||
compile("org.springframework:spring-webmvc:$springVersion")
|
||||
provided("javax.el:javax.el-api:2.2.5")
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
provided("javax.portlet:portlet-api:2.0")
|
||||
provided("com.sun.faces:jsf-api:2.2.13")
|
||||
provided("com.sun.faces:jsf-impl:2.2.13")
|
||||
provided("org.apache.myfaces.core:myfaces-impl:2.1.18")
|
||||
@@ -295,7 +281,6 @@ project("spring-faces") {
|
||||
optional("org.springframework.security:spring-security-core:$springSecurityVersion")
|
||||
optional("org.springframework.security:spring-security-web:$springSecurityVersion")
|
||||
optional("org.springframework.security:spring-security-taglibs:$springSecurityVersion")
|
||||
optional("org.springframework:spring-webmvc-portlet:$springVersion")
|
||||
testCompile("log4j:log4j:$log4jVersion") {
|
||||
exclude group: "javax.mail", module: "mail"
|
||||
exclude group: "javax.jms", module: "jms"
|
||||
@@ -454,7 +439,7 @@ configure(rootProject) {
|
||||
gradleVersion = "1.11"
|
||||
|
||||
doLast() {
|
||||
def gradleOpts = "-XX:MaxPermSize=1024m -Xmx1024m"
|
||||
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
|
||||
def gradleBatOpts = "$gradleOpts -XX:MaxHeapSize=256m"
|
||||
File wrapperFile = file("gradlew")
|
||||
wrapperFile.text = wrapperFile.text.replace("DEFAULT_JVM_OPTS=",
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2014 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.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.faces.webflow.context.portlet.JsfResourceRequestHandler;
|
||||
|
||||
/**
|
||||
* Extends {@link AbstractFacesFlowConfiguration} and registers a
|
||||
* {@link JsfResourceRequestHandler} bean for serving resources in a Portlet environment.
|
||||
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.4
|
||||
*/
|
||||
public class AbstractFacesPortletFlowConfiguration extends AbstractFacesFlowConfiguration {
|
||||
|
||||
@Bean
|
||||
public JsfResourceRequestHandler jsfPortletResourceRequestHandler() {
|
||||
return new JsfResourceRequestHandler();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.application.portlet;
|
||||
|
||||
import javax.faces.application.ViewHandler;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.faces.webflow.context.portlet.PortletViewHandler;
|
||||
|
||||
/**
|
||||
* {@link ViewHandler} implementation for Portlets. This class is provided for compatibility with Web Flow v2.2.0, users
|
||||
* should replace references in their <tt>faces-confix.xml</tt> with
|
||||
* {@link org.springframework.faces.webflow.context.portlet.PortletViewHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
* @deprecated In favor of org.springframework.faces.webflow.context.portlet.PortletViewHandler
|
||||
*/
|
||||
@Deprecated
|
||||
public class PortletFaceletViewHandler extends PortletViewHandler {
|
||||
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
public PortletFaceletViewHandler(ViewHandler wrapped) {
|
||||
super(wrapped);
|
||||
this.logger.warn("*****");
|
||||
this.logger.warn("***** PLEASE UPDATE YOUR faces-confix.xml");
|
||||
this.logger.warn("*****");
|
||||
this.logger.warn("***** org.springframework.faces.webflow.application.portlet.PortletFaceletViewHandler has been deprecated");
|
||||
this.logger.warn("***** please update references to use org.springframework.faces.webflow.context.portlet.PortletViewHandler");
|
||||
this.logger.warn("*****");
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Map backed by a PortletContext for accessing Portlet initialization parameters.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class InitParameterMap extends StringKeyedMapAdapter<String> {
|
||||
|
||||
final private PortletContext portletContext;
|
||||
|
||||
public InitParameterMap(PortletContext portletContext) {
|
||||
this.portletContext = portletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAttribute(String key) {
|
||||
return this.portletContext.getInitParameter(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAttribute(String key, String value) {
|
||||
throw new UnsupportedOperationException("Cannot set PortletContext InitParameter");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeAttribute(String key) {
|
||||
throw new UnsupportedOperationException("Cannot remove PortletContext InitParameter");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return CollectionUtils.toIterator(this.portletContext.getInitParameterNames());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.Resource;
|
||||
import javax.faces.application.ResourceHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.EventRequest;
|
||||
import javax.portlet.EventResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.faces.webflow.FacesContextHelper;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.portlet.HandlerAdapter;
|
||||
import org.springframework.web.portlet.HandlerExecutionChain;
|
||||
import org.springframework.web.portlet.HandlerMapping;
|
||||
import org.springframework.web.portlet.ModelAndView;
|
||||
import org.springframework.web.portlet.handler.PortletContentGenerator;
|
||||
|
||||
/**
|
||||
* Handles a request by delegating to the JSF ResourceHandler, which serves web application and classpath resources such
|
||||
* as images, CSS and JavaScript files from well-known locations.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @author Phillip Webb
|
||||
* @see ResourceHandler
|
||||
*/
|
||||
public class JsfResourceRequestHandler extends PortletContentGenerator implements HandlerAdapter, HandlerMapping, Ordered {
|
||||
|
||||
private static final String FACES_RESOURCE = "javax.faces.resource";
|
||||
|
||||
private static final String RESOURCE_EXCLUDES_DEFAULT = ".class .jsp .jspx .properties .xhtml .groovy";
|
||||
|
||||
private static final String RESOURCE_EXCLUDES_PARAM_NAME = "javax.faces.RESOURCE_EXCLUDES";
|
||||
|
||||
private int order = Ordered.HIGHEST_PRECEDENCE;
|
||||
|
||||
public HandlerExecutionChain getHandler(PortletRequest request) throws Exception {
|
||||
if (request instanceof ResourceRequest && request.getParameter(FACES_RESOURCE) != null) {
|
||||
return new HandlerExecutionChain(new JsfResourceRequest());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supports(Object handler) {
|
||||
return handler instanceof JsfResourceRequest;
|
||||
}
|
||||
|
||||
public ModelAndView handleResource(ResourceRequest request, ResourceResponse response, Object handler) throws IOException {
|
||||
FacesContextHelper helper = new FacesContextHelper();
|
||||
try {
|
||||
FacesContext facesContext = helper.getFacesContext(getPortletContext(), request, response);
|
||||
handleResourceRequest(facesContext, request, response);
|
||||
} finally {
|
||||
helper.releaseIfNecessary();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleResourceRequest(FacesContext facesContext, ResourceRequest request, ResourceResponse response) throws IOException {
|
||||
ResourceHandler resourceHandler = facesContext.getApplication().getResourceHandler();
|
||||
String resourceName = request.getParameter(FACES_RESOURCE);
|
||||
String libraryName = request.getParameter("ln");
|
||||
int statusCodeNotFound = HttpStatus.NOT_FOUND.value();
|
||||
if (isResourceExcluded(facesContext, resourceName)) {
|
||||
response.setProperty(ResourceResponse.HTTP_STATUS_CODE, String.valueOf(statusCodeNotFound));
|
||||
PortletResponseUtils.setStatusCodeForPluto(response, statusCodeNotFound);
|
||||
return;
|
||||
}
|
||||
Resource resource = createResource(resourceHandler, resourceName, libraryName);
|
||||
if (resource == null) {
|
||||
response.setProperty(ResourceResponse.HTTP_STATUS_CODE, String.valueOf(statusCodeNotFound));
|
||||
PortletResponseUtils.setStatusCodeForPluto(response, statusCodeNotFound);
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : resource.getResponseHeaders().entrySet()) {
|
||||
response.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
response.setContentType(resource.getContentType());
|
||||
FileCopyUtils.copy(resource.getInputStream(), response.getPortletOutputStream());
|
||||
}
|
||||
|
||||
private boolean isResourceExcluded(FacesContext context, String resourceName) {
|
||||
for (String resourceExclude : getResourceExcludes(context)) {
|
||||
if (StringUtils.endsWithIgnoreCase(resourceName, resourceExclude)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String[] getResourceExcludes(FacesContext context) {
|
||||
String resourceExcludes = context.getExternalContext().getInitParameter(RESOURCE_EXCLUDES_PARAM_NAME);
|
||||
if (resourceExcludes == null) {
|
||||
resourceExcludes = RESOURCE_EXCLUDES_DEFAULT;
|
||||
}
|
||||
return StringUtils.tokenizeToStringArray(resourceExcludes, " ");
|
||||
}
|
||||
|
||||
private Resource createResource(ResourceHandler resourceHandler, String resourceName, String libraryName) {
|
||||
if (libraryName != null) {
|
||||
return resourceHandler.createResource(resourceName, libraryName);
|
||||
}
|
||||
return resourceHandler.createResource(resourceName);
|
||||
}
|
||||
|
||||
public void handleAction(ActionRequest request, ActionResponse response, Object handler) throws Exception {
|
||||
}
|
||||
|
||||
public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object handler) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void handleEvent(EventRequest request, EventResponse response, Object handler) throws Exception {
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
private static class JsfResourceRequest {
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
/**
|
||||
* A {@link Map} for accessing to {@link PortletContext} request parameters as a String array.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @see PortletRequest#getParameterValues(String)
|
||||
*/
|
||||
public class MultiValueRequestParameterMap extends RequestParameterMap<String[]> {
|
||||
|
||||
public MultiValueRequestParameterMap(PortletRequest portletRequest) {
|
||||
super(portletRequest);
|
||||
}
|
||||
|
||||
protected String[] getAttribute(String key) {
|
||||
return getPortletRequest().getParameterValues(key);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
/**
|
||||
* A {@link Map} for accessing to {@link PortletContext} request properties as a String array.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @see PortletRequest#getProperties(String)
|
||||
*/
|
||||
public class MultiValueRequestPropertyMap extends RequestPropertyMap<String[]> {
|
||||
|
||||
public MultiValueRequestPropertyMap(PortletRequest portletRequest) {
|
||||
super(portletRequest);
|
||||
}
|
||||
|
||||
protected String[] getAttribute(String key) {
|
||||
List<String> list = Collections.list(getPortletRequest().getProperties(key));
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
}
|
||||
@@ -1,599 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.Flash;
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.ClientDataRequest;
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.apache.myfaces.shared.context.flash.FlashImpl;
|
||||
import org.springframework.binding.collection.MapAdaptable;
|
||||
import org.springframework.faces.webflow.JsfRuntimeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.webflow.context.portlet.PortletContextMap;
|
||||
import org.springframework.webflow.context.portlet.PortletRequestMap;
|
||||
import org.springframework.webflow.context.portlet.PortletSessionMap;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
|
||||
import com.sun.faces.context.flash.ELFlash;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ExternalContext} for use with Portlet requests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class PortletExternalContextImpl extends ExternalContext {
|
||||
|
||||
private Map<String, Object> applicationMap;
|
||||
|
||||
private PortletContext portletContext;
|
||||
|
||||
private PortletRequest request;
|
||||
|
||||
private PortletResponse response;
|
||||
|
||||
private boolean isActionRequest;
|
||||
|
||||
private Map<String, String> initParameterMap;
|
||||
|
||||
private Map<String, String> requestHeaderMap;
|
||||
|
||||
private Map<String, String[]> requestHeaderValuesMap;
|
||||
|
||||
private Map<String, Object> requestMap;
|
||||
|
||||
private Map<String, String> requestParameterMap;
|
||||
|
||||
private Map<String, String[]> requestParameterValuesMap;
|
||||
|
||||
private MapAdaptable<String, Object> sessionMap;
|
||||
|
||||
private Flash flash;
|
||||
|
||||
public PortletExternalContextImpl(PortletContext portletContext, PortletRequest portletRequest,
|
||||
PortletResponse portletResponse) {
|
||||
this.portletContext = portletContext;
|
||||
this.request = portletRequest;
|
||||
this.response = portletResponse;
|
||||
if (portletRequest instanceof ActionRequest) {
|
||||
this.isActionRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
portletContext = null;
|
||||
request = null;
|
||||
response = null;
|
||||
applicationMap = null;
|
||||
sessionMap = null;
|
||||
requestMap = null;
|
||||
requestParameterMap = null;
|
||||
requestParameterValuesMap = null;
|
||||
requestHeaderMap = null;
|
||||
requestHeaderValuesMap = null;
|
||||
initParameterMap = null;
|
||||
}
|
||||
|
||||
public Flash getFlash() {
|
||||
if(this.flash == null) {
|
||||
this.flash = createFlash();
|
||||
}
|
||||
return this.flash;
|
||||
}
|
||||
|
||||
private Flash createFlash() {
|
||||
if (JsfRuntimeInformation.isMojarraPresent() && !JsfRuntimeInformation.isMyFacesInUse()) {
|
||||
return new MojarraFlashFactory().newFlash(this);
|
||||
}
|
||||
else {
|
||||
return new MyFacesFlashFactory().newFlash(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatch(String path) throws IOException {
|
||||
Assert.isTrue(!isActionRequest);
|
||||
PortletRequestDispatcher requestDispatcher = portletContext.getRequestDispatcher(path);
|
||||
try {
|
||||
requestDispatcher.include((RenderRequest) request, (RenderResponse) response);
|
||||
} catch (PortletException exception) {
|
||||
if (exception.getMessage() != null) {
|
||||
throw new FacesException(exception.getMessage(), exception);
|
||||
}
|
||||
throw new FacesException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redirect(String url) throws IOException {
|
||||
Assert.isInstanceOf(ActionResponse.class, response);
|
||||
((ActionResponse) response).sendRedirect(url);
|
||||
}
|
||||
|
||||
public String encodeNamespace(String name) {
|
||||
Assert.isTrue(!isActionRequest);
|
||||
return name + ((RenderResponse) response).getNamespace();
|
||||
}
|
||||
|
||||
public String encodeActionURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return response.encodeURL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeResourceURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return response.encodeURL(url);
|
||||
}
|
||||
|
||||
public String encodePartialActionURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return response.encodeURL(url);
|
||||
}
|
||||
|
||||
public String encodeBookmarkableURL(String baseUrl, Map<String, List<String>> parameters) {
|
||||
return encodeUrl(baseUrl, parameters);
|
||||
}
|
||||
|
||||
public String encodeRedirectURL(String baseUrl, Map<String, List<String>> parameters) {
|
||||
return response.encodeURL(encodeUrl(baseUrl, parameters));
|
||||
}
|
||||
|
||||
private String encodeUrl(String baseUrl, Map<String, List<String>> parameters) {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(baseUrl);
|
||||
for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
|
||||
builder.queryParam(entry.getKey(), entry.getValue().toArray());
|
||||
}
|
||||
return builder.buildAndExpand().toUriString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getContext() {
|
||||
return portletContext;
|
||||
}
|
||||
|
||||
public String getContextName() {
|
||||
return portletContext.getPortletContextName();
|
||||
}
|
||||
|
||||
public String getMimeType(String file) {
|
||||
return portletContext.getMimeType(file);
|
||||
}
|
||||
|
||||
public String getRealPath(String path) {
|
||||
return portletContext.getRealPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
Assert.notNull(message);
|
||||
portletContext.log(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message, Throwable exception) {
|
||||
Assert.notNull(message);
|
||||
Assert.notNull(exception);
|
||||
portletContext.log(message, exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getApplicationMap() {
|
||||
if (applicationMap == null) {
|
||||
applicationMap = new PortletContextMap(portletContext);
|
||||
}
|
||||
return applicationMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInitParameter(String name) {
|
||||
return portletContext.getInitParameter(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getInitParameterMap() {
|
||||
if (initParameterMap == null) {
|
||||
initParameterMap = new InitParameterMap(portletContext);
|
||||
}
|
||||
return initParameterMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String path) throws MalformedURLException {
|
||||
Assert.notNull(path);
|
||||
return portletContext.getResource(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String path) {
|
||||
Assert.notNull(path);
|
||||
return portletContext.getResourceAsStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getResourcePaths(String path) {
|
||||
Assert.notNull(path);
|
||||
return portletContext.getResourcePaths(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequest(Object request) {
|
||||
this.request = (PortletRequest) request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestContentType() {
|
||||
if (request instanceof ClientDataRequest) {
|
||||
ClientDataRequest clientDataRequest = (ClientDataRequest) request;
|
||||
return clientDataRequest.getContentType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestContextPath() {
|
||||
return request.getContextPath();
|
||||
}
|
||||
|
||||
public String getRequestScheme() {
|
||||
return request.getScheme();
|
||||
}
|
||||
|
||||
public String getRequestServerName() {
|
||||
return request.getServerName();
|
||||
}
|
||||
|
||||
public int getRequestServerPort() {
|
||||
return request.getServerPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getRequestLocale() {
|
||||
return request.getLocale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Locale> getRequestLocales() {
|
||||
return CollectionUtils.toIterator(request.getLocales());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestCharacterEncoding() {
|
||||
if (request instanceof ClientDataRequest) {
|
||||
return ((ClientDataRequest) request).getCharacterEncoding();
|
||||
}
|
||||
else {
|
||||
Assert.state(response instanceof MimeResponse);
|
||||
return ((MimeResponse) response).getCharacterEncoding();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRequestCharacterEncoding(String encoding) throws java.io.UnsupportedEncodingException {
|
||||
Assert.isInstanceOf(ClientDataRequest.class, request);
|
||||
((ClientDataRequest) request).setCharacterEncoding(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRequestCookieMap() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getRequestHeaderMap() {
|
||||
if (requestHeaderMap == null) {
|
||||
requestHeaderMap = new SingleValueRequestPropertyMap(request);
|
||||
}
|
||||
return requestHeaderMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getRequestHeaderValuesMap() {
|
||||
if (requestHeaderValuesMap == null) {
|
||||
requestHeaderValuesMap = new MultiValueRequestPropertyMap(request);
|
||||
}
|
||||
return requestHeaderValuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRequestMap() {
|
||||
if (requestMap == null) {
|
||||
requestMap = new PortletRequestMap(request);
|
||||
}
|
||||
return requestMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getRequestParameterMap() {
|
||||
if (requestParameterMap == null) {
|
||||
requestParameterMap = new SingleValueRequestParameterMap(request);
|
||||
}
|
||||
return requestParameterMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getRequestParameterNames() {
|
||||
return CollectionUtils.toIterator(request.getParameterNames());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getRequestParameterValuesMap() {
|
||||
if (requestParameterValuesMap == null) {
|
||||
requestParameterValuesMap = new MultiValueRequestParameterMap(request);
|
||||
}
|
||||
return requestParameterValuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestServletPath() {
|
||||
// Return "" instead of null in order to prevent NullPointerException in Apache MyFaces 1.2 when it tries to
|
||||
// determine the servlet mappings in DefaultViewHandlerSupport.calculateFacesServletMapping(..).
|
||||
// Note that the FacesServlet mapping in Web Flow is not relevant so this should be ok.
|
||||
//
|
||||
// Alternatively this method could be implemented to provide an actual servlet path derived from the
|
||||
// viewId when that becomes available during rendering as the MyFaces Portlet Bridge does.
|
||||
//
|
||||
// return JsfRuntimeInformation.isMyFacesPresent() ? "" : null;
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestPathInfo() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public int getRequestContentLength() {
|
||||
Assert.isInstanceOf(ClientDataRequest.class, request);
|
||||
return ((ClientDataRequest) request).getContentLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthType() {
|
||||
return request.getAuthType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteUser() {
|
||||
return request.getRemoteUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return request.getUserPrincipal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
Assert.notNull(role);
|
||||
return request.isUserInRole(role);
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return request.isSecure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResponse(Object response) {
|
||||
this.response = (PortletResponse) response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponseContentType() {
|
||||
return getMimeResponse().getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponseCharacterEncoding() {
|
||||
return getMimeResponse().getCharacterEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResponseCharacterEncoding(String encoding) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
public OutputStream getResponseOutputStream() throws IOException {
|
||||
return getMimeResponse().getPortletOutputStream();
|
||||
}
|
||||
|
||||
public Writer getResponseOutputWriter() throws IOException {
|
||||
return getMimeResponse().getWriter();
|
||||
}
|
||||
|
||||
public void addResponseCookie(String name, String value, Map<String, Object> properties) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
setCookieProperties(cookie, properties);
|
||||
response.addProperty(cookie);
|
||||
}
|
||||
|
||||
private void setCookieProperties(Cookie cookie, Map<String, Object> properties) {
|
||||
if (properties != null) {
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
setCookieProperty(cookie, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setCookieProperty(Cookie cookie, String property, Object value) {
|
||||
if ("domain".equalsIgnoreCase(property)) {
|
||||
cookie.setDomain((String) value);
|
||||
return;
|
||||
}
|
||||
if ("maxAge".equalsIgnoreCase(property)) {
|
||||
cookie.setMaxAge((Integer) value);
|
||||
return;
|
||||
}
|
||||
if ("path".equalsIgnoreCase(property)) {
|
||||
cookie.setPath((String) value);
|
||||
return;
|
||||
}
|
||||
if ("secure".equalsIgnoreCase(property)) {
|
||||
cookie.setSecure((Boolean) value);
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("Unknown cookie property " + property);
|
||||
}
|
||||
|
||||
public void addResponseHeader(String name, String value) {
|
||||
response.addProperty(name, value);
|
||||
}
|
||||
|
||||
public void responseFlushBuffer() throws IOException {
|
||||
getMimeResponse().flushBuffer();
|
||||
}
|
||||
|
||||
public void responseReset() {
|
||||
MimeResponse mimeResponse = getMimeResponse(false);
|
||||
if (mimeResponse != null) {
|
||||
mimeResponse.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void responseSendError(int statusCode, String message) throws IOException {
|
||||
throw new IOException(statusCode + ": " + message);
|
||||
}
|
||||
|
||||
public void setResponseBufferSize(int size) {
|
||||
getMimeResponse().setBufferSize(size);
|
||||
}
|
||||
|
||||
public void setResponseContentLength(int length) {
|
||||
if (portletContext instanceof ResourceResponse) {
|
||||
((ResourceResponse) portletContext).setContentLength(length);
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponseContentType(String contentType) {
|
||||
MimeResponse mimeResponse = getMimeResponse(false);
|
||||
if (mimeResponse != null) {
|
||||
mimeResponse.setContentType(contentType);
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponseHeader(String name, String value) {
|
||||
response.setProperty(name, value);
|
||||
}
|
||||
|
||||
public void setResponseStatus(int statusCode) {
|
||||
response.setProperty(ResourceResponse.HTTP_STATUS_CODE, String.valueOf(statusCode));
|
||||
PortletResponseUtils.setStatusCodeForPluto(response, statusCode);
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
MimeResponse mimeResponse = getMimeResponse(false);
|
||||
return ((mimeResponse != null) ? mimeResponse.isCommitted() : false);
|
||||
}
|
||||
|
||||
public int getResponseBufferSize() {
|
||||
return getMimeResponse().getBufferSize();
|
||||
|
||||
}
|
||||
|
||||
private MimeResponse getMimeResponse() {
|
||||
return getMimeResponse(true);
|
||||
}
|
||||
|
||||
private MimeResponse getMimeResponse(boolean required) {
|
||||
if (response instanceof MimeResponse) {
|
||||
return (MimeResponse) response;
|
||||
}
|
||||
if (!required) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Portlet response is not a MimeResponse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSession(boolean create) {
|
||||
return request.getPortletSession(create);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSessionMap() {
|
||||
if (sessionMap == null) {
|
||||
sessionMap = new LocalAttributeMap<Object>(new PortletSessionMap(request));
|
||||
}
|
||||
return sessionMap.asMap();
|
||||
}
|
||||
|
||||
public int getSessionMaxInactiveInterval() {
|
||||
return request.getPortletSession().getMaxInactiveInterval();
|
||||
}
|
||||
|
||||
public void invalidateSession() {
|
||||
PortletSession portletSession = request.getPortletSession(false);
|
||||
if (portletSession != null) {
|
||||
portletSession.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSessionMaxInactiveInterval(int interval) {
|
||||
request.getPortletSession().setMaxInactiveInterval(interval);
|
||||
}
|
||||
|
||||
private static class MojarraFlashFactory {
|
||||
public Flash newFlash(ExternalContext context) {
|
||||
return (Flash) ELFlash.getFlash();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyFacesFlashFactory {
|
||||
public Flash newFlash(ExternalContext context) {
|
||||
return FlashImpl.getCurrentInstance(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2015 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.context.portlet;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
|
||||
import org.springframework.faces.webflow.JsfRuntimeInformation;
|
||||
|
||||
/**
|
||||
* {@link FacesContextFactory} to support portlet environments.
|
||||
* @author Phillip Webb
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class PortletFacesContextFactory extends FacesContextFactory {
|
||||
|
||||
private final FacesContextFactory factory;
|
||||
|
||||
public PortletFacesContextFactory(FacesContextFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FacesContextFactory getWrapped() {
|
||||
return this.factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
|
||||
throws FacesException {
|
||||
if (JsfRuntimeInformation.isPortletContext(context)) {
|
||||
return new PortletFacesContextImpl((PortletContext) context, (PortletRequest) request,
|
||||
(PortletResponse) response);
|
||||
}
|
||||
return this.factory.getFacesContext(context, request, response, lifecycle);
|
||||
}
|
||||
}
|
||||
@@ -1,460 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELContextEvent;
|
||||
import javax.el.ELContextListener;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.FunctionMapper;
|
||||
import javax.el.VariableMapper;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.ApplicationFactory;
|
||||
import javax.faces.application.FacesMessage;
|
||||
import javax.faces.application.ProjectStage;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.ExceptionHandler;
|
||||
import javax.faces.context.ExceptionHandlerFactory;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.PartialViewContext;
|
||||
import javax.faces.context.PartialViewContextFactory;
|
||||
import javax.faces.context.ResponseStream;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
|
||||
import org.springframework.faces.webflow.JsfUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* The default FacesContext implementation in Mojarra and in Apache MyFaces depends on the Servlet API. This
|
||||
* implementation provides an alternative that accepts Portlet request and response structures and creates a
|
||||
* {@link PortletExternalContextImpl} in its constructor. The rest of the method implementations mimic the equivalent
|
||||
* methods in the default FacesContext implementation.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class PortletFacesContextImpl extends FacesContext {
|
||||
|
||||
private static final List<FacesMessage> NO_MESSAGES = Collections.unmodifiableList(Collections
|
||||
.<FacesMessage> emptyList());
|
||||
|
||||
private static final Iterator<String> NO_CLIENT_IDS_WITH_MESSAGES = Collections.unmodifiableSet(
|
||||
Collections.<String> emptySet()).iterator();
|
||||
|
||||
private Application application;
|
||||
|
||||
private ELContext elContext;
|
||||
|
||||
private ExternalContext externalContext;
|
||||
|
||||
private List<Message> messages;
|
||||
|
||||
private FacesMessage.Severity maximumSeverity;
|
||||
|
||||
private boolean released = false;
|
||||
|
||||
private RenderKitFactory renderKitFactory;
|
||||
|
||||
private boolean renderResponse = false;
|
||||
|
||||
private boolean responseComplete = false;
|
||||
|
||||
private ResponseStream responseStream;
|
||||
|
||||
private ResponseWriter responseWriter;
|
||||
|
||||
private UIViewRoot viewRoot;
|
||||
|
||||
private Map<Object, Object> attributes;
|
||||
|
||||
private PhaseId currentPhaseId;
|
||||
|
||||
private ExceptionHandler exceptionHandler;
|
||||
|
||||
private boolean validationFailed;
|
||||
|
||||
private PartialViewContext partialViewContext;
|
||||
|
||||
private boolean processingEvents;
|
||||
|
||||
public PortletFacesContextImpl(ExternalContext externalContext) {
|
||||
this.externalContext = externalContext;
|
||||
}
|
||||
|
||||
public PortletFacesContextImpl(PortletContext portletContext, PortletRequest portletRequest,
|
||||
PortletResponse portletResponse) {
|
||||
application = JsfUtils.findFactory(ApplicationFactory.class).getApplication();
|
||||
renderKitFactory = JsfUtils.findFactory(RenderKitFactory.class);
|
||||
this.externalContext = new PortletExternalContextImpl(portletContext, portletRequest, portletResponse);
|
||||
FacesContext.setCurrentInstance(this);
|
||||
// This depends on the current FacesContext instance
|
||||
this.exceptionHandler = JsfUtils.findFactory(ExceptionHandlerFactory.class).getExceptionHandler();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
assertNotReleased();
|
||||
if (externalContext != null) {
|
||||
Method delegateMethod = ClassUtils.getMethodIfAvailable(externalContext.getClass(), "release");
|
||||
if (delegateMethod != null) {
|
||||
try {
|
||||
delegateMethod.invoke(externalContext);
|
||||
} catch (Exception e) {
|
||||
externalContext.log("Failed to release external context", e);
|
||||
}
|
||||
externalContext = null;
|
||||
}
|
||||
}
|
||||
messages = null;
|
||||
maximumSeverity = null;
|
||||
application = null;
|
||||
responseStream = null;
|
||||
responseWriter = null;
|
||||
viewRoot = null;
|
||||
exceptionHandler = null;
|
||||
attributes = null;
|
||||
|
||||
released = true;
|
||||
FacesContext.setCurrentInstance(null);
|
||||
}
|
||||
|
||||
public ExternalContext getExternalContext() {
|
||||
assertNotReleased();
|
||||
return externalContext;
|
||||
}
|
||||
|
||||
public Application getApplication() {
|
||||
assertNotReleased();
|
||||
return application;
|
||||
}
|
||||
|
||||
public RenderKit getRenderKit() {
|
||||
if (getViewRoot() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String renderKitId = getViewRoot().getRenderKitId();
|
||||
|
||||
if (renderKitId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return renderKitFactory.getRenderKit(this, renderKitId);
|
||||
}
|
||||
|
||||
public boolean getRenderResponse() {
|
||||
assertNotReleased();
|
||||
return renderResponse;
|
||||
}
|
||||
|
||||
public boolean getResponseComplete() {
|
||||
assertNotReleased();
|
||||
return responseComplete;
|
||||
}
|
||||
|
||||
public ResponseStream getResponseStream() {
|
||||
assertNotReleased();
|
||||
return responseStream;
|
||||
}
|
||||
|
||||
public void setResponseStream(ResponseStream responseStream) {
|
||||
assertNotReleased();
|
||||
if (responseStream == null) {
|
||||
throw new NullPointerException("responseStream");
|
||||
}
|
||||
this.responseStream = responseStream;
|
||||
}
|
||||
|
||||
public ResponseWriter getResponseWriter() {
|
||||
assertNotReleased();
|
||||
return responseWriter;
|
||||
}
|
||||
|
||||
public void setResponseWriter(ResponseWriter responseWriter) {
|
||||
assertNotReleased();
|
||||
if (responseWriter == null) {
|
||||
throw new NullPointerException("responseWriter");
|
||||
}
|
||||
this.responseWriter = responseWriter;
|
||||
}
|
||||
|
||||
public UIViewRoot getViewRoot() {
|
||||
assertNotReleased();
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
public void setViewRoot(UIViewRoot viewRoot) {
|
||||
assertNotReleased();
|
||||
if (viewRoot == null) {
|
||||
throw new NullPointerException("viewRoot");
|
||||
}
|
||||
this.viewRoot = viewRoot;
|
||||
}
|
||||
|
||||
public void renderResponse() {
|
||||
assertNotReleased();
|
||||
renderResponse = true;
|
||||
}
|
||||
|
||||
public void responseComplete() {
|
||||
assertNotReleased();
|
||||
responseComplete = true;
|
||||
}
|
||||
|
||||
public ELContext getELContext() {
|
||||
if (elContext == null) {
|
||||
createELContext();
|
||||
}
|
||||
return elContext;
|
||||
}
|
||||
|
||||
private void createELContext() {
|
||||
elContext = new PortletELContextImpl(getApplication().getELResolver());
|
||||
elContext.putContext(FacesContext.class, FacesContext.getCurrentInstance());
|
||||
if (getViewRoot() != null) {
|
||||
elContext.setLocale(getViewRoot().getLocale());
|
||||
}
|
||||
fireContextCreated(getApplication().getELContextListeners());
|
||||
}
|
||||
|
||||
private void fireContextCreated(ELContextListener[] listeners) {
|
||||
if (listeners.length > 0) {
|
||||
ELContextEvent event = new ELContextEvent(elContext);
|
||||
for (ELContextListener listener : listeners) {
|
||||
listener.contextCreated(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMessage(String clientId, FacesMessage message) {
|
||||
assertNotReleased();
|
||||
if (message == null) {
|
||||
throw new NullPointerException("message");
|
||||
}
|
||||
|
||||
if (messages == null) {
|
||||
messages = new ArrayList<Message>();
|
||||
}
|
||||
messages.add(new Message(clientId, message));
|
||||
recalculateMaximumSeverity(message.getSeverity());
|
||||
}
|
||||
|
||||
private void recalculateMaximumSeverity(FacesMessage.Severity severity) {
|
||||
if (severity != null) {
|
||||
if (maximumSeverity == null || severity.compareTo(maximumSeverity) > 0) {
|
||||
maximumSeverity = severity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FacesMessage.Severity getMaximumSeverity() {
|
||||
assertNotReleased();
|
||||
return maximumSeverity;
|
||||
}
|
||||
|
||||
public Iterator<FacesMessage> getMessages() {
|
||||
return getMessageList().iterator();
|
||||
}
|
||||
|
||||
public List<FacesMessage> getMessageList() {
|
||||
assertNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return NO_MESSAGES;
|
||||
}
|
||||
List<FacesMessage> messageList = new ArrayList<FacesMessage>();
|
||||
for (Message message : messages) {
|
||||
messageList.add(message.getFacesMessage());
|
||||
}
|
||||
return Collections.unmodifiableList(messageList);
|
||||
}
|
||||
|
||||
public Iterator<FacesMessage> getMessages(String clientId) {
|
||||
return getMessageList(clientId).iterator();
|
||||
}
|
||||
|
||||
public List<FacesMessage> getMessageList(String clientId) {
|
||||
assertNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return NO_MESSAGES;
|
||||
}
|
||||
List<FacesMessage> messageList = new ArrayList<FacesMessage>();
|
||||
for (Message message : messages) {
|
||||
if (message.isForClientId(clientId)) {
|
||||
messageList.add(message.getFacesMessage());
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(messageList);
|
||||
}
|
||||
|
||||
public Iterator<String> getClientIdsWithMessages() {
|
||||
assertNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return NO_CLIENT_IDS_WITH_MESSAGES;
|
||||
}
|
||||
Set<String> clientIdsWithMessags = new LinkedHashSet<String>();
|
||||
for (Message message : messages) {
|
||||
clientIdsWithMessags.add(message.getClientId());
|
||||
}
|
||||
return Collections.unmodifiableSet(clientIdsWithMessags).iterator();
|
||||
}
|
||||
|
||||
public Map<Object, Object> getAttributes() {
|
||||
assertNotReleased();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<Object, Object>();
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public PhaseId getCurrentPhaseId() {
|
||||
assertNotReleased();
|
||||
return currentPhaseId;
|
||||
}
|
||||
|
||||
public ExceptionHandler getExceptionHandler() {
|
||||
return exceptionHandler;
|
||||
}
|
||||
|
||||
public boolean isPostback() {
|
||||
RenderKit renderKit = getRenderKit();
|
||||
if (renderKit == null) {
|
||||
String renderKitId = getApplication().getViewHandler().calculateRenderKitId(this);
|
||||
renderKit = JsfUtils.findFactory(RenderKitFactory.class).getRenderKit(this, renderKitId);
|
||||
}
|
||||
return renderKit.getResponseStateManager().isPostback(this);
|
||||
}
|
||||
|
||||
public boolean isReleased() {
|
||||
return released;
|
||||
}
|
||||
|
||||
public boolean isValidationFailed() {
|
||||
assertNotReleased();
|
||||
return validationFailed;
|
||||
}
|
||||
|
||||
public void setCurrentPhaseId(PhaseId currentPhaseId) {
|
||||
assertNotReleased();
|
||||
this.currentPhaseId = currentPhaseId;
|
||||
}
|
||||
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
assertNotReleased();
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
}
|
||||
|
||||
public void validationFailed() {
|
||||
assertNotReleased();
|
||||
validationFailed = true;
|
||||
}
|
||||
|
||||
public PartialViewContext getPartialViewContext() {
|
||||
assertNotReleased();
|
||||
if (partialViewContext == null) {
|
||||
partialViewContext = JsfUtils.findFactory(PartialViewContextFactory.class).getPartialViewContext(this);
|
||||
}
|
||||
return partialViewContext;
|
||||
}
|
||||
|
||||
public boolean isProcessingEvents() {
|
||||
assertNotReleased();
|
||||
return processingEvents;
|
||||
}
|
||||
|
||||
public void setProcessingEvents(boolean processingEvents) {
|
||||
assertNotReleased();
|
||||
this.processingEvents = processingEvents;
|
||||
}
|
||||
|
||||
public boolean isProjectStage(ProjectStage stage) {
|
||||
Assert.notNull(stage, "Stage must not be null");
|
||||
return (stage.equals(getApplication().getProjectStage()));
|
||||
}
|
||||
|
||||
private void assertNotReleased() {
|
||||
Assert.isTrue(!released, "FacesContext already released");
|
||||
}
|
||||
|
||||
private class PortletELContextImpl extends ELContext {
|
||||
|
||||
private FunctionMapper functionMapper;
|
||||
private VariableMapper variableMapper;
|
||||
private ELResolver resolver;
|
||||
|
||||
public PortletELContextImpl(ELResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionMapper getFunctionMapper() {
|
||||
return functionMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableMapper getVariableMapper() {
|
||||
return variableMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ELResolver getELResolver() {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Message {
|
||||
|
||||
private String clientId;
|
||||
private FacesMessage facesMessage;
|
||||
|
||||
public Message(String clientId, FacesMessage facesMessage) {
|
||||
this.clientId = clientId;
|
||||
this.facesMessage = facesMessage;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public boolean isForClientId(String clientId) {
|
||||
return ObjectUtils.nullSafeEquals(this.clientId, clientId);
|
||||
}
|
||||
|
||||
public FacesMessage getFacesMessage() {
|
||||
return facesMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Utilities when dealing with {@link PortletResponse}s.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PortletResponseUtils {
|
||||
|
||||
// Work around for PLUTO-603
|
||||
|
||||
public static void setStatusCodeForPluto(PortletResponse response, int statusCode) {
|
||||
if (response.getClass().getName().startsWith("org.apache.pluto")) {
|
||||
Method servletResponseMethod = ReflectionUtils.findMethod(response.getClass(), "getServletResponse");
|
||||
if (servletResponseMethod != null) {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(servletResponseMethod);
|
||||
HttpServletResponse servletResponse = (HttpServletResponse) servletResponseMethod.invoke(response);
|
||||
servletResponse.setStatus(statusCode);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.application.ViewHandlerWrapper;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.ResourceURL;
|
||||
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* JSF {@link ViewHandler} that adds support for generating Portlet compatible resource URLs.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class PortletViewHandler extends ViewHandlerWrapper {
|
||||
|
||||
private static final String FACES_RESOURCE = "javax.faces.resource";
|
||||
|
||||
private ViewHandler wrapped;
|
||||
|
||||
public PortletViewHandler(ViewHandler wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public ViewHandler getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public String getResourceURL(FacesContext context, String path) {
|
||||
String uri = super.getResourceURL(context, path);
|
||||
int facesResourceIndex = (uri == null ? -1 : uri.indexOf(FACES_RESOURCE));
|
||||
if (facesResourceIndex == -1) {
|
||||
return uri;
|
||||
}
|
||||
UriComponents components = UriComponentsBuilder.fromUriString(uri.substring(facesResourceIndex + FACES_RESOURCE.length() + 1)).build();
|
||||
MimeResponse response = (MimeResponse) context.getExternalContext().getResponse();
|
||||
ResourceURL resourceURL = response.createResourceURL();
|
||||
for (Map.Entry<String, List<String>> entry : components.getQueryParams().entrySet()) {
|
||||
String name = entry.getKey();
|
||||
List<String> value = entry.getValue();
|
||||
resourceURL.setParameter(name, value.toArray(new String[value.size()]));
|
||||
}
|
||||
resourceURL.setParameter(FACES_RESOURCE, components.getPath());
|
||||
return resourceURL.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.webflow.context.portlet.PortletRequestParameterMap;
|
||||
|
||||
/**
|
||||
* /** Base class for {@link Map}s allowing access to {@link PortletContext} request paramters.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @see SingleValueRequestParameterMap
|
||||
* @see MultiValueRequestParameterMap
|
||||
*/
|
||||
public abstract class RequestParameterMap<V> extends StringKeyedMapAdapter<V> {
|
||||
|
||||
private final PortletRequest portletRequest;
|
||||
|
||||
private final Delegate delegate;
|
||||
|
||||
public RequestParameterMap(PortletRequest portletRequest) {
|
||||
this.portletRequest = portletRequest;
|
||||
this.delegate = new Delegate(portletRequest);
|
||||
}
|
||||
|
||||
protected final PortletRequest getPortletRequest() {
|
||||
return this.portletRequest;
|
||||
}
|
||||
|
||||
protected void setAttribute(String key, V value) {
|
||||
this.delegate.setAttribute(key, value);
|
||||
}
|
||||
|
||||
protected void removeAttribute(String key) {
|
||||
this.delegate.removeAttribute(key);
|
||||
}
|
||||
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return this.delegate.getAttributeNames();
|
||||
}
|
||||
|
||||
private static class Delegate extends PortletRequestParameterMap {
|
||||
|
||||
public Delegate(PortletRequest request) {
|
||||
super(request);
|
||||
}
|
||||
|
||||
public Object getAttribute(String key) {
|
||||
return super.getAttribute(key);
|
||||
}
|
||||
|
||||
public void setAttribute(String key, Object value) {
|
||||
super.setAttribute(key, value);
|
||||
}
|
||||
|
||||
public void removeAttribute(String key) {
|
||||
super.removeAttribute(key);
|
||||
}
|
||||
|
||||
public Iterator<String> getAttributeNames() {
|
||||
return super.getAttributeNames();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Base class for {@link Map}s allowing access to {@link PortletContext} request properties.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @see SingleValueRequestPropertyMap
|
||||
* @see MultiValueRequestPropertyMap
|
||||
*/
|
||||
public abstract class RequestPropertyMap<V> extends StringKeyedMapAdapter<V> {
|
||||
|
||||
private final PortletRequest portletRequest;
|
||||
|
||||
public RequestPropertyMap(PortletRequest portletRequest) {
|
||||
this.portletRequest = portletRequest;
|
||||
}
|
||||
|
||||
protected final PortletRequest getPortletRequest() {
|
||||
return this.portletRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAttribute(String key, V value) {
|
||||
throw new UnsupportedOperationException("Cannot set PortletRequest property");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeAttribute(String key) {
|
||||
throw new UnsupportedOperationException("Cannot remove PortletRequest property");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return CollectionUtils.toIterator(this.portletRequest.getPropertyNames());
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
/**
|
||||
* A {@link Map} for accessing to {@link PortletContext} request parameters containing single String values.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @see PortletRequest#getParameterValues(String)
|
||||
*/
|
||||
public class SingleValueRequestParameterMap extends RequestParameterMap<String> {
|
||||
|
||||
public SingleValueRequestParameterMap(PortletRequest portletRequest) {
|
||||
super(portletRequest);
|
||||
}
|
||||
|
||||
protected String getAttribute(String key) {
|
||||
return getPortletRequest().getParameter(key);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
/**
|
||||
* A {@link Map} for accessing to {@link PortletContext} request properties containing single String values.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @see PortletRequest#getProperties(String)
|
||||
*/
|
||||
public class SingleValueRequestPropertyMap extends RequestPropertyMap<String> {
|
||||
|
||||
public SingleValueRequestPropertyMap(PortletRequest portletRequest) {
|
||||
super(portletRequest);
|
||||
}
|
||||
|
||||
protected String getAttribute(String key) {
|
||||
return getPortletRequest().getProperty(key);
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,4 @@ public abstract class AbstractResourcesConfigurationTests extends TestCase {
|
||||
assertEquals(0, handlerMapping.getOrder());
|
||||
}
|
||||
|
||||
public void testConfigurePortlet() {
|
||||
Object resourceHandler = this.context.getBean(ResourcesBeanDefinitionParser.PORTLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
assertNotNull(resourceHandler);
|
||||
assertTrue(resourceHandler instanceof org.springframework.faces.webflow.context.portlet.JsfResourceRequestHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
|
||||
import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
|
||||
import org.springframework.webflow.validation.BeanValidationHintResolver;
|
||||
|
||||
public class FacesFlowBuilderServicesJavaConfigTests extends AbstractFacesFlowBuilderServicesConfigurationTests {
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.springframework.faces.config;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
public class ResourcesJavaConfigTests extends AbstractResourcesConfigurationTests {
|
||||
|
||||
|
||||
@Override
|
||||
protected ApplicationContext initApplicationContext() {
|
||||
return new AnnotationConfigApplicationContext(FacesFlowConfig.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class FacesFlowConfig extends AbstractFacesPortletFlowConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package org.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
|
||||
public class MultiValueRequestParameterMapTests extends TestCase {
|
||||
|
||||
private MultiValueRequestParameterMap requestMap;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.request = new MockPortletRequest();
|
||||
this.requestMap = new MultiValueRequestParameterMap(this.request);
|
||||
}
|
||||
|
||||
public void testMultiValueParameter() throws Exception {
|
||||
this.request.setParameter("key", "value");
|
||||
this.request.addParameter("key", "value2");
|
||||
Object actual = this.requestMap.getAttribute("key");
|
||||
assertTrue(actual.getClass().isArray());
|
||||
assertEquals(2, ((String[]) actual).length);
|
||||
assertEquals("value", ((String[]) actual)[0]);
|
||||
assertEquals("value2", ((String[]) actual)[1]);
|
||||
}
|
||||
|
||||
public void testSingleValueParameterAsArray() throws Exception {
|
||||
this.request.setParameter("key", "value");
|
||||
Object actual = this.requestMap.getAttribute("key");
|
||||
assertTrue(actual.getClass().isArray());
|
||||
assertEquals(1, ((String[]) actual).length);
|
||||
assertEquals("value", ((String[]) actual)[0]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
|
||||
public class MultiValueRequestPropertyMapTests extends TestCase {
|
||||
|
||||
private MultiValueRequestPropertyMap requestMap;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.request = new MockPortletRequest();
|
||||
this.requestMap = new MultiValueRequestPropertyMap(this.request);
|
||||
}
|
||||
|
||||
public void testMultiValueProperty() throws Exception {
|
||||
this.request.setProperty("key", "value");
|
||||
this.request.addProperty("key", "value2");
|
||||
Object actual = this.requestMap.getAttribute("key");
|
||||
assertEquals(2, ((String[]) actual).length);
|
||||
assertEquals("value", ((String[]) actual)[0]);
|
||||
assertEquals("value2", ((String[]) actual)[1]);
|
||||
}
|
||||
|
||||
public void testSingleValuePropertyAsArray() throws Exception {
|
||||
this.request.setProperty("key", "value");
|
||||
Object actual = this.requestMap.getAttribute("key");
|
||||
assertEquals(1, ((String[]) actual).length);
|
||||
assertEquals("value", ((String[]) actual)[0]);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
|
||||
public class SingleValueRequestParameterMapTests extends TestCase {
|
||||
|
||||
private SingleValueRequestParameterMap requestMap;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.request = new MockPortletRequest();
|
||||
this.requestMap = new SingleValueRequestParameterMap(this.request);
|
||||
}
|
||||
|
||||
public void testSingleValueParameter() throws Exception {
|
||||
this.request.setParameter("key", "value");
|
||||
assertEquals("value", this.requestMap.getAttribute("key"));
|
||||
}
|
||||
|
||||
public void testMultiValueParameterAsString() throws Exception {
|
||||
this.request.setParameter("key", "value");
|
||||
this.request.addParameter("key", "value2");
|
||||
Object actual = this.requestMap.getAttribute("key");
|
||||
assertEquals("value", actual);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
|
||||
public class SingleValueRequestPropertyMapTests extends TestCase {
|
||||
|
||||
private SingleValueRequestPropertyMap requestMap;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.request = new MockPortletRequest();
|
||||
this.requestMap = new SingleValueRequestPropertyMap(this.request);
|
||||
}
|
||||
|
||||
public void testSingleValueProperty() throws Exception {
|
||||
this.request.setProperty("key", "value");
|
||||
assertEquals("value", this.requestMap.getAttribute("key"));
|
||||
}
|
||||
|
||||
public void testMultiValuePropertyAsString() throws Exception {
|
||||
this.request.setProperty("key", "value");
|
||||
this.request.addProperty("key", "value2");
|
||||
Object actual = this.requestMap.getAttribute("key");
|
||||
assertEquals("value", actual);
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.js.ajax.tiles2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.tiles.Attribute;
|
||||
import org.apache.tiles.AttributeContext;
|
||||
import org.apache.tiles.Definition;
|
||||
import org.apache.tiles.context.TilesRequestContext;
|
||||
import org.apache.tiles.context.TilesRequestContextFactory;
|
||||
import org.apache.tiles.impl.BasicTilesContainer;
|
||||
import org.apache.tiles.servlet.context.ServletTilesRequestContextFactory;
|
||||
import org.apache.tiles.servlet.context.ServletUtil;
|
||||
import org.springframework.js.ajax.AjaxHandler;
|
||||
import org.springframework.js.ajax.SpringJavascriptAjaxHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.support.JstlUtils;
|
||||
import org.springframework.web.servlet.support.RequestContext;
|
||||
import org.springframework.web.servlet.view.tiles2.TilesView;
|
||||
|
||||
/**
|
||||
* Tiles view implementation that is able to handle partial rendering for Spring Javascript Ajax requests.
|
||||
*
|
||||
* <p>
|
||||
* This implementation uses the {@link SpringJavascriptAjaxHandler} by default to determine whether the current request
|
||||
* is an Ajax request. On an Ajax request, a "fragments" parameter will be extracted from the request in order to
|
||||
* determine which attributes to render from the current tiles view.
|
||||
* </p>
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author David Winterfeldt
|
||||
*/
|
||||
public class AjaxTilesView extends TilesView {
|
||||
|
||||
private static final String FRAGMENTS_PARAM = "fragments";
|
||||
|
||||
private TilesRequestContextFactory tilesRequestContextFactory;
|
||||
|
||||
private AjaxHandler ajaxHandler = new SpringJavascriptAjaxHandler();
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
tilesRequestContextFactory = new ServletTilesRequestContextFactory();
|
||||
tilesRequestContextFactory.init(new HashMap<String, String>());
|
||||
}
|
||||
|
||||
public AjaxHandler getAjaxHandler() {
|
||||
return ajaxHandler;
|
||||
}
|
||||
|
||||
public void setAjaxHandler(AjaxHandler ajaxHandler) {
|
||||
this.ajaxHandler = ajaxHandler;
|
||||
}
|
||||
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
|
||||
ServletContext servletContext = getServletContext();
|
||||
if (ajaxHandler.isAjaxRequest(request, response)) {
|
||||
|
||||
String[] fragmentsToRender = getRenderFragments(model, request, response);
|
||||
if (fragmentsToRender.length == 0) {
|
||||
logger.warn("An Ajax request was detected, but no fragments were specified to be re-rendered. "
|
||||
+ "Falling back to full page render. This can cause unpredictable results when processing "
|
||||
+ "the ajax response on the client.");
|
||||
super.renderMergedOutputModel(model, request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getCurrentContainer(request,
|
||||
servletContext);
|
||||
if (container == null) {
|
||||
throw new ServletException("Tiles container is not initialized. "
|
||||
+ "Have you added a TilesConfigurer to your web application context?");
|
||||
}
|
||||
|
||||
exposeModelAsRequestAttributes(model, request);
|
||||
JstlUtils.exposeLocalizationContext(new RequestContext(request, servletContext));
|
||||
|
||||
TilesRequestContext tilesRequestContext = tilesRequestContextFactory.createRequestContext(
|
||||
container.getApplicationContext(), new Object[] { request, response });
|
||||
Definition compositeDefinition = container.getDefinitionsFactory().getDefinition(getUrl(),
|
||||
tilesRequestContext);
|
||||
|
||||
Map<String, Attribute> flattenedAttributeMap = new HashMap<String, Attribute>();
|
||||
flattenAttributeMap(container, tilesRequestContext, flattenedAttributeMap, compositeDefinition, request,
|
||||
response);
|
||||
addRuntimeAttributes(container, flattenedAttributeMap, request, response);
|
||||
|
||||
if (fragmentsToRender.length > 1) {
|
||||
request.setAttribute(ServletUtil.FORCE_INCLUDE_ATTRIBUTE_NAME, true);
|
||||
}
|
||||
|
||||
for (String element : fragmentsToRender) {
|
||||
Attribute attributeToRender = flattenedAttributeMap.get(element);
|
||||
|
||||
if (attributeToRender == null) {
|
||||
throw new ServletException("No tiles attribute with a name of '" + element
|
||||
+ "' could be found for the current view: " + this);
|
||||
} else {
|
||||
container.startContext(request, response).inheritCascadedAttributes(compositeDefinition);
|
||||
container.render(attributeToRender, request, response);
|
||||
container.endContext(request, response);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.renderMergedOutputModel(model, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] getRenderFragments(Map<String, Object> model, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
String attrName = request.getParameter(FRAGMENTS_PARAM);
|
||||
String[] renderFragments = StringUtils.commaDelimitedListToStringArray(attrName);
|
||||
return StringUtils.trimArrayElements(renderFragments);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Iterate over all attributes in the given Tiles definition. Every attribute value that represents a template (i.e.
|
||||
* start with "/") or is a nested definition is added to a Map. The method class itself recursively to traverse
|
||||
* nested definitions.
|
||||
* </p>
|
||||
*
|
||||
* @param container the TilesContainer
|
||||
* @param requestContext the TilesRequestContext
|
||||
* @param resultMap the output Map where attributes of interest are added to.
|
||||
* @param compositeDefinition the definition to search for attributes of interest.
|
||||
* @param request the servlet request
|
||||
* @param response the servlet response
|
||||
*/
|
||||
protected void flattenAttributeMap(BasicTilesContainer container, TilesRequestContext requestContext,
|
||||
Map<String, Attribute> resultMap, Definition compositeDefinition, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
Iterator<String> iterator = compositeDefinition.getAttributeNames();
|
||||
while (iterator.hasNext()) {
|
||||
String attributeName = iterator.next();
|
||||
Attribute attribute = compositeDefinition.getAttribute(attributeName);
|
||||
if (attribute.getValue() == null || !(attribute.getValue() instanceof String)) {
|
||||
continue;
|
||||
}
|
||||
String value = attribute.getValue().toString();
|
||||
if (value.startsWith("/")) {
|
||||
resultMap.put(attributeName, attribute);
|
||||
} else if (container.isValidDefinition(value, new Object[] { request, response })) {
|
||||
resultMap.put(attributeName, attribute);
|
||||
Definition nestedDefinition = container.getDefinitionsFactory().getDefinition(value, requestContext);
|
||||
Assert.isTrue(nestedDefinition != compositeDefinition, "Circular nested definition: " + value);
|
||||
flattenAttributeMap(container, requestContext, resultMap, nestedDefinition, request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Iterate over dynamically added Tiles attributes (see "Runtime Composition" in the Tiles documentation) and add
|
||||
* them to the output Map passed as input.
|
||||
* </p>
|
||||
*
|
||||
* @param container the Tiles container
|
||||
* @param resultMap the output Map where attributes of interest are added to.
|
||||
* @param request the Servlet request
|
||||
* @param response the Servlet response
|
||||
*/
|
||||
protected void addRuntimeAttributes(BasicTilesContainer container, Map<String, Attribute> resultMap,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
AttributeContext attributeContext = container.getAttributeContext(new Object[] { request, response });
|
||||
Set<String> attributeNames = new HashSet<String>();
|
||||
if (attributeContext.getLocalAttributeNames() != null) {
|
||||
attributeNames.addAll(attributeContext.getLocalAttributeNames());
|
||||
}
|
||||
if (attributeContext.getCascadedAttributeNames() != null) {
|
||||
attributeNames.addAll(attributeContext.getCascadedAttributeNames());
|
||||
}
|
||||
for (String name : attributeNames) {
|
||||
Attribute attr = attributeContext.getAttribute(name);
|
||||
resultMap.put(name, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Ajax integration between Spring.js and the Tiles2 layout system.
|
||||
*/
|
||||
package org.springframework.js.ajax.tiles2;
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
package org.springframework.js.ajax.tiles2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.tiles.Attribute;
|
||||
import org.apache.tiles.AttributeContext;
|
||||
import org.apache.tiles.Definition;
|
||||
import org.apache.tiles.context.TilesRequestContext;
|
||||
import org.apache.tiles.context.TilesRequestContextFactory;
|
||||
import org.apache.tiles.impl.BasicTilesContainer;
|
||||
import org.apache.tiles.preparer.ViewPreparer;
|
||||
import org.apache.tiles.servlet.context.ServletTilesRequestContextFactory;
|
||||
import org.apache.tiles.servlet.context.ServletUtil;
|
||||
import org.springframework.js.ajax.SpringJavascriptAjaxHandler;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.support.RequestContext;
|
||||
import org.springframework.web.servlet.view.tiles2.TilesConfigurer;
|
||||
|
||||
public class AjaxTilesViewTests extends TestCase {
|
||||
|
||||
private AjaxTilesView ajaxTilesView;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
private MockHttpServletResponse response;
|
||||
private MockServletContext servletContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
servletContext = new MockServletContext("/org/springframework/js/ajax/tiles2/");
|
||||
request = new MockHttpServletRequest(servletContext);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
TilesConfigurer tc = new TilesConfigurer();
|
||||
tc.setDefinitions(new String[] { "tiles-definitions.xml" });
|
||||
tc.setValidateDefinitions(true);
|
||||
tc.setServletContext(servletContext);
|
||||
tc.setUseMutableTilesContainer(true);
|
||||
tc.afterPropertiesSet();
|
||||
|
||||
ajaxTilesView = new AjaxTilesView();
|
||||
}
|
||||
|
||||
private void setupStaticWebApplicationContext() {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
request.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
ajaxTilesView.setApplicationContext(wac);
|
||||
}
|
||||
|
||||
public void testFullPageRendering() throws Exception {
|
||||
setupStaticWebApplicationContext();
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/layout.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
public void testAjaxRequestNoFragments() throws Exception {
|
||||
setupStaticWebApplicationContext();
|
||||
request.addHeader("Accept", SpringJavascriptAjaxHandler.AJAX_ACCEPT_CONTENT_TYPE);
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/layout.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
public void testRenderFragment_Template() throws Exception {
|
||||
setupStaticWebApplicationContext();
|
||||
request.addHeader("Accept", SpringJavascriptAjaxHandler.AJAX_ACCEPT_CONTENT_TYPE);
|
||||
request.addParameter("fragments", "searchResults");
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/searchResults.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
public void testRenderFragment_Definition() throws Exception {
|
||||
setupStaticWebApplicationContext();
|
||||
request.addHeader("Accept", SpringJavascriptAjaxHandler.AJAX_ACCEPT_CONTENT_TYPE);
|
||||
request.addParameter("fragments", "body");
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/search.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
public void testRenderFragment_CascadedAttribute() throws Exception {
|
||||
setupStaticWebApplicationContext();
|
||||
request.addHeader("Accept", SpringJavascriptAjaxHandler.AJAX_ACCEPT_CONTENT_TYPE);
|
||||
request.addParameter("fragments", "searchNavigation");
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/searchNavigation.jsp", response.getForwardedUrl());
|
||||
}
|
||||
|
||||
public void testRenderFragment_InheritCascadedAttribute() throws Exception {
|
||||
BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getCurrentContainer(request, servletContext);
|
||||
ServletTilesRequestContextFactory tilesRequestContextFactory = new ServletTilesRequestContextFactory();
|
||||
tilesRequestContextFactory.init(new HashMap<String, String>());
|
||||
TilesRequestContext tilesRequestContext = tilesRequestContextFactory.createRequestContext(
|
||||
container.getApplicationContext(), new Object[] { request, response });
|
||||
Definition definition = container.getDefinitionsFactory().getDefinition("search.body", tilesRequestContext);
|
||||
definition.setPreparer("org.springframework.js.ajax.tiles2.AjaxTilesViewTests$AttributeTestingPreparer");
|
||||
|
||||
setupStaticWebApplicationContext();
|
||||
request.addHeader("Accept", SpringJavascriptAjaxHandler.AJAX_ACCEPT_CONTENT_TYPE);
|
||||
request.addParameter("fragments", "body");
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertTrue(AttributeTestingPreparer.invoked);
|
||||
}
|
||||
|
||||
public void testRenderFragment_DynamicAttribute() throws Exception {
|
||||
BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getCurrentContainer(request, servletContext);
|
||||
Object[] requestItems = new Object[] { request, response };
|
||||
AttributeContext attributeContext = container.startContext(requestItems);
|
||||
attributeContext.putAttribute("body", new Attribute("/WEB-INF/dynamicTemplate.jsp"));
|
||||
Map<String, Attribute> resultMap = new HashMap<String, Attribute>();
|
||||
ajaxTilesView.addRuntimeAttributes(container, resultMap, request, response);
|
||||
assertNotNull(resultMap.get("body"));
|
||||
assertEquals("/WEB-INF/dynamicTemplate.jsp", resultMap.get("body").toString());
|
||||
container.endContext(requestItems);
|
||||
}
|
||||
|
||||
public void testRenderFragment_Multiple() throws Exception {
|
||||
setupStaticWebApplicationContext();
|
||||
request.addHeader("Accept", SpringJavascriptAjaxHandler.AJAX_ACCEPT_CONTENT_TYPE);
|
||||
request.addParameter("fragments", "body,searchNavigation");
|
||||
ajaxTilesView.setUrl("search");
|
||||
ajaxTilesView.afterPropertiesSet();
|
||||
ajaxTilesView.renderMergedOutputModel(new HashMap<String, Object>(), request, response);
|
||||
assertTrue("Multiple fragments should result in include, not forward", response.getIncludedUrls().size() == 2);
|
||||
assertEquals("/WEB-INF/search.jsp", response.getIncludedUrls().get(0));
|
||||
assertEquals("/WEB-INF/searchNavigation.jsp", response.getIncludedUrls().get(1));
|
||||
}
|
||||
|
||||
public void testFlattenAttributeMap() throws Exception {
|
||||
TilesRequestContextFactory tilesRequestContextFactory = new ServletTilesRequestContextFactory();
|
||||
tilesRequestContextFactory.init(new HashMap<String, String>());
|
||||
BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getCurrentContainer(request, servletContext);
|
||||
TilesRequestContext tilesRequestContext = tilesRequestContextFactory.createRequestContext(
|
||||
container.getApplicationContext(), new Object[] { request, response });
|
||||
Definition compositeDefinition = container.getDefinitionsFactory().getDefinition("search", tilesRequestContext);
|
||||
Map<String, Attribute> resultMap = new HashMap<String, Attribute>();
|
||||
ajaxTilesView.flattenAttributeMap(container, tilesRequestContext, resultMap, compositeDefinition, request,
|
||||
response);
|
||||
assertNotNull(resultMap.get("body"));
|
||||
assertNotNull(resultMap.get("searchForm"));
|
||||
assertEquals("/WEB-INF/searchForm.jsp", resultMap.get("searchForm").toString());
|
||||
assertNotNull(resultMap.get("searchResults"));
|
||||
}
|
||||
|
||||
public void testGetRenderFragments() throws Exception {
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
request.setParameter("fragments", "f1,f2, f3");
|
||||
String[] fragments = ajaxTilesView.getRenderFragments(model, request, response);
|
||||
assertEquals("f1", fragments[0]);
|
||||
assertEquals("f2", fragments[1]);
|
||||
assertEquals("f3", fragments[2]);
|
||||
}
|
||||
|
||||
public static class AttributeTestingPreparer implements ViewPreparer {
|
||||
public static boolean invoked;
|
||||
|
||||
public void execute(TilesRequestContext tilesContext, AttributeContext attributeContext) {
|
||||
invoked = true;
|
||||
Assert.assertTrue(attributeContext.getAttribute("searchNavigation") != null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE tiles-definitions PUBLIC
|
||||
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
|
||||
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
|
||||
|
||||
<tiles-definitions>
|
||||
|
||||
<definition name="layout" template="/WEB-INF/layout.jsp"/>
|
||||
|
||||
<definition name="search" extends="layout">
|
||||
<put-attribute name="searchForm" value="Substituted Value" type="string" />
|
||||
<put-attribute name="body" value="search.body" />
|
||||
<put-attribute name="searchNavigation" value="/WEB-INF/searchNavigation.jsp" cascade="true" />
|
||||
</definition>
|
||||
|
||||
<definition name="search.body" template="/WEB-INF/search.jsp">
|
||||
<put-attribute name="searchForm" value="/WEB-INF/searchForm.jsp" />
|
||||
<put-attribute name="searchResults" value="/WEB-INF/searchResults.jsp" />
|
||||
</definition>
|
||||
|
||||
</tiles-definitions>
|
||||
@@ -1,83 +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.context.portlet;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.PortletURL;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
/**
|
||||
* Default flow URL handler for SWF 2.
|
||||
*
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class DefaultFlowUrlHandler implements FlowUrlHandler {
|
||||
|
||||
private static final String EXECUTION_ATTRIBUTE = "execution";
|
||||
|
||||
public String getFlowExecutionKey(PortletRequest request) {
|
||||
String flowExecutionKey = request.getParameter(EXECUTION_ATTRIBUTE);
|
||||
PortletSession session = request.getPortletSession(false);
|
||||
if (session != null) {
|
||||
if (flowExecutionKey == null && request instanceof RenderRequest) {
|
||||
flowExecutionKey = (String) session.getAttribute(EXECUTION_ATTRIBUTE);
|
||||
} else if (flowExecutionKey != null && request instanceof ActionRequest) {
|
||||
session.removeAttribute(EXECUTION_ATTRIBUTE);
|
||||
}
|
||||
}
|
||||
return flowExecutionKey;
|
||||
}
|
||||
|
||||
public void setFlowExecutionRenderParameter(String flowExecutionKey, ActionResponse response) {
|
||||
response.setRenderParameter(EXECUTION_ATTRIBUTE, flowExecutionKey);
|
||||
}
|
||||
|
||||
public void setFlowExecutionInSession(String flowExecutionKey, RenderRequest request) {
|
||||
setSessionAttribute(EXECUTION_ATTRIBUTE, flowExecutionKey, request);
|
||||
}
|
||||
|
||||
public void setFlowExecutionInSession(String flowExecutionKey, ResourceRequest request) {
|
||||
setSessionAttribute(EXECUTION_ATTRIBUTE, flowExecutionKey, request);
|
||||
}
|
||||
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, RenderResponse response) {
|
||||
return createFlowExecutionActionUrl(flowExecutionKey, response);
|
||||
}
|
||||
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, ResourceResponse response) {
|
||||
// Create Action URL by default
|
||||
return createFlowExecutionActionUrl(flowExecutionKey, response);
|
||||
}
|
||||
|
||||
private void setSessionAttribute(String name, String value, PortletRequest request) {
|
||||
PortletSession session = request.getPortletSession();
|
||||
session.setAttribute(name, value);
|
||||
}
|
||||
|
||||
private String createFlowExecutionActionUrl(String flowExecutionKey, MimeResponse response) {
|
||||
PortletURL url = response.createActionURL();
|
||||
url.setParameter(EXECUTION_ATTRIBUTE, flowExecutionKey);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +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.context.portlet;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
/**
|
||||
* A interface for parsing and generating flow URLs. Encapsulates a specific flow URL format.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public interface FlowUrlHandler {
|
||||
|
||||
/**
|
||||
* Extract the flow execution from the request.
|
||||
* @param request the request
|
||||
* @return the flow execution key, or null if no flow execution key is present
|
||||
*/
|
||||
public String getFlowExecutionKey(PortletRequest request);
|
||||
|
||||
/**
|
||||
* Set the flow execution key render parameter.
|
||||
* @param flowExecutionKey the key
|
||||
* @param response the action response
|
||||
*/
|
||||
public void setFlowExecutionRenderParameter(String flowExecutionKey, ActionResponse response);
|
||||
|
||||
/**
|
||||
* Set the flow execution key into the portlet session. This should only be used in a render request when the
|
||||
* portlet is started before any action requests are made
|
||||
* @param flowExecutionKey the key
|
||||
* @param request the request
|
||||
*/
|
||||
public void setFlowExecutionInSession(String flowExecutionKey, RenderRequest request);
|
||||
|
||||
/**
|
||||
* Set the flow execution key into the portlet session. This should only be used in a resource request when the
|
||||
* portlet is started before any action requests are made
|
||||
* @param flowExecutionKey the key
|
||||
* @param request the request
|
||||
*/
|
||||
public void setFlowExecutionInSession(String flowExecutionKey, ResourceRequest request);
|
||||
|
||||
/**
|
||||
* Creates a flow execution URL during a render phase suitable to invoke Web Flow in a portlet environment
|
||||
* @param flowId the flow id
|
||||
* @param flowExecutionKey the flow execution key
|
||||
* @param response the response
|
||||
* @return the execution url
|
||||
*/
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, RenderResponse response);
|
||||
|
||||
/**
|
||||
* Creates a flow execution URL during a resource phase suitable to invoke Web Flow in a portlet environment
|
||||
* @param flowId the flow id
|
||||
* @param flowExecutionKey the flow execution key
|
||||
* @param response the response
|
||||
* @return the execution url
|
||||
*/
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, ResourceResponse response);
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
|
||||
import org.springframework.binding.collection.SharedMap;
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Map backed by the Portlet context for accessing application scoped attributes.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletContextMap extends StringKeyedMapAdapter<Object> implements SharedMap<String, Object> {
|
||||
|
||||
/**
|
||||
* The wrapped portlet context.
|
||||
*/
|
||||
private PortletContext context;
|
||||
|
||||
/**
|
||||
* Create a map wrapping given portlet context.
|
||||
*/
|
||||
public PortletContextMap(PortletContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected Object getAttribute(String key) {
|
||||
return context.getAttribute(key);
|
||||
}
|
||||
|
||||
protected void setAttribute(String key, Object value) {
|
||||
context.setAttribute(key, value);
|
||||
}
|
||||
|
||||
protected void removeAttribute(String key) {
|
||||
context.removeAttribute(key);
|
||||
}
|
||||
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return CollectionUtils.toIterator(context.getAttributeNames());
|
||||
}
|
||||
|
||||
public Object getMutex() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.security.Principal;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.collection.LocalParameterMap;
|
||||
import org.springframework.webflow.core.collection.LocalSharedAttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.core.collection.ParameterMap;
|
||||
import org.springframework.webflow.core.collection.SharedAttributeMap;
|
||||
|
||||
/**
|
||||
* Provides contextual information about an portlet environment that has interacted with Spring Web Flow.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Erwin Vervaet
|
||||
* @author Jeremy Grelle
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletExternalContext implements ExternalContext {
|
||||
|
||||
protected static final short ACTION_PHASE = 1;
|
||||
|
||||
protected static final short RENDER_PHASE = 2;
|
||||
|
||||
protected static final short RESOURCE_PHASE = 3;
|
||||
|
||||
/**
|
||||
* The context.
|
||||
*/
|
||||
private PortletContext context;
|
||||
|
||||
/**
|
||||
* The request.
|
||||
*/
|
||||
private PortletRequest request;
|
||||
|
||||
/**
|
||||
* The response.
|
||||
*/
|
||||
private PortletResponse response;
|
||||
|
||||
/**
|
||||
* The portlet request phase: render, action, resource
|
||||
*/
|
||||
private short requestPhase;
|
||||
|
||||
/**
|
||||
* An accessor for the HTTP request parameter map.
|
||||
*/
|
||||
private ParameterMap requestParameterMap;
|
||||
|
||||
/**
|
||||
* An accessor for the HTTP request attribute map.
|
||||
*/
|
||||
private MutableAttributeMap<Object> requestMap;
|
||||
|
||||
/**
|
||||
* An accessor for the HTTP session map.
|
||||
*/
|
||||
private SharedAttributeMap<Object> sessionMap;
|
||||
|
||||
/**
|
||||
* An accessor for the servlet context application map.
|
||||
*/
|
||||
private SharedAttributeMap<Object> applicationMap;
|
||||
|
||||
/**
|
||||
* A flag indicating if the flow committed the response. Set to true by requesting an execution redirect, definition
|
||||
* redirect, external redirect, or by calling {@link ExternalContext#recordResponseComplete()}
|
||||
*/
|
||||
private boolean responseComplete;
|
||||
|
||||
/**
|
||||
* A flag indicating if a flow execution redirect has been requested.
|
||||
*/
|
||||
private boolean flowExecutionRedirectRequested;
|
||||
|
||||
/**
|
||||
* A string specifying the id of the flow to redirect to after request processing. If null, no flow definition
|
||||
* redirect has been requested.
|
||||
*/
|
||||
private String flowDefinitionRedirectFlowId;
|
||||
|
||||
/**
|
||||
* Input to pass the flow definition upon redirecting. May be null. Never set unless
|
||||
* {@link #flowDefinitionRedirectFlowId} has been set.
|
||||
*/
|
||||
private MutableAttributeMap<Object> flowDefinitionRedirectFlowInput;
|
||||
|
||||
/**
|
||||
* A string specifying an arbitrary
|
||||
*/
|
||||
private String externalRedirectUrl;
|
||||
|
||||
/**
|
||||
* The strategy for generating flow execution urls.
|
||||
*/
|
||||
private FlowUrlHandler flowUrlHandler;
|
||||
|
||||
/**
|
||||
* In the case where a redirect response is requested, this flag indicates if the redirect should be issued from a
|
||||
* popup dialog.
|
||||
*/
|
||||
private boolean redirectInPopup;
|
||||
|
||||
/**
|
||||
* Create a new external context wrapping given portlet action request and response and given portlet context.
|
||||
* @param context the portal context
|
||||
* @param request the portlet request
|
||||
* @param response the portlet response
|
||||
*/
|
||||
public PortletExternalContext(PortletContext context, PortletRequest request, PortletResponse response) {
|
||||
init(context, request, response, new DefaultFlowUrlHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new external context wrapping given portlet action request and response and given portlet context.
|
||||
* @param context the portal context
|
||||
* @param request the portlet request
|
||||
* @param response the portlet response
|
||||
* @param flowUrlHandler the flow url handler
|
||||
*/
|
||||
public PortletExternalContext(PortletContext context, PortletRequest request, PortletResponse response,
|
||||
FlowUrlHandler flowUrlHandler) {
|
||||
init(context, request, response, flowUrlHandler);
|
||||
}
|
||||
|
||||
// implementing external context
|
||||
|
||||
public String getContextPath() {
|
||||
return request.getContextPath();
|
||||
}
|
||||
|
||||
public ParameterMap getRequestParameterMap() {
|
||||
return requestParameterMap;
|
||||
}
|
||||
|
||||
public MutableAttributeMap<Object> getRequestMap() {
|
||||
return requestMap;
|
||||
}
|
||||
|
||||
public SharedAttributeMap<Object> getSessionMap() {
|
||||
return sessionMap;
|
||||
}
|
||||
|
||||
public SharedAttributeMap<Object> getGlobalSessionMap() {
|
||||
return getSessionMap();
|
||||
}
|
||||
|
||||
public SharedAttributeMap<Object> getApplicationMap() {
|
||||
return applicationMap;
|
||||
}
|
||||
|
||||
public Principal getCurrentUser() {
|
||||
return request.getUserPrincipal();
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return request.getLocale();
|
||||
}
|
||||
|
||||
public Object getNativeContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public Object getNativeRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public Object getNativeResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public boolean isAjaxRequest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getFlowExecutionUrl(String flowId, String flowExecutionKey) {
|
||||
if (isRenderPhase()) {
|
||||
return flowUrlHandler.createFlowExecutionUrl(flowId, flowExecutionKey, (RenderResponse) response);
|
||||
} else if (isResourcePhase()) {
|
||||
return flowUrlHandler.createFlowExecutionUrl(flowId, flowExecutionKey, (ResourceResponse) response);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"A flow execution action URL can only be obtained in a RenderRequest or a ResourceRequest");
|
||||
}
|
||||
}
|
||||
|
||||
public Writer getResponseWriter() throws IllegalStateException {
|
||||
assertResponseAllowed();
|
||||
try {
|
||||
return ((MimeResponse) response).getWriter();
|
||||
} catch (IOException e) {
|
||||
IllegalStateException ise = new IllegalStateException("Unable to access the response Writer");
|
||||
ise.initCause(e);
|
||||
throw ise;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isResponseAllowed() {
|
||||
return (isRenderPhase() || isResourcePhase()) && !responseComplete;
|
||||
}
|
||||
|
||||
public boolean isResponseComplete() {
|
||||
return responseComplete;
|
||||
}
|
||||
|
||||
public void recordResponseComplete() {
|
||||
responseComplete = true;
|
||||
}
|
||||
|
||||
public boolean isResponseCompleteFlowExecutionRedirect() {
|
||||
return flowExecutionRedirectRequested;
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() throws IllegalStateException {
|
||||
assertRedirectResponseAllowed();
|
||||
flowExecutionRedirectRequested = true;
|
||||
recordResponseComplete();
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap<?> input) throws IllegalStateException {
|
||||
assertRedirectResponseAllowed();
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = new LocalAttributeMap<Object>();
|
||||
if (input != null) {
|
||||
flowDefinitionRedirectFlowInput.putAll(input);
|
||||
}
|
||||
recordResponseComplete();
|
||||
}
|
||||
|
||||
public void requestExternalRedirect(String uri) throws IllegalStateException {
|
||||
assertRedirectResponseAllowed();
|
||||
externalRedirectUrl = uri;
|
||||
recordResponseComplete();
|
||||
}
|
||||
|
||||
public void requestRedirectInPopup() throws IllegalStateException {
|
||||
if (isRedirectRequested()) {
|
||||
redirectInPopup = true;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Only call requestRedirectInPopup after a redirect has been requested by calling requestFlowExecutionRedirect, requestFlowDefinitionRedirect, or requestExternalRedirect");
|
||||
}
|
||||
}
|
||||
|
||||
// implementation specific methods
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow execution redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean getFlowExecutionRedirectRequested() {
|
||||
return flowExecutionRedirectRequested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow definition redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean getFlowDefinitionRedirectRequested() {
|
||||
return flowDefinitionRedirectFlowId != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the flow definition to redirect to. Only set when {@link #getFlowDefinitionRedirectRequested()}
|
||||
* returns true.
|
||||
*/
|
||||
public String getFlowRedirectFlowId() {
|
||||
return flowDefinitionRedirectFlowId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input to pass the flow definition through the redirect. Only set when
|
||||
* {@link #getFlowDefinitionRedirectRequested()} returns true.
|
||||
*/
|
||||
public MutableAttributeMap<Object> getFlowRedirectFlowInput() {
|
||||
return flowDefinitionRedirectFlowInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if an external redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean getExternalRedirectRequested() {
|
||||
return externalRedirectUrl != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to redirect to. Only set if {@link #getExternalRedirectRequested()} returns true.
|
||||
*/
|
||||
public String getExternalRedirectUrl() {
|
||||
return externalRedirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a redirect response has been requested, indicates if the redirect should be issued from a popup dialog.
|
||||
*/
|
||||
public boolean getRedirectInPopup() {
|
||||
return redirectInPopup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current request phase is the action phase
|
||||
*/
|
||||
public boolean isActionPhase() {
|
||||
return requestPhase == ACTION_PHASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current request phase is the render phase
|
||||
*/
|
||||
public boolean isRenderPhase() {
|
||||
return requestPhase == RENDER_PHASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current request phase is the resource phase
|
||||
*/
|
||||
public boolean isResourcePhase() {
|
||||
return requestPhase == RESOURCE_PHASE;
|
||||
}
|
||||
|
||||
// private helpers
|
||||
|
||||
private void init(PortletContext context, PortletRequest request, PortletResponse response,
|
||||
FlowUrlHandler flowUrlHandler) {
|
||||
this.context = context;
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.requestParameterMap = new LocalParameterMap(new PortletRequestParameterMap(request));
|
||||
this.requestMap = new LocalAttributeMap<Object>(new PortletRequestMap(request));
|
||||
this.sessionMap = new LocalSharedAttributeMap<Object>(new PortletSessionMap(request));
|
||||
this.applicationMap = new LocalSharedAttributeMap<Object>(new PortletContextMap(context));
|
||||
this.flowUrlHandler = flowUrlHandler;
|
||||
if (request instanceof ActionRequest && response instanceof ActionResponse) {
|
||||
requestPhase = ACTION_PHASE;
|
||||
} else if (request instanceof RenderRequest && response instanceof RenderResponse) {
|
||||
requestPhase = RENDER_PHASE;
|
||||
} else if (request instanceof ResourceRequest && response instanceof ResourceResponse) {
|
||||
requestPhase = RESOURCE_PHASE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown portlet phase, expected: action, render, or resource");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertResponseAllowed() throws IllegalStateException {
|
||||
if (!isRenderPhase() && !isResourcePhase()) {
|
||||
throw new IllegalStateException(
|
||||
"A response is not allowed because the current PortletRequest is neither a RenderRequest nor a ResourceRequest");
|
||||
}
|
||||
if (responseComplete) {
|
||||
throw new IllegalStateException(
|
||||
"A response is not allowed because recordResponseComplete() has already been called on this ExternalContext");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertRedirectResponseAllowed() throws IllegalStateException {
|
||||
if (!isActionPhase()) {
|
||||
throw new IllegalStateException(
|
||||
"A redirect is not allowed because the current PortletRequest is not a ActionRequest");
|
||||
}
|
||||
if (responseComplete) {
|
||||
throw new IllegalStateException(
|
||||
"A redirect is not allowed because a response has already been completed on this ExternalContext");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRedirectRequested() {
|
||||
return getFlowExecutionRedirectRequested() || getFlowDefinitionRedirectRequested()
|
||||
|| getExternalRedirectRequested();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Map backed by the Portlet request attribute map for accessing request local attributes.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletRequestMap extends StringKeyedMapAdapter<Object> {
|
||||
|
||||
/**
|
||||
* The wrapped portlet request.
|
||||
*/
|
||||
private PortletRequest request;
|
||||
|
||||
/**
|
||||
* Create a new map wrapping the attributes of given request.
|
||||
*/
|
||||
public PortletRequestMap(PortletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
protected Object getAttribute(String key) {
|
||||
return request.getAttribute(key);
|
||||
}
|
||||
|
||||
protected void setAttribute(String key, Object value) {
|
||||
request.setAttribute(key, value);
|
||||
}
|
||||
|
||||
protected void removeAttribute(String key) {
|
||||
request.removeAttribute(key);
|
||||
}
|
||||
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return CollectionUtils.toIterator(request.getAttributeNames());
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2014 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CompositeIterator;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.portlet.multipart.MultipartActionRequest;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Map backed by the Portlet request parameter map for accessing request parameters. Also provides support for
|
||||
* multi-part requests, providing transparent access to the request "fileMap" as a request parameter entry.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletRequestParameterMap extends StringKeyedMapAdapter<Object> {
|
||||
|
||||
/**
|
||||
* The wrapped Portlet request.
|
||||
*/
|
||||
private PortletRequest request;
|
||||
|
||||
/**
|
||||
* Create a new map wrapping the parameters of given request.
|
||||
*/
|
||||
public PortletRequestParameterMap(PortletRequest request) {
|
||||
Assert.notNull(request, "The portlet request is required");
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
protected Object getAttribute(String key) {
|
||||
if (request instanceof MultipartActionRequest) {
|
||||
MultipartActionRequest multipartRequest = (MultipartActionRequest) request;
|
||||
List<MultipartFile> data = multipartRequest.getMultiFileMap().get(key);
|
||||
if (data != null && data.size() > 0) {
|
||||
if (data.size() == 1) {
|
||||
return data.get(0);
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
String[] parameters = request.getParameterValues(key);
|
||||
if (parameters == null) {
|
||||
return null;
|
||||
} else if (parameters.length == 1) {
|
||||
return parameters[0];
|
||||
} else {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setAttribute(String key, Object value) {
|
||||
throw new UnsupportedOperationException("PortletRequest parameter maps are immutable");
|
||||
}
|
||||
|
||||
protected void removeAttribute(String key) {
|
||||
throw new UnsupportedOperationException("PortletRequest parameter maps are immutable");
|
||||
}
|
||||
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
if (request instanceof MultipartActionRequest) {
|
||||
MultipartActionRequest multipartRequest = (MultipartActionRequest) request;
|
||||
CompositeIterator<String> iterator = new CompositeIterator<String>();
|
||||
iterator.add(multipartRequest.getFileMap().keySet().iterator());
|
||||
iterator.add(CollectionUtils.toIterator(request.getParameterNames()));
|
||||
return iterator;
|
||||
} else {
|
||||
return CollectionUtils.toIterator(request.getParameterNames());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletSession;
|
||||
|
||||
import org.springframework.binding.collection.SharedMap;
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
import org.springframework.webflow.context.web.HttpSessionMapBindingListener;
|
||||
import org.springframework.webflow.core.collection.AttributeMapBindingListener;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* A Shared Map backed by the Portlet session, for accessing session scoped attributes.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletSessionMap extends StringKeyedMapAdapter<Object> implements SharedMap<String, Object> {
|
||||
|
||||
/**
|
||||
* The wrapped portlet request, providing access to the session.
|
||||
*/
|
||||
private PortletRequest request;
|
||||
|
||||
/**
|
||||
* Create a map wrapping the session of given request.
|
||||
*/
|
||||
public PortletSessionMap(PortletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper to get the portlet session associated with the wrapped request, or null if there is no such
|
||||
* session.
|
||||
* <p>
|
||||
* Note that this method will not force session creation.
|
||||
*/
|
||||
private PortletSession getSession() {
|
||||
return request.getPortletSession(false);
|
||||
}
|
||||
|
||||
protected Object getAttribute(String key) {
|
||||
PortletSession session = getSession();
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
Object value = session.getAttribute(key);
|
||||
if (value instanceof HttpSessionMapBindingListener) {
|
||||
// unwrap
|
||||
return ((HttpSessionMapBindingListener) value).getListener();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setAttribute(String key, Object value) {
|
||||
// force session creation
|
||||
PortletSession session = request.getPortletSession(true);
|
||||
if (value instanceof AttributeMapBindingListener) {
|
||||
// wrap
|
||||
session.setAttribute(key, new HttpSessionMapBindingListener((AttributeMapBindingListener) value, this));
|
||||
} else {
|
||||
session.setAttribute(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeAttribute(String key) {
|
||||
PortletSession session = getSession();
|
||||
if (session != null) {
|
||||
session.removeAttribute(key);
|
||||
}
|
||||
}
|
||||
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
PortletSession session = getSession();
|
||||
return session == null ? CollectionUtils.<String> emptyIterator() : CollectionUtils.toIterator(session
|
||||
.getAttributeNames());
|
||||
}
|
||||
|
||||
public Object getMutex() {
|
||||
// force session creation
|
||||
PortletSession session = request.getPortletSession(true);
|
||||
Object mutex = session.getAttribute(WebUtils.SESSION_MUTEX_ATTRIBUTE);
|
||||
return mutex != null ? mutex : session;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the PortletExternalContext implementation for calling into Web Flow from a Portlet.
|
||||
*/
|
||||
package org.springframework.webflow.context.portlet;
|
||||
|
||||
@@ -19,7 +19,6 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.mvc.servlet.FlowController;
|
||||
|
||||
@@ -68,7 +67,30 @@ public class FilenameFlowUrlHandler extends DefaultFlowUrlHandler {
|
||||
}
|
||||
|
||||
public String getFlowId(HttpServletRequest request) {
|
||||
return WebUtils.extractFilenameFromUrlPath(urlPathHelper.getLookupPathForRequest(request));
|
||||
return extractFilenameFromUrlPath(urlPathHelper.getLookupPathForRequest(request));
|
||||
}
|
||||
|
||||
public static String extractFilenameFromUrlPath(String urlPath) {
|
||||
String filename = extractFullFilenameFromUrlPath(urlPath);
|
||||
int dotIndex = filename.lastIndexOf('.');
|
||||
if (dotIndex != -1) {
|
||||
filename = filename.substring(0, dotIndex);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
public static String extractFullFilenameFromUrlPath(String urlPath) {
|
||||
int end = urlPath.indexOf('?');
|
||||
if (end == -1) {
|
||||
end = urlPath.indexOf('#');
|
||||
if (end == -1) {
|
||||
end = urlPath.length();
|
||||
}
|
||||
}
|
||||
int begin = urlPath.lastIndexOf('/', end) + 1;
|
||||
int paramIndex = urlPath.indexOf(';', begin);
|
||||
end = (paramIndex != -1 && paramIndex < end ? paramIndex : end);
|
||||
return urlPath.substring(begin, end);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
package org.springframework.webflow.mvc.builder;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.portlet.context.ConfigurablePortletApplicationContext;
|
||||
|
||||
/**
|
||||
* Supported Spring Web MVC environments.
|
||||
@@ -43,18 +41,11 @@ public enum MvcEnvironment {
|
||||
* @return the web environment the context is running in, or null if not running in a web environment
|
||||
*/
|
||||
public static MvcEnvironment environmentFor(ApplicationContext applicationContext) {
|
||||
if (ClassUtils.isPresent("javax.portlet.PortletContext", MvcEnvironment.class.getClassLoader()) && isPortletApplicationContext(applicationContext)) {
|
||||
return MvcEnvironment.PORTLET;
|
||||
} else if (applicationContext instanceof WebApplicationContext) {
|
||||
if (applicationContext instanceof WebApplicationContext) {
|
||||
return MvcEnvironment.SERVLET;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPortletApplicationContext(ApplicationContext applicationContext) {
|
||||
return ClassUtils.isPresent("org.springframework.web.portlet.context.ConfigurablePortletApplicationContext", MvcEnvironment.class.getClassLoader())
|
||||
&& applicationContext instanceof ConfigurablePortletApplicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
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.AbstractMvcViewFactory;
|
||||
import org.springframework.webflow.mvc.view.FlowViewResolver;
|
||||
@@ -52,7 +51,6 @@ import org.springframework.webflow.validation.WebFlowMessageCodesResolver;
|
||||
* pre-existing Spring MVC {@link ViewResolver view resolvers}.
|
||||
*
|
||||
* @see ServletMvcViewFactory
|
||||
* @see PortletMvcViewFactory
|
||||
* @see FlowResourceFlowViewResolver
|
||||
* @see DelegatingFlowViewResolver
|
||||
*
|
||||
@@ -198,9 +196,6 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
if (environment == MvcEnvironment.SERVLET) {
|
||||
return new ServletMvcViewFactory(viewId, flowViewResolver, expressionParser, conversionService,
|
||||
binderConfiguration, messageCodesResolver);
|
||||
} else if (environment == MvcEnvironment.PORTLET) {
|
||||
return new PortletMvcViewFactory(viewId, flowViewResolver, expressionParser, conversionService,
|
||||
binderConfiguration, messageCodesResolver);
|
||||
} else {
|
||||
throw new IllegalStateException("Web MVC Environment " + environment + " not supported ");
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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 javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import org.springframework.webflow.core.FlowException;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionOutcome;
|
||||
|
||||
/**
|
||||
* Trivial flow handler base class that simply returns null for all operations. Subclasses should extend and override
|
||||
* which operations they need.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class AbstractFlowHandler implements FlowHandler {
|
||||
|
||||
public String getFlowId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MutableAttributeMap<Object> createExecutionInputMap(RenderRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MutableAttributeMap<Object> createResourceExecutionInputMap(ResourceRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean handleExecutionOutcome(FlowExecutionOutcome outcome, ActionRequest request, ActionResponse response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String handleException(FlowException e, PortletRequest request, RenderResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String handleException(FlowException e, RenderRequest request, RenderResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String handleResourceException(FlowException e, ResourceRequest request, ResourceResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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 javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletModeException;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import org.springframework.webflow.core.FlowException;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionOutcome;
|
||||
|
||||
/**
|
||||
* A controller helper used for customizing access to a <i>single</i> flow definition in a Portlet environment. This
|
||||
* helper is used to:
|
||||
* <ol>
|
||||
* <li>Launch executions of that flow with data in the execution input map
|
||||
* <li>Handle outcomes reached by that flow in a custom manner
|
||||
* <li>Handle unhandled exceptions dealing with that flow in a custom manner
|
||||
* </ol>
|
||||
* Such a handler can be visually thought of as a "flow reference" on a Garrett IA diagram. It holds a reference to the
|
||||
* flow id to launch, how to provision its input, how to process its outcomes, and how to handle uncaught exceptions.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public interface FlowHandler {
|
||||
|
||||
/**
|
||||
* Returns the id of the flow handled by this handler. Used by a Controller to load the flow definition.
|
||||
* @return the flow id
|
||||
*/
|
||||
public String getFlowId();
|
||||
|
||||
/**
|
||||
* Creates the flow execution input map to pass to a new instance of the flow being started in a render request.
|
||||
* Used by a Controller to launch the flow execution with the correct input.
|
||||
* @param request the current request
|
||||
* @return the input map
|
||||
*/
|
||||
public MutableAttributeMap<Object> createExecutionInputMap(RenderRequest request);
|
||||
|
||||
/**
|
||||
* Creates the flow execution input map to pass to a new instance of the flow being started in a resource request.
|
||||
* Used by a Controller to launch the flow execution with the correct input.
|
||||
* @param request the current request
|
||||
* @return the input map
|
||||
*/
|
||||
public MutableAttributeMap<Object> createResourceExecutionInputMap(ResourceRequest request);
|
||||
|
||||
/**
|
||||
* Handles a specific flow execution outcome. Used to change portlet modes after the flow ends.
|
||||
* @param outcome the outcome that was reached
|
||||
* @param request the current action request
|
||||
* @param response the current action response
|
||||
* @return whether this outcome was handled, or whether the caller should handle it
|
||||
* @throws PortletModeException if this handler tries to change the portlet mode to something invalid
|
||||
*/
|
||||
public boolean handleExecutionOutcome(FlowExecutionOutcome outcome, ActionRequest request, ActionResponse response)
|
||||
throws PortletModeException;
|
||||
|
||||
/**
|
||||
* Handles a flow exception that was not handled by the Web Flow system in render request. Used by a Controller to
|
||||
* handle a specific type of exception dealing with this flow in a custom manner.
|
||||
* @param e the unhandled exception originating from Spring Web Flow. May be thrown by the flow execution itself or
|
||||
* the flow executor system if no execution could be restored.
|
||||
* @param request the current request
|
||||
* @param response the current response
|
||||
* @return the name of a specific error view to render, or <code>null</code> if the exception should be handled by
|
||||
* the caller
|
||||
*/
|
||||
public String handleException(FlowException e, RenderRequest request, RenderResponse response);
|
||||
|
||||
/**
|
||||
* Handles a flow exception that was not handled by the Web Flow system in a resource request. Used by a Controller
|
||||
* to handle a specific type of exception dealing with this flow in a custom manner.
|
||||
* @param e the unhandled exception originating from Spring Web Flow. May be thrown by the flow execution itself or
|
||||
* the flow executor system if no execution could be restored.
|
||||
* @param request the current request
|
||||
* @param response the current response
|
||||
* @return the name of a specific error view to render, or <code>null</code> if the exception should be handled by
|
||||
* the caller
|
||||
*/
|
||||
public String handleResourceException(FlowException e, ResourceRequest request, ResourceResponse response);
|
||||
|
||||
}
|
||||
@@ -1,330 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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 java.util.Map;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.EventRequest;
|
||||
import javax.portlet.EventResponse;
|
||||
import javax.portlet.PortletModeException;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.portlet.HandlerAdapter;
|
||||
import org.springframework.web.portlet.ModelAndView;
|
||||
import org.springframework.web.portlet.handler.PortletContentGenerator;
|
||||
import org.springframework.webflow.context.portlet.DefaultFlowUrlHandler;
|
||||
import org.springframework.webflow.context.portlet.FlowUrlHandler;
|
||||
import org.springframework.webflow.context.portlet.PortletExternalContext;
|
||||
import org.springframework.webflow.core.FlowException;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionOutcome;
|
||||
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
|
||||
import org.springframework.webflow.executor.FlowExecutionResult;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
|
||||
/**
|
||||
* A custom MVC HandlerAdapter that encapsulates the generic workflow associated with executing flows in a Portlet
|
||||
* environment. Delegates to mapped {@link FlowHandler flow handlers} to manage the interaction with executions of
|
||||
* specific flow definitions.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class FlowHandlerAdapter extends PortletContentGenerator implements HandlerAdapter, InitializingBean {
|
||||
|
||||
private static final String ACTION_REQUEST_FLOW_EXCEPTION_ATTRIBUTE = "actionRequestFlowException";
|
||||
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
private FlowUrlHandler flowUrlHandler;
|
||||
|
||||
/**
|
||||
* Creates a new flow handler adapter.
|
||||
* @see #setFlowExecutor(FlowExecutor)
|
||||
* @see #setFlowUrlHandler(FlowUrlHandler)
|
||||
* @see #afterPropertiesSet()
|
||||
*/
|
||||
public FlowHandlerAdapter() {
|
||||
// prevent caching of flow pages by default
|
||||
setCacheSeconds(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the central service for executing flows. Required.
|
||||
*/
|
||||
public FlowExecutor getFlowExecutor() {
|
||||
return flowExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the central service for executing flows. Required.
|
||||
* @param flowExecutor
|
||||
*/
|
||||
public void setFlowExecutor(FlowExecutor flowExecutor) {
|
||||
this.flowExecutor = flowExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flow url handler.
|
||||
*/
|
||||
public FlowUrlHandler getFlowUrlHandler() {
|
||||
return flowUrlHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flow url handler
|
||||
* @param urlHandler the flow url handler
|
||||
*/
|
||||
public void setFlowUrlHandler(FlowUrlHandler urlHandler) {
|
||||
this.flowUrlHandler = urlHandler;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(flowExecutor, "The FlowExecutor to execute flows is required");
|
||||
if (flowUrlHandler == null) {
|
||||
flowUrlHandler = new DefaultFlowUrlHandler();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supports(Object handler) {
|
||||
return handler instanceof FlowHandler;
|
||||
}
|
||||
|
||||
public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object handler) throws Exception {
|
||||
FlowHandler flowHandler = (FlowHandler) handler;
|
||||
checkAndPrepare(request, response);
|
||||
populateConveniencePortletProperties(request);
|
||||
FlowException e = clearActionRequestFlowException(request, response, flowHandler);
|
||||
if (e != null) {
|
||||
return handleException(e, flowHandler, request, response);
|
||||
}
|
||||
String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request);
|
||||
if (flowExecutionKey != null) {
|
||||
return resumeFlowRender(request, response, flowHandler, flowExecutionKey);
|
||||
} else {
|
||||
MutableAttributeMap<Object> input = flowHandler.createExecutionInputMap(request);
|
||||
if (input == null) {
|
||||
input = defaultCreateFlowExecutionInputMap(request);
|
||||
}
|
||||
return startFlowRender(flowHandler, input, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
public ModelAndView handleResource(ResourceRequest request, ResourceResponse response, Object handler)
|
||||
throws Exception {
|
||||
FlowHandler flowHandler = (FlowHandler) handler;
|
||||
checkAndPrepare(request, response);
|
||||
populateConveniencePortletProperties(request);
|
||||
String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request);
|
||||
if (flowExecutionKey != null) {
|
||||
return resumeFlowResource(request, response, flowHandler, flowExecutionKey);
|
||||
} else {
|
||||
MutableAttributeMap<Object> input = flowHandler.createResourceExecutionInputMap(request);
|
||||
if (input == null) {
|
||||
input = defaultCreateFlowExecutionInputMap(request);
|
||||
}
|
||||
return startFlowResource(flowHandler, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleAction(ActionRequest request, ActionResponse response, Object handler) throws Exception {
|
||||
FlowHandler flowHandler = (FlowHandler) handler;
|
||||
populateConveniencePortletProperties(request);
|
||||
String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request);
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
try {
|
||||
FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context);
|
||||
if (result.isPaused()) {
|
||||
flowUrlHandler.setFlowExecutionRenderParameter(result.getPausedKey(), response);
|
||||
} else if (result.isEnded()) {
|
||||
handleFlowExecutionOutcome(result.getOutcome(), flowHandler, request, response);
|
||||
} else {
|
||||
throw new IllegalStateException("Execution result should have been one of [paused] or [ended]");
|
||||
}
|
||||
} catch (FlowException e) {
|
||||
request.getPortletSession().setAttribute(ACTION_REQUEST_FLOW_EXCEPTION_ATTRIBUTE, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleEvent(EventRequest request, EventResponse response, Object handler) throws Exception {
|
||||
// keep render params
|
||||
response.setRenderParameters(request);
|
||||
}
|
||||
|
||||
// subclassing hooks
|
||||
|
||||
protected void populateConveniencePortletProperties(PortletRequest request) {
|
||||
request.setAttribute("portletMode", request.getPortletMode().toString());
|
||||
request.setAttribute("portletWindowState", request.getWindowState().toString());
|
||||
}
|
||||
|
||||
protected PortletExternalContext createPortletExternalContext(PortletRequest request, PortletResponse response) {
|
||||
return new PortletExternalContext(getPortletContext(), request, response);
|
||||
}
|
||||
|
||||
protected MutableAttributeMap<Object> defaultCreateFlowExecutionInputMap(PortletRequest request) {
|
||||
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||
if (parameterMap.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
LocalAttributeMap<Object> inputMap = new LocalAttributeMap<Object>();
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
String[] values = entry.getValue();
|
||||
inputMap.put(entry.getKey(), values.length == 1 ? values[0] : values);
|
||||
}
|
||||
return inputMap;
|
||||
}
|
||||
|
||||
protected void defaultHandleExecutionOutcome(FlowExecutionOutcome outcome, FlowHandler flowHandler,
|
||||
ActionRequest request, ActionResponse response) throws PortletModeException {
|
||||
}
|
||||
|
||||
protected ModelAndView defaultHandleException(FlowHandler flowHandler, FlowException e, RenderRequest request,
|
||||
RenderResponse response) {
|
||||
if (e instanceof NoSuchFlowExecutionException) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Starting a new execution of previously ended flow '" + flowHandler.getFlowId() + "'");
|
||||
}
|
||||
// by default, attempt to restart the flow
|
||||
try {
|
||||
startFlowRender(flowHandler, null, request, response);
|
||||
return null;
|
||||
} catch (FlowException flowException) {
|
||||
return handleException(flowException, flowHandler, request, response);
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected ModelAndView defaultHandleResourceException(FlowHandler flowHandler, FlowException e,
|
||||
ResourceRequest request, ResourceResponse response) {
|
||||
if (e instanceof NoSuchFlowExecutionException) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Starting a new execution of previously ended flow '" + flowHandler.getFlowId() + "'");
|
||||
}
|
||||
// by default, attempt to restart the flow
|
||||
return startFlowResource(flowHandler, request, response);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
private ModelAndView handleException(FlowException e, FlowHandler flowHandler, RenderRequest request,
|
||||
RenderResponse response) {
|
||||
String view = flowHandler.handleException(e, request, response);
|
||||
if (view != null) {
|
||||
return new ModelAndView(view);
|
||||
} else {
|
||||
return defaultHandleException(flowHandler, e, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView handleResourceException(FlowException e, FlowHandler flowHandler, ResourceRequest request,
|
||||
ResourceResponse response) {
|
||||
String view = flowHandler.handleResourceException(e, request, response);
|
||||
if (view != null) {
|
||||
return new ModelAndView(view);
|
||||
} else {
|
||||
return defaultHandleResourceException(flowHandler, e, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFlowExecutionOutcome(FlowExecutionOutcome outcome, FlowHandler flowHandler,
|
||||
ActionRequest request, ActionResponse response) throws PortletModeException {
|
||||
boolean handled = flowHandler.handleExecutionOutcome(outcome, request, response);
|
||||
if (!handled) {
|
||||
defaultHandleExecutionOutcome(outcome, flowHandler, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView startFlowRender(FlowHandler flowHandler, MutableAttributeMap<Object> input,
|
||||
RenderRequest request, RenderResponse response) {
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
try {
|
||||
FlowExecutionResult result = flowExecutor.launchExecution(flowHandler.getFlowId(), input, context);
|
||||
if (result.isPaused()) {
|
||||
flowUrlHandler.setFlowExecutionInSession(result.getPausedKey(), request);
|
||||
}
|
||||
return null;
|
||||
} catch (FlowException flowEx) {
|
||||
return handleException(flowEx, flowHandler, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView startFlowResource(FlowHandler flowHandler, ResourceRequest request, ResourceResponse response) {
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
try {
|
||||
FlowExecutionResult result = flowExecutor.launchExecution(flowHandler.getFlowId(), null, context);
|
||||
if (result.isPaused()) {
|
||||
flowUrlHandler.setFlowExecutionInSession(result.getPausedKey(), request);
|
||||
}
|
||||
return null;
|
||||
} catch (FlowException flowEx) {
|
||||
return handleResourceException(flowEx, flowHandler, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView resumeFlowRender(RenderRequest request, RenderResponse response, FlowHandler flowHandler,
|
||||
String flowExecutionKey) {
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
try {
|
||||
flowExecutor.resumeExecution(flowExecutionKey, context);
|
||||
return null;
|
||||
} catch (FlowException e) {
|
||||
return handleException(e, flowHandler, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView resumeFlowResource(ResourceRequest request, ResourceResponse response,
|
||||
FlowHandler flowHandler, String flowExecutionKey) {
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
try {
|
||||
flowExecutor.resumeExecution(flowExecutionKey, context);
|
||||
return null;
|
||||
} catch (FlowException e) {
|
||||
return handleResourceException(e, flowHandler, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private FlowException clearActionRequestFlowException(RenderRequest request, RenderResponse response,
|
||||
FlowHandler flowHandler) {
|
||||
PortletSession session = request.getPortletSession(false);
|
||||
if (session != null) {
|
||||
FlowException e = (FlowException) session.getAttribute(ACTION_REQUEST_FLOW_EXCEPTION_ATTRIBUTE);
|
||||
if (e != null) {
|
||||
session.removeAttribute(ACTION_REQUEST_FLOW_EXCEPTION_ATTRIBUTE);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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 java.util.Map;
|
||||
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.springframework.web.portlet.DispatcherPortlet;
|
||||
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.AbstractMvcView;
|
||||
|
||||
/**
|
||||
* The Spring Web Portlet MVC view implementation.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletMvcView extends AbstractMvcView {
|
||||
|
||||
/**
|
||||
* Creates a new Portlet MVC view.
|
||||
* @param view the view to render
|
||||
* @param context the current flow request context
|
||||
*/
|
||||
public PortletMvcView(org.springframework.web.servlet.View view, RequestContext context) {
|
||||
super(view, context);
|
||||
}
|
||||
|
||||
protected void doRender(Map<String, ?> model) throws Exception {
|
||||
RequestContext context = getRequestContext();
|
||||
ExternalContext externalContext = context.getExternalContext();
|
||||
View view = getView();
|
||||
PortletContext portletContext = (PortletContext) externalContext.getNativeContext();
|
||||
PortletRequest request = (PortletRequest) externalContext.getNativeRequest();
|
||||
MimeResponse response = (MimeResponse) externalContext.getNativeResponse();
|
||||
if (response.getContentType() == null) {
|
||||
// No Portlet content type specified yet -> use the view-determined type.
|
||||
// (The Portlet spec requires the content type to be set on the RenderResponse)
|
||||
String contentType = view.getContentType();
|
||||
if (contentType != null) {
|
||||
response.setContentType(contentType);
|
||||
}
|
||||
}
|
||||
request.setAttribute(ViewRendererServlet.VIEW_ATTRIBUTE, view);
|
||||
request.setAttribute(ViewRendererServlet.MODEL_ATTRIBUTE, model);
|
||||
request.setAttribute(org.springframework.web.servlet.support.RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
|
||||
context.getActiveFlow().getApplicationContext());
|
||||
portletContext.getRequestDispatcher(DispatcherPortlet.DEFAULT_VIEW_RENDERER_URL).include(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +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.portlet;
|
||||
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
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
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletMvcViewFactory extends AbstractMvcViewFactory {
|
||||
|
||||
/**
|
||||
* Creates a new portlet-based MVC view factory.
|
||||
* @param viewId the id of the view as an expression
|
||||
* @param viewResolver the resolver to resolve the View implementation
|
||||
* @param expressionParser the expression parser
|
||||
* @param conversionService the conversion service
|
||||
* @param binderConfiguration the model binding configuration
|
||||
* @param messageCodesResolver
|
||||
*/
|
||||
public PortletMvcViewFactory(Expression viewId, FlowViewResolver viewResolver, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration,
|
||||
MessageCodesResolver messageCodesResolver) {
|
||||
super(viewId, viewResolver, expressionParser, conversionService, binderConfiguration, messageCodesResolver);
|
||||
}
|
||||
|
||||
protected AbstractMvcView createMvcView(View view, RequestContext context) {
|
||||
return new PortletMvcView(view, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The integration between Web Flow and Spring Portlet MVC, Spring's portlet application platform.
|
||||
*/
|
||||
package org.springframework.webflow.mvc.portlet;
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.js.ajax.tiles2.AjaxTilesView;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.View;
|
||||
|
||||
/**
|
||||
* Tiles view implementation that is able to handle partial rendering for Spring
|
||||
* Javascript Ajax requests.
|
||||
*
|
||||
* <p>This implementation uses the {@link org.springframework.js.ajax.SpringJavascriptAjaxHandler}
|
||||
* by default to determine whether the current request is an Ajax request. On an
|
||||
* Ajax request for an active flow execution, the fragments set by a {@code <render>}
|
||||
* action will be respected, otherwise the parent
|
||||
* {@link org.springframework.js.ajax.tiles2.AjaxTilesView}'s resolution algorithm
|
||||
* will be applied.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowAjaxTilesView extends AjaxTilesView {
|
||||
|
||||
|
||||
protected String[] getRenderFragments(Map<String, Object> model, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
|
||||
RequestContext context = RequestContextHolder.getRequestContext();
|
||||
if (context == null) {
|
||||
return super.getRenderFragments(model, request, response);
|
||||
}
|
||||
|
||||
String[] fragments = (String[]) context.getFlashScope().get(View.RENDER_FRAGMENTS_ATTRIBUTE);
|
||||
if (fragments == null) {
|
||||
return super.getRenderFragments(model, request, response);
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.hibernate.FlushMode;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.orm.hibernate4.SessionHolder;
|
||||
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
@@ -250,16 +250,7 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
||||
}
|
||||
|
||||
private void bind(Session session) {
|
||||
Object sessionHolder;
|
||||
if (hibernate3Present) {
|
||||
sessionHolder = new org.springframework.orm.hibernate3.SessionHolder(session);
|
||||
}
|
||||
else if (hibernate5Present) {
|
||||
sessionHolder = new org.springframework.orm.hibernate5.SessionHolder(session);
|
||||
}
|
||||
else {
|
||||
sessionHolder = new SessionHolder(session);
|
||||
}
|
||||
Object sessionHolder = new org.springframework.orm.hibernate5.SessionHolder(session);
|
||||
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package org.springframework.webflow.context.portlet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockActionRequest;
|
||||
import org.springframework.mock.web.portlet.MockActionResponse;
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
import org.springframework.mock.web.portlet.MockRenderRequest;
|
||||
import org.springframework.mock.web.portlet.MockRenderResponse;
|
||||
|
||||
public class DefaultFlowUrlHandlerTests extends TestCase {
|
||||
private DefaultFlowUrlHandler urlHandler = new DefaultFlowUrlHandler();
|
||||
private MockPortletRequest request = new MockPortletRequest();
|
||||
private MockActionRequest actionRequest = new MockActionRequest();
|
||||
private MockRenderRequest renderRequest = new MockRenderRequest();
|
||||
private MockActionResponse actionResponse = new MockActionResponse();
|
||||
private MockRenderResponse renderResponse = new MockRenderResponse();
|
||||
|
||||
public void testGetFlowExecutionKey() {
|
||||
request.addParameter("execution", "12345");
|
||||
assertEquals("12345", urlHandler.getFlowExecutionKey(request));
|
||||
}
|
||||
|
||||
public void testSetFlowExecutionRenderParameter() {
|
||||
urlHandler.setFlowExecutionRenderParameter("12345", actionResponse);
|
||||
assertEquals("12345", actionResponse.getRenderParameter("execution"));
|
||||
}
|
||||
|
||||
public void testSetFlowExecutionInSession() {
|
||||
urlHandler.setFlowExecutionInSession("12345", renderRequest);
|
||||
assertEquals("12345", renderRequest.getPortletSession().getAttribute("execution"));
|
||||
}
|
||||
|
||||
public void testSessionFlowExecutionRemoval() {
|
||||
urlHandler.setFlowExecutionInSession("12345", renderRequest);
|
||||
assertEquals("12345", urlHandler.getFlowExecutionKey(renderRequest));
|
||||
actionRequest.setParameter("execution", "12345");
|
||||
assertEquals("12345", urlHandler.getFlowExecutionKey(actionRequest));
|
||||
assertNull(actionRequest.getPortletSession().getAttribute("execution"));
|
||||
}
|
||||
|
||||
public void testCreateFlowExecutionUrl() {
|
||||
String url = urlHandler.createFlowExecutionUrl("foo", "12345", renderResponse);
|
||||
assertEquals("http://localhost/mockportlet?urlType=action;param_execution=12345", url);
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletContext;
|
||||
|
||||
/**
|
||||
* Test case for the {@link PortletContextMap} class.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @author Erwin Vervaet
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletContextMapTests extends TestCase {
|
||||
|
||||
private PortletContextMap tested;
|
||||
|
||||
private MockPortletContext context;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
context = new MockPortletContext();
|
||||
// a fresh MockPortletContext seems to already contain an element;
|
||||
// that's confusing, so we remove it
|
||||
context.removeAttribute("javax.servlet.context.tempdir");
|
||||
tested = new PortletContextMap(context);
|
||||
tested.put("SomeKey", "SomeValue");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
context = null;
|
||||
tested = null;
|
||||
}
|
||||
|
||||
public void testIsEmpty() {
|
||||
tested.remove("SomeKey");
|
||||
assertEquals("size,", 0, tested.size());
|
||||
assertEquals("isEmpty,", true, tested.isEmpty());
|
||||
}
|
||||
|
||||
public void testSizeAddOne() {
|
||||
assertEquals("size,", 1, tested.size());
|
||||
}
|
||||
|
||||
public void testSizeAddTwo() {
|
||||
tested.put("SomeOtherKey", "SomeOtherValue");
|
||||
assertEquals("size,", 2, tested.size());
|
||||
}
|
||||
|
||||
public void testContainsKey() {
|
||||
assertEquals("containsKey,", true, tested.containsKey("SomeKey"));
|
||||
}
|
||||
|
||||
public void testContainsValue() {
|
||||
assertTrue(tested.containsValue("SomeValue"));
|
||||
}
|
||||
|
||||
public void testGet() {
|
||||
assertEquals("get,", "SomeValue", tested.get("SomeKey"));
|
||||
}
|
||||
|
||||
public void testPut() {
|
||||
Object old = tested.put("SomeKey", "SomeNewValue");
|
||||
|
||||
assertEquals("old value,", "SomeValue", old);
|
||||
assertEquals("new value,", "SomeNewValue", tested.get("SomeKey"));
|
||||
}
|
||||
|
||||
public void testRemove() {
|
||||
Object old = tested.remove("SomeKey");
|
||||
|
||||
assertEquals("old value,", "SomeValue", old);
|
||||
assertNull("should be gone", tested.get("SomeKey"));
|
||||
}
|
||||
|
||||
public void testPutAll() {
|
||||
Map<String, Object> otherMap = new HashMap<String, Object>();
|
||||
otherMap.put("SomeOtherKey", "SomeOtherValue");
|
||||
otherMap.put("SomeKey", "SomeUpdatedValue");
|
||||
tested.putAll(otherMap);
|
||||
assertEquals("SomeOtherValue", tested.get("SomeOtherKey"));
|
||||
assertEquals("SomeUpdatedValue", tested.get("SomeKey"));
|
||||
}
|
||||
|
||||
public void testClear() {
|
||||
tested.clear();
|
||||
assertTrue(tested.isEmpty());
|
||||
}
|
||||
|
||||
public void testKeySet() {
|
||||
assertEquals(1, tested.keySet().size());
|
||||
assertTrue(tested.keySet().contains("SomeKey"));
|
||||
}
|
||||
|
||||
public void testValues() {
|
||||
assertEquals(1, tested.values().size());
|
||||
assertTrue(tested.values().contains("SomeValue"));
|
||||
}
|
||||
|
||||
public void testEntrySet() {
|
||||
assertEquals(1, tested.entrySet().size());
|
||||
assertEquals("SomeKey", tested.entrySet().iterator().next().getKey());
|
||||
assertEquals("SomeValue", tested.entrySet().iterator().next().getValue());
|
||||
}
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockActionRequest;
|
||||
import org.springframework.mock.web.portlet.MockActionResponse;
|
||||
import org.springframework.mock.web.portlet.MockPortletContext;
|
||||
import org.springframework.mock.web.portlet.MockRenderRequest;
|
||||
import org.springframework.mock.web.portlet.MockRenderResponse;
|
||||
import org.springframework.webflow.context.servlet.ServletExternalContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ServletExternalContext}.
|
||||
*/
|
||||
public class PortletExternalContextTests extends TestCase {
|
||||
|
||||
private MockPortletContext portletContext;
|
||||
|
||||
private MockActionRequest request;
|
||||
|
||||
private MockActionResponse response;
|
||||
|
||||
private PortletExternalContext context;
|
||||
|
||||
private MockRenderRequest renderRequest;
|
||||
|
||||
private MockRenderResponse renderResponse;
|
||||
|
||||
private PortletExternalContext renderContext;
|
||||
|
||||
protected void setUp() {
|
||||
portletContext = new MockPortletContext();
|
||||
request = new MockActionRequest();
|
||||
response = new MockActionResponse();
|
||||
context = new PortletExternalContext(portletContext, request, response);
|
||||
renderRequest = new MockRenderRequest();
|
||||
renderResponse = new MockRenderResponse();
|
||||
renderContext = new PortletExternalContext(portletContext, renderRequest, renderResponse);
|
||||
}
|
||||
|
||||
public void testGetContextPath() {
|
||||
request.setContextPath("/foo");
|
||||
assertEquals("/foo", request.getContextPath());
|
||||
}
|
||||
|
||||
public void testRequestParameters() {
|
||||
assertTrue(context.getRequestParameterMap().isEmpty());
|
||||
}
|
||||
|
||||
public void testGetNativeObjects() {
|
||||
assertEquals(portletContext, context.getNativeContext());
|
||||
assertEquals(request, context.getNativeRequest());
|
||||
assertEquals(response, context.getNativeResponse());
|
||||
}
|
||||
|
||||
public void testNotAnAjaxRequest() {
|
||||
assertFalse(context.isAjaxRequest());
|
||||
}
|
||||
|
||||
public void testAjaxRequestAcceptHeader() {
|
||||
assertFalse(context.isAjaxRequest());
|
||||
}
|
||||
|
||||
public void testNotResponseCommitted() {
|
||||
assertFalse(context.isResponseComplete());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirect() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
context.requestFlowExecutionRedirect();
|
||||
assertTrue(context.getFlowExecutionRedirectRequested());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertTrue(context.isResponseCompleteFlowExecutionRedirect());
|
||||
assertFalse(context.isResponseAllowed());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirectRenderRequest() {
|
||||
try {
|
||||
renderContext.requestFlowExecutionRedirect();
|
||||
fail("IllegalStateException expected");
|
||||
} catch (IllegalStateException e) {
|
||||
// we want this
|
||||
}
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirect() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertFalse(context.isResponseCompleteFlowExecutionRedirect());
|
||||
assertFalse(context.isResponseAllowed());
|
||||
assertNotNull(context.getFlowRedirectFlowInput());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirectWithInput() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
LocalAttributeMap<Object> input = new LocalAttributeMap<Object>();
|
||||
context.requestFlowDefinitionRedirect("foo", input);
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertFalse(context.isResponseCompleteFlowExecutionRedirect());
|
||||
assertFalse(context.isResponseAllowed());
|
||||
assertEquals(input, context.getFlowRedirectFlowInput());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirectRenderRequest() {
|
||||
try {
|
||||
renderContext.requestFlowDefinitionRedirect("foo", null);
|
||||
fail("IllegalStateException expected");
|
||||
} catch (IllegalStateException e) {
|
||||
// we want this
|
||||
}
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirect() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
context.requestExternalRedirect("foo");
|
||||
assertTrue(context.getExternalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertFalse(context.isResponseCompleteFlowExecutionRedirect());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirectRenderRequest() {
|
||||
try {
|
||||
renderContext.requestExternalRedirect("foo");
|
||||
fail("IllegalStateException expected");
|
||||
} catch (IllegalStateException e) {
|
||||
// we want this
|
||||
}
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirectPopup() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
context.requestFlowExecutionRedirect();
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.getFlowExecutionRedirectRequested());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertTrue(context.isResponseCompleteFlowExecutionRedirect());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirectPopup() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.getFlowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertFalse(context.isResponseCompleteFlowExecutionRedirect());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirectPopup() {
|
||||
context.requestExternalRedirect("foo");
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.getExternalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertFalse(context.isResponseCompleteFlowExecutionRedirect());
|
||||
}
|
||||
|
||||
public void testExecutionRedirectPopupRenderRequest() {
|
||||
try {
|
||||
renderContext.requestRedirectInPopup();
|
||||
fail("IllegalStateException expected");
|
||||
} catch (IllegalStateException e) {
|
||||
// we want this
|
||||
}
|
||||
}
|
||||
|
||||
public void testResponseAllowed() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
}
|
||||
|
||||
public void testIsActionPhase() {
|
||||
assertTrue(context.isActionPhase());
|
||||
}
|
||||
|
||||
public void testIsRenderPhase() {
|
||||
assertFalse(context.isRenderPhase());
|
||||
}
|
||||
|
||||
public void testRecordResponseComplete() {
|
||||
context.recordResponseComplete();
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertFalse(context.isResponseAllowed());
|
||||
}
|
||||
|
||||
public void testDoubleCommitResponse() {
|
||||
context.recordResponseComplete();
|
||||
try {
|
||||
context.requestExternalRedirect("foo");
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
try {
|
||||
context.requestFlowExecutionRedirect();
|
||||
fail("Should have failed");
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
fail("Should have failed");
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void testRedirectInPopup() {
|
||||
assertFalse(context.isResponseComplete());
|
||||
assertFalse(context.isResponseAllowed());
|
||||
context.requestFlowExecutionRedirect();
|
||||
assertTrue(context.isResponseComplete());
|
||||
assertTrue(context.isResponseCompleteFlowExecutionRedirect());
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
assertFalse(context.isResponseAllowed());
|
||||
assertTrue(context.getRedirectInPopup());
|
||||
}
|
||||
|
||||
public void testRedirectInPopupNoRedirectRequested() {
|
||||
try {
|
||||
context.requestRedirectInPopup();
|
||||
fail("Should have failed");
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetResponseWriter() throws IOException {
|
||||
Writer writer = renderContext.getResponseWriter();
|
||||
writer.append('t');
|
||||
assertEquals("t", renderResponse.getContentAsString());
|
||||
}
|
||||
|
||||
public void testGetResponseWriterResponseComplete() throws IOException {
|
||||
context.recordResponseComplete();
|
||||
try {
|
||||
context.getResponseWriter();
|
||||
fail("Should have failed");
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
|
||||
/**
|
||||
* Unit test for the {@link PortletRequestMap} class.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletRequestMapTests extends TestCase {
|
||||
|
||||
private PortletRequestMap tested;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
request = new MockPortletRequest();
|
||||
tested = new PortletRequestMap(request);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
request = null;
|
||||
tested = null;
|
||||
}
|
||||
|
||||
public void testGetAttribute() {
|
||||
request.setAttribute("Some key", "Some value");
|
||||
// perform test
|
||||
Object result = tested.getAttribute("Some key");
|
||||
assertEquals("Some value", result);
|
||||
}
|
||||
|
||||
public void testSetAttribute() {
|
||||
// perform test
|
||||
tested.setAttribute("Some key", "Some value");
|
||||
assertEquals("Some value", request.getAttribute("Some key"));
|
||||
}
|
||||
|
||||
public void testRemoveAttribute() {
|
||||
request.setAttribute("Some key", "Some value");
|
||||
// perform test
|
||||
tested.removeAttribute("Some key");
|
||||
assertNull(request.getAttribute("Some key"));
|
||||
}
|
||||
|
||||
public void testGetAttributeNames() {
|
||||
request.setAttribute("Some key", "Some value");
|
||||
// perform test
|
||||
Iterator<String> names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertTrue("More elements", names.hasNext());
|
||||
while (names.hasNext()) {
|
||||
String name = names.next();
|
||||
if ("Some key".equals(name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail("Expected to find: 'Some key'");
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
|
||||
/**
|
||||
* Unit test for the {@link PortletRequestParameterMap} class.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletRequestParameterMapTests extends TestCase {
|
||||
|
||||
private PortletRequestParameterMap tested;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
request = new MockPortletRequest();
|
||||
tested = new PortletRequestParameterMap(request);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
request = null;
|
||||
tested = null;
|
||||
}
|
||||
|
||||
public void testGetAttribute() {
|
||||
request.setParameter("Some param", "Some value");
|
||||
// perform test
|
||||
Object result = tested.getAttribute("Some param");
|
||||
assertEquals("Some value", result);
|
||||
}
|
||||
|
||||
public void testSetAttribute() {
|
||||
// perform test
|
||||
try {
|
||||
tested.setAttribute("Some key", "Some value");
|
||||
fail("UnsupportedOperationException expected");
|
||||
} catch (UnsupportedOperationException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveAttribute() {
|
||||
request.setParameter("Some param", "Some value");
|
||||
// perform test
|
||||
try {
|
||||
tested.removeAttribute("Some param");
|
||||
fail("UnsupportedOperationException expected");
|
||||
} catch (UnsupportedOperationException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetAttributeNames() {
|
||||
request.setParameter("Some param", "Some value");
|
||||
// perform test
|
||||
Iterator<String> names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertTrue("More elements", names.hasNext());
|
||||
String name = names.next();
|
||||
assertEquals("Some param", name);
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 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.context.portlet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Unit test for the {@link PortletSessionMap} class.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class PortletSessionMapTests extends TestCase {
|
||||
|
||||
private PortletSessionMap tested;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
request = new MockPortletRequest();
|
||||
tested = new PortletSessionMap(request);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
request = null;
|
||||
tested = null;
|
||||
}
|
||||
|
||||
public void testGetAttribute() {
|
||||
request.getPortletSession().setAttribute("Some key", "Some value");
|
||||
// perform test
|
||||
Object result = tested.getAttribute("Some key");
|
||||
assertEquals("Some value", result);
|
||||
}
|
||||
|
||||
public void testGetAttributeNullSession() {
|
||||
request.setSession(null);
|
||||
// perform test
|
||||
Object result = tested.getAttribute("Some key");
|
||||
assertNull("No value expected", result);
|
||||
}
|
||||
|
||||
public void testSetAttribute() {
|
||||
// perform test
|
||||
tested.setAttribute("Some key", "Some value");
|
||||
assertEquals("Some value", request.getPortletSession().getAttribute("Some key"));
|
||||
}
|
||||
|
||||
public void testRemoveAttribute() {
|
||||
request.getPortletSession().setAttribute("Some key", "Some value");
|
||||
// perform test
|
||||
tested.removeAttribute("Some key");
|
||||
assertNull(request.getPortletSession().getAttribute("Some key"));
|
||||
}
|
||||
|
||||
public void testRemoveAttributeNullSession() {
|
||||
request.setSession(null);
|
||||
// perform test
|
||||
tested.removeAttribute("Some key");
|
||||
assertNull(request.getPortletSession().getAttribute("Some key"));
|
||||
}
|
||||
|
||||
public void testGetAttributeNames() {
|
||||
request.getPortletSession().setAttribute("Some key", "Some value");
|
||||
// perform test
|
||||
Iterator<String> names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertTrue("More elements", names.hasNext());
|
||||
String name = names.next();
|
||||
assertEquals("Some key", name);
|
||||
}
|
||||
|
||||
public void testGetAttributeNamesNullSession() {
|
||||
request.setSession(null);
|
||||
// perform test
|
||||
Iterator<String> names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertFalse("No elements expected", names.hasNext());
|
||||
}
|
||||
|
||||
public void testGetSessionAsMutex() {
|
||||
Object mutex = tested.getMutex();
|
||||
assertSame(mutex, request.getPortletSession());
|
||||
}
|
||||
|
||||
public void testGetSessionMutex() {
|
||||
Object object = new Object();
|
||||
request.getPortletSession().setAttribute(WebUtils.SESSION_MUTEX_ATTRIBUTE, object);
|
||||
Object mutex = tested.getMutex();
|
||||
assertSame(mutex, object);
|
||||
}
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
package org.springframework.webflow.mvc.portlet;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.mock.web.portlet.MockActionRequest;
|
||||
import org.springframework.mock.web.portlet.MockActionResponse;
|
||||
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.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.portlet.ModelAndView;
|
||||
import org.springframework.webflow.context.portlet.PortletExternalContext;
|
||||
import org.springframework.webflow.core.FlowException;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionOutcome;
|
||||
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
|
||||
import org.springframework.webflow.executor.FlowExecutionResult;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.test.MockFlowExecutionKey;
|
||||
|
||||
public class FlowHandlerAdapterTests extends TestCase {
|
||||
|
||||
private FlowHandlerAdapter controller;
|
||||
private FlowExecutor flowExecutor;
|
||||
private MockPortletContext portletContext;
|
||||
private MockActionRequest actionRequest;
|
||||
private MockActionResponse actionResponse;
|
||||
private MockRenderRequest renderRequest;
|
||||
private MockRenderResponse renderResponse;
|
||||
private PortletExternalContext actionContext;
|
||||
private PortletExternalContext renderContext;
|
||||
private FlowHandler flowHandler;
|
||||
private LocalAttributeMap<Object> flowInput = null;
|
||||
private boolean handleException;
|
||||
private boolean handleExecutionOutcome;
|
||||
private boolean handleExecutionOutcomeCalled;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
flowExecutor = EasyMock.createMock(FlowExecutor.class);
|
||||
controller = new FlowHandlerAdapter() {
|
||||
protected PortletExternalContext createPortletExternalContext(PortletRequest request,
|
||||
PortletResponse response) {
|
||||
if (request instanceof ActionRequest) {
|
||||
return actionContext;
|
||||
} else {
|
||||
return renderContext;
|
||||
}
|
||||
}
|
||||
};
|
||||
controller.setFlowExecutor(flowExecutor);
|
||||
controller.setApplicationContext(new StaticWebApplicationContext());
|
||||
portletContext = new MockPortletContext();
|
||||
controller.setPortletContext(portletContext);
|
||||
controller.afterPropertiesSet();
|
||||
|
||||
actionRequest = new MockActionRequest();
|
||||
actionResponse = new MockActionResponse();
|
||||
renderRequest = new MockRenderRequest();
|
||||
renderResponse = new MockRenderResponse();
|
||||
actionContext = new PortletExternalContext(portletContext, actionRequest, actionResponse,
|
||||
controller.getFlowUrlHandler());
|
||||
renderContext = new PortletExternalContext(portletContext, renderRequest, renderResponse,
|
||||
controller.getFlowUrlHandler());
|
||||
|
||||
flowHandler = new FlowHandler() {
|
||||
public String getFlowId() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public MutableAttributeMap<Object> createExecutionInputMap(RenderRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MutableAttributeMap<Object> createResourceExecutionInputMap(ResourceRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean handleExecutionOutcome(FlowExecutionOutcome outcome, ActionRequest request,
|
||||
ActionResponse response) {
|
||||
handleExecutionOutcomeCalled = true;
|
||||
if (handleExecutionOutcome) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String handleException(FlowException e, RenderRequest request, RenderResponse response) {
|
||||
if (handleException) {
|
||||
return "error";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String handleResourceException(FlowException e, ResourceRequest request, ResourceResponse response) {
|
||||
if (handleException) {
|
||||
return "error";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public void testLaunchFlowRequest() throws Exception {
|
||||
renderRequest.setContextPath("/springtravel");
|
||||
flowExecutor.launchExecution("foo", flowInput, renderContext);
|
||||
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345");
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
ModelAndView mv = controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
assertNull(mv);
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
}
|
||||
|
||||
public void testResumeFlowActionRequest() throws Exception {
|
||||
actionRequest.setContextPath("/springtravel");
|
||||
actionRequest.addParameter("execution", "12345");
|
||||
flowExecutor.resumeExecution("12345", actionContext);
|
||||
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456");
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
controller.handleAction(actionRequest, actionResponse, flowHandler);
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
}
|
||||
|
||||
public void testResumeFlowRenderRequest() throws Exception {
|
||||
renderRequest.setContextPath("/springtravel");
|
||||
renderRequest.addParameter("execution", "12345");
|
||||
flowExecutor.resumeExecution("12345", renderContext);
|
||||
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456");
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
}
|
||||
|
||||
public void testResumeFlowRenderRequestFromSession() throws Exception {
|
||||
renderRequest.setContextPath("/springtravel");
|
||||
PortletSession session = renderRequest.getPortletSession();
|
||||
session.setAttribute("execution", "12345");
|
||||
flowExecutor.resumeExecution("12345", renderContext);
|
||||
FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456");
|
||||
EasyMock.expectLastCall().andReturn(result);
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
}
|
||||
|
||||
public void testDefaultHandleFlowException() throws Exception {
|
||||
PortletSession session = renderRequest.getPortletSession();
|
||||
final FlowException flowException = new FlowException("Error") {
|
||||
};
|
||||
session.setAttribute("actionRequestFlowException", flowException);
|
||||
try {
|
||||
controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
fail("Should have thrown exception");
|
||||
} catch (FlowException e) {
|
||||
assertEquals(flowException, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultHandleNoSuchFlowExecutionException() throws Exception {
|
||||
actionRequest.setContextPath("/springtravel");
|
||||
actionRequest.addParameter("execution", "12345");
|
||||
flowExecutor.resumeExecution("12345", actionContext);
|
||||
FlowException flowException = new NoSuchFlowExecutionException(new MockFlowExecutionKey("12345"), null);
|
||||
EasyMock.expectLastCall().andThrow(flowException);
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
controller.handleAction(actionRequest, actionResponse, flowHandler);
|
||||
assertNotNull(actionRequest.getPortletSession().getAttribute("actionRequestFlowException"));
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
Exception e = (Exception) actionRequest.getPortletSession().getAttribute("actionRequestFlowException");
|
||||
assertTrue(e instanceof NoSuchFlowExecutionException);
|
||||
}
|
||||
|
||||
public void testHandleFlowOutcomeCustomFlowHandler() throws Exception {
|
||||
handleExecutionOutcome = true;
|
||||
actionRequest.setContextPath("/springtravel");
|
||||
actionRequest.addParameter("execution", "12345");
|
||||
LocalAttributeMap<Object> output = new LocalAttributeMap<Object>();
|
||||
output.put("bar", "baz");
|
||||
FlowExecutionOutcome outcome = new FlowExecutionOutcome("finish", output);
|
||||
flowExecutor.resumeExecution("12345", actionContext);
|
||||
EasyMock.expectLastCall().andReturn(FlowExecutionResult.createEndedResult("bar", outcome));
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
controller.handleAction(actionRequest, actionResponse, flowHandler);
|
||||
assertTrue(handleExecutionOutcomeCalled);
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
}
|
||||
|
||||
public void testHandleFlowExceptionCustomFlowHandler() throws Exception {
|
||||
handleException = true;
|
||||
final FlowException flowException = new FlowException("Error") {
|
||||
};
|
||||
renderRequest.setContextPath("/springtravel");
|
||||
flowExecutor.launchExecution("foo", flowInput, renderContext);
|
||||
EasyMock.expectLastCall().andThrow(flowException);
|
||||
EasyMock.replay(new Object[] { flowExecutor });
|
||||
ModelAndView mv = controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
assertNotNull(mv);
|
||||
assertEquals("error", mv.getViewName());
|
||||
EasyMock.verify(new Object[] { flowExecutor });
|
||||
}
|
||||
|
||||
public void testHandleFlowExceptionFromSession() throws Exception {
|
||||
handleException = true;
|
||||
PortletSession session = renderRequest.getPortletSession();
|
||||
final FlowException flowException = new FlowException("Error") {
|
||||
};
|
||||
session.setAttribute("actionRequestFlowException", flowException);
|
||||
ModelAndView mv = controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
assertEquals("error", mv.getViewName());
|
||||
}
|
||||
|
||||
public void testPopulateConveniencePortletProperties() {
|
||||
controller.populateConveniencePortletProperties(renderRequest);
|
||||
assertEquals(renderRequest.getPortletMode().toString(), renderRequest.getAttribute("portletMode"));
|
||||
assertEquals(renderRequest.getWindowState().toString(), renderRequest.getAttribute("portletWindowState"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.springframework.webflow.mvc.portlet;
|
||||
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.binding.expression.support.StaticExpression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
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.expression.spel.WebFlowSpringELExpressionParser;
|
||||
import org.springframework.webflow.mvc.view.AbstractMvcView;
|
||||
import org.springframework.webflow.mvc.view.MvcViewTests.BindBean;
|
||||
import org.springframework.webflow.test.MockFlowExecutionKey;
|
||||
import org.springframework.webflow.test.MockRequestContext;
|
||||
import org.springframework.webflow.validation.WebFlowMessageCodesResolver;
|
||||
|
||||
public class PortletMvcViewTests extends TestCase {
|
||||
|
||||
public void testRender() throws Exception {
|
||||
RenderRequest request = new MockRenderRequest();
|
||||
RenderResponse response = new MockRenderResponse();
|
||||
MockRequestContext context = new MockRequestContext();
|
||||
context.getMockExternalContext().setNativeContext(new MockPortletContext());
|
||||
context.getMockExternalContext().setNativeRequest(request);
|
||||
context.getMockExternalContext().setNativeResponse(response);
|
||||
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
|
||||
org.springframework.web.servlet.View mvcView = EasyMock.createMock(org.springframework.web.servlet.View.class);
|
||||
AbstractMvcView view = new PortletMvcView(mvcView, context);
|
||||
view.render();
|
||||
assertNotNull(request.getAttribute(ViewRendererServlet.VIEW_ATTRIBUTE));
|
||||
assertNotNull(request.getAttribute(ViewRendererServlet.MODEL_ATTRIBUTE));
|
||||
}
|
||||
|
||||
public void testResumeEvent() throws Exception {
|
||||
MockRequestContext context = new MockRequestContext();
|
||||
context.putRequestParameter("_eventId", "submit");
|
||||
context.putRequestParameter("booleanProperty", "bogus");
|
||||
context.putRequestParameter("_booleanProperty", "whatever");
|
||||
BindBean bindBean = new BindBean();
|
||||
StaticExpression modelObject = new StaticExpression(bindBean);
|
||||
modelObject.setExpressionString("bindBean");
|
||||
context.getCurrentState().getAttributes().put("model", modelObject);
|
||||
context.getFlowScope().put("bindBean", bindBean);
|
||||
context.getMockExternalContext().setNativeContext(new MockServletContext());
|
||||
context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest());
|
||||
context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse());
|
||||
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
|
||||
org.springframework.web.servlet.View mvcView = EasyMock.createMock(org.springframework.web.servlet.View.class);
|
||||
AbstractMvcView view = new PortletMvcView(mvcView, context);
|
||||
view.setExpressionParser(new WebFlowSpringELExpressionParser(new SpelExpressionParser()));
|
||||
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
|
||||
view.processUserEvent();
|
||||
assertEquals(true, bindBean.getBooleanProperty());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
|
||||
import org.springframework.orm.hibernate5.HibernateTransactionManager;
|
||||
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
|
||||
@@ -16,85 +16,22 @@
|
||||
package org.springframework.webflow.persistence;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.orm.hibernate4.HibernateCallback;
|
||||
import org.springframework.orm.hibernate4.HibernateTemplate;
|
||||
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class HibernateHandlerFactory {
|
||||
|
||||
static HibernateHandler create(DataSource dataSource) throws Exception {
|
||||
if (ClassUtils.isPresent("org.hibernate.engine.transaction.spi.TransactionContext",
|
||||
HibernateHandlerFactory.class.getClassLoader())) {
|
||||
return new Hibernate4Handler(dataSource);
|
||||
}
|
||||
return new Hibernate5Handler(dataSource);
|
||||
}
|
||||
|
||||
private static class Hibernate4Handler implements HibernateHandler {
|
||||
|
||||
private final HibernateTemplate template;
|
||||
|
||||
private final PlatformTransactionManager tranasactionManager;
|
||||
|
||||
private final SessionFactory sessionFactory;
|
||||
|
||||
private Hibernate4Handler(DataSource dataSource) throws Exception {
|
||||
sessionFactory = createSessionFactory(dataSource);
|
||||
template = new HibernateTemplate(sessionFactory);
|
||||
template.setCheckWriteOperations(false);
|
||||
tranasactionManager = new HibernateTransactionManager(sessionFactory);
|
||||
}
|
||||
|
||||
public void templateSave(Object entity) {
|
||||
template.save(entity);
|
||||
}
|
||||
|
||||
public <T> T templateGet(Class<T> entityClass, Serializable id) {
|
||||
return template.get(entityClass, id);
|
||||
}
|
||||
|
||||
public void templateExecuteWithNativeSession(final SessionCallback callback) {
|
||||
template.executeWithNativeSession(new HibernateCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInHibernate(Session session) throws HibernateException {
|
||||
callback.doWithSession(session);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public PlatformTransactionManager getTransactionManager() {
|
||||
return tranasactionManager;
|
||||
}
|
||||
|
||||
public SessionFactory getSessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
private static SessionFactory createSessionFactory(DataSource dataSource) throws Exception {
|
||||
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
factory.setMappingLocations(new Resource[] {
|
||||
new ClassPathResource("org/springframework/webflow/persistence/TestBean.hbm.xml"),
|
||||
new ClassPathResource("org/springframework/webflow/persistence/TestAddress.hbm.xml") });
|
||||
factory.afterPropertiesSet();
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Hibernate5Handler implements HibernateHandler {
|
||||
|
||||
private final org.springframework.orm.hibernate5.HibernateTemplate template;
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.webflow.engine.EndState;
|
||||
import org.springframework.webflow.execution.FlowExecutionException;
|
||||
|
||||
Reference in New Issue
Block a user