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:
Rossen Stoyanchev
2017-01-05 18:00:10 -05:00
parent b5dd6a8193
commit deeaeab894
57 changed files with 37 additions and 5177 deletions

View File

@@ -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=",

View File

@@ -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();
}
}

View File

@@ -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("*****");
}
}

View File

@@ -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());
}
}

View File

@@ -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 {
}
}

View File

@@ -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);
}
}

View File

@@ -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()]);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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) {
}
}
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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 {
}
}

View File

@@ -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]);
}
}

View File

@@ -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]);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);
}
/**

View File

@@ -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;
}
}

View File

@@ -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 ");
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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) {
}
}
}

View File

@@ -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'");
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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"));
}
}

View File

@@ -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());
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;