SWF-183
first pass at portlet integration
This commit is contained in:
@@ -172,4 +172,10 @@ public interface ExternalContext {
|
||||
*/
|
||||
public boolean isResponseCommitted();
|
||||
|
||||
/**
|
||||
* Is a response allowed for this request
|
||||
* @return true if yes, false otherwise
|
||||
*/
|
||||
public boolean isResponseAllowed();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.PortletURL;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
/**
|
||||
* Default flow URL handler for SWF 2.
|
||||
*
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class DefaultFlowUrlHandler implements FlowUrlHandler {
|
||||
|
||||
public String getFlowExecutionKey(PortletRequest request) {
|
||||
return request.getParameter("execution");
|
||||
}
|
||||
|
||||
public void setFlowExecutionRenderParameter(String flowExecutionKey, ActionResponse response) {
|
||||
response.setRenderParameter("execution", flowExecutionKey);
|
||||
}
|
||||
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, RenderResponse response) {
|
||||
PortletURL url = response.createActionURL();
|
||||
url.setParameter("execution", flowExecutionKey);
|
||||
return url.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.webflow.context.portlet;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, RenderResponse response);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 implements SharedMap {
|
||||
|
||||
/**
|
||||
* 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 getAttributeNames() {
|
||||
return CollectionUtils.toIterator(context.getAttributeNames());
|
||||
}
|
||||
|
||||
public Object getMutex() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
package org.springframework.webflow.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.security.Principal;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
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;
|
||||
|
||||
/**
|
||||
* The context.
|
||||
*/
|
||||
private PortletContext context;
|
||||
|
||||
/**
|
||||
* The request.
|
||||
*/
|
||||
private PortletRequest request;
|
||||
|
||||
/**
|
||||
* The response.
|
||||
*/
|
||||
private PortletResponse response;
|
||||
|
||||
/**
|
||||
* The portlet request phase: render or action
|
||||
*/
|
||||
private short requestPhase;
|
||||
|
||||
/**
|
||||
* An accessor for the HTTP request parameter map.
|
||||
*/
|
||||
private ParameterMap requestParameterMap;
|
||||
|
||||
/**
|
||||
* An accessor for the HTTP request attribute map.
|
||||
*/
|
||||
private MutableAttributeMap requestMap;
|
||||
|
||||
/**
|
||||
* An accessor for the HTTP session map.
|
||||
*/
|
||||
private SharedAttributeMap sessionMap;
|
||||
|
||||
/**
|
||||
* An accessor for the servlet context application map.
|
||||
*/
|
||||
private SharedAttributeMap applicationMap;
|
||||
|
||||
/**
|
||||
* 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 AttributeMap flowDefinitionRedirectFlowInput;
|
||||
|
||||
/**
|
||||
* A string specifying an arbitrary
|
||||
*/
|
||||
private String externalRedirectUrl;
|
||||
|
||||
/**
|
||||
* The strategy for generating flow execution urls.
|
||||
*/
|
||||
private FlowUrlHandler flowUrlHandler;
|
||||
|
||||
/**
|
||||
* Whether this external request context originated from an Ajax request or not.
|
||||
*/
|
||||
private boolean ajaxRequest;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the current request from this client is an ajax request. This flag may effect the handling of
|
||||
* response writing within Spring Web Flow.
|
||||
* @param ajaxRequest the ajax request flag
|
||||
*/
|
||||
public void setAjaxRequest(boolean ajaxRequest) {
|
||||
this.ajaxRequest = ajaxRequest;
|
||||
}
|
||||
|
||||
// implementing external context
|
||||
|
||||
public String getContextPath() {
|
||||
return request.getContextPath();
|
||||
}
|
||||
|
||||
public ParameterMap getRequestParameterMap() {
|
||||
return requestParameterMap;
|
||||
}
|
||||
|
||||
public MutableAttributeMap getRequestMap() {
|
||||
return requestMap;
|
||||
}
|
||||
|
||||
public SharedAttributeMap getSessionMap() {
|
||||
return sessionMap;
|
||||
}
|
||||
|
||||
public SharedAttributeMap getGlobalSessionMap() {
|
||||
return getSessionMap();
|
||||
}
|
||||
|
||||
public SharedAttributeMap getApplicationMap() {
|
||||
return applicationMap;
|
||||
}
|
||||
|
||||
public Principal getCurrentUser() {
|
||||
return request.getUserPrincipal();
|
||||
}
|
||||
|
||||
public Object getNativeContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public Object getNativeRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public Object getNativeResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public boolean isAjaxRequest() {
|
||||
return ajaxRequest;
|
||||
}
|
||||
|
||||
public String getFlowExecutionUri(String flowId, String flowExecutionKey) {
|
||||
if (this.isRenderPhase()) {
|
||||
return flowUrlHandler.createFlowExecutionUrl(flowId, flowExecutionKey, (RenderResponse) response);
|
||||
} else {
|
||||
throw new IllegalStateException("Only a render request can obtain an flow execution uri");
|
||||
}
|
||||
}
|
||||
|
||||
public Writer getResponseWriter() {
|
||||
try {
|
||||
if (isRenderPhase()) {
|
||||
return ((RenderResponse) response).getWriter();
|
||||
} else {
|
||||
throw new IllegalStateException("Only render requests can obtain response writer");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to obtain response writer", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
return flowExecutionRedirectRequested() || flowDefinitionRedirectRequested() || externalRedirectRequested();
|
||||
}
|
||||
|
||||
public boolean isResponseAllowed() {
|
||||
return isRenderPhase();
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() {
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
public void requestExternalRedirect(String uri) {
|
||||
externalRedirectUrl = uri;
|
||||
}
|
||||
|
||||
public void requestFlowDefinitionRedirect(String flowId, AttributeMap input) {
|
||||
flowDefinitionRedirectFlowId = flowId;
|
||||
flowDefinitionRedirectFlowInput = input;
|
||||
}
|
||||
|
||||
public void requestRedirectInPopup() {
|
||||
redirectInPopup = true;
|
||||
}
|
||||
|
||||
// implementation specific methods
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow execution redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean flowExecutionRedirectRequested() {
|
||||
return flowExecutionRedirectRequested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if a flow definition redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean flowDefinitionRedirectRequested() {
|
||||
return flowDefinitionRedirectFlowId != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the flow definition to redirect to. Only set when {@link #flowDefinitionRedirectRequested()}
|
||||
* returns true.
|
||||
*/
|
||||
public String getFlowRedirectFlowId() {
|
||||
return flowDefinitionRedirectFlowId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input to pass the flow definition through the redirect. Only set when
|
||||
* {@link #flowDefinitionRedirectRequested()} returns true.
|
||||
*/
|
||||
public AttributeMap getFlowRedirectFlowInput() {
|
||||
return flowDefinitionRedirectFlowInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flag indicating if an external redirect response has been requested by the flow.
|
||||
*/
|
||||
public boolean externalRedirectRequested() {
|
||||
return externalRedirectUrl != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL to redirect to. Only set if {@link #externalRedirectRequested()} 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 redirectInPopup() {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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(new PortletRequestMap(request));
|
||||
this.sessionMap = new LocalSharedAttributeMap(new PortletSessionMap(request));
|
||||
this.applicationMap = new LocalSharedAttributeMap(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 {
|
||||
throw new IllegalArgumentException("Unknown portlet phase, expected: action or render");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 {
|
||||
|
||||
/**
|
||||
* 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 getAttributeNames() {
|
||||
return CollectionUtils.toIterator(request.getAttributeNames());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.CompositeIterator;
|
||||
import org.springframework.binding.collection.StringKeyedMapAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
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 {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
Object data = multipartRequest.getFileMap().get(key);
|
||||
if (data != null) {
|
||||
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 getAttributeNames() {
|
||||
if (request instanceof MultipartActionRequest) {
|
||||
MultipartActionRequest multipartRequest = (MultipartActionRequest) request;
|
||||
CompositeIterator iterator = new CompositeIterator();
|
||||
iterator.add(multipartRequest.getFileMap().keySet().iterator());
|
||||
iterator.add(CollectionUtils.toIterator(request.getParameterNames()));
|
||||
return iterator;
|
||||
} else {
|
||||
return CollectionUtils.toIterator(request.getParameterNames());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 implements SharedMap {
|
||||
|
||||
/**
|
||||
* 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 getAttributeNames() {
|
||||
PortletSession session = getSession();
|
||||
return session == null ? CollectionUtils.EMPTY_ITERATOR : 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;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import javax.servlet.http.HttpSession;
|
||||
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;
|
||||
|
||||
|
||||
@@ -207,6 +207,10 @@ public class ServletExternalContext implements ExternalContext {
|
||||
return flowExecutionRedirectRequested() || flowDefinitionRedirectRequested() || externalRedirectRequested();
|
||||
}
|
||||
|
||||
public boolean isResponseAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() {
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.webflow.context.servlet;
|
||||
package org.springframework.webflow.context.web;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -96,7 +96,7 @@ public class EndState extends State {
|
||||
FlowSession activeSession = context.getFlowExecutionContext().getActiveSession();
|
||||
if (activeSession.isRoot()) {
|
||||
// entire flow execution is ending; issue the final response
|
||||
if (finalResponseAction != null) {
|
||||
if (finalResponseAction != null && context.getExternalContext().isResponseAllowed()) {
|
||||
ActionExecutor.execute(finalResponseAction, context);
|
||||
}
|
||||
context.endActiveFlowSession(createSessionOutput(context));
|
||||
|
||||
@@ -161,14 +161,16 @@ public class ViewState extends TransitionableState {
|
||||
|
||||
protected void doEnter(RequestControlContext context) throws FlowExecutionException {
|
||||
context.assignFlowExecutionKey();
|
||||
if (shouldRedirect(context)) {
|
||||
context.getExternalContext().requestFlowExecutionRedirect();
|
||||
if (popup) {
|
||||
context.getExternalContext().requestRedirectInPopup();
|
||||
if (context.getExternalContext().isResponseAllowed()) {
|
||||
if (shouldRedirect(context)) {
|
||||
context.getExternalContext().requestFlowExecutionRedirect();
|
||||
if (popup) {
|
||||
context.getExternalContext().requestRedirectInPopup();
|
||||
}
|
||||
} else {
|
||||
View view = viewFactory.getView(context);
|
||||
render(context, view);
|
||||
}
|
||||
} else {
|
||||
View view = viewFactory.getView(context);
|
||||
render(context, view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,11 +184,13 @@ public class ViewState extends TransitionableState {
|
||||
logger.debug("Event '" + event.getId() + "' signaled on view " + view);
|
||||
}
|
||||
boolean stateExited = context.handleEvent(event);
|
||||
if (!stateExited) {
|
||||
if (!stateExited && context.getExternalContext().isResponseAllowed()) {
|
||||
render(context, view);
|
||||
}
|
||||
} else {
|
||||
render(context, view);
|
||||
if (context.getExternalContext().isResponseAllowed()) {
|
||||
render(context, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.portlet;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.springframework.web.portlet.ModelAndView;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
|
||||
/**
|
||||
* A controller helper used for customizing access to a <i>single</i> flow definition. 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 un-handled 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
|
||||
*/
|
||||
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. Used by a Controller to
|
||||
* launch the flow execution with the correct input.
|
||||
* @param request the current request
|
||||
* @return the input map
|
||||
*/
|
||||
public MutableAttributeMap createExecutionInputMap(PortletRequest request);
|
||||
|
||||
public ModelAndView handleFlowOutcome(String endedOutcome, AttributeMap endedOutput, RenderRequest request,
|
||||
RenderResponse response);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package org.springframework.webflow.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 org.springframework.web.portlet.HandlerAdapter;
|
||||
import org.springframework.web.portlet.ModelAndView;
|
||||
import org.springframework.web.portlet.context.PortletApplicationObjectSupport;
|
||||
import org.springframework.webflow.context.portlet.FlowUrlHandler;
|
||||
import org.springframework.webflow.context.portlet.PortletExternalContext;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.executor.FlowExecutionResult;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
|
||||
public class FlowHandlerAdapter extends PortletApplicationObjectSupport implements HandlerAdapter {
|
||||
|
||||
private static final String FLOW_EXECUTION_RESULT = "flowExecutionResult";
|
||||
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
private FlowUrlHandler urlHandler;
|
||||
|
||||
public FlowHandlerAdapter(FlowExecutor flowExecutor) {
|
||||
this.flowExecutor = flowExecutor;
|
||||
}
|
||||
|
||||
public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object handler) throws Exception {
|
||||
FlowHandler flowHandler = (FlowHandler) handler;
|
||||
String flowExecutionKey = urlHandler.getFlowExecutionKey(request);
|
||||
if (flowExecutionKey != null) {
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
flowExecutor.resumeExecution(flowExecutionKey, context);
|
||||
return null;
|
||||
} else {
|
||||
PortletSession session = request.getPortletSession(true);
|
||||
FlowExecutionResult result = (FlowExecutionResult) session.getAttribute(FLOW_EXECUTION_RESULT);
|
||||
if (result != null) {
|
||||
session.removeAttribute(FLOW_EXECUTION_RESULT);
|
||||
return flowHandler.handleFlowOutcome(result.getEndedOutcome(), result.getEndedOutput(), request,
|
||||
response);
|
||||
} else {
|
||||
MutableAttributeMap input = flowHandler.createExecutionInputMap(request);
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
flowExecutor.launchExecution(flowHandler.getFlowId(), input, context);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleAction(ActionRequest request, ActionResponse response, Object handler) throws Exception {
|
||||
String flowExecutionKey = urlHandler.getFlowExecutionKey(request);
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context);
|
||||
if (result.paused()) {
|
||||
urlHandler.setFlowExecutionRenderParameter(flowExecutionKey, response);
|
||||
} else {
|
||||
setEndResult(result, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void setEndResult(FlowExecutionResult result, ActionRequest request) {
|
||||
request.getPortletSession().setAttribute(FLOW_EXECUTION_RESULT, result);
|
||||
}
|
||||
|
||||
public boolean supports(Object handler) {
|
||||
return handler instanceof FlowHandler;
|
||||
}
|
||||
|
||||
private PortletExternalContext createPortletExternalContext(PortletRequest request, PortletResponse response) {
|
||||
return new PortletExternalContext(getPortletContext(), request, response);
|
||||
}
|
||||
}
|
||||
@@ -145,6 +145,10 @@ public class MockExternalContext implements ExternalContext {
|
||||
return flowExecutionRedirectRequested() || flowDefinitionRedirectRequested() || externalRedirectRequested();
|
||||
}
|
||||
|
||||
public boolean isResponseAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void requestFlowExecutionRedirect() {
|
||||
flowExecutionRedirectRequested = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.springframework.webflow.context.portlet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.portlet.MockActionResponse;
|
||||
import org.springframework.mock.web.portlet.MockPortletRequest;
|
||||
import org.springframework.mock.web.portlet.MockRenderResponse;
|
||||
|
||||
public class DefaultFlowUrlHandlerTests extends TestCase {
|
||||
private DefaultFlowUrlHandler urlHandler = new DefaultFlowUrlHandler();
|
||||
private MockPortletRequest request = new MockPortletRequest();
|
||||
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 testCreateFlowExecutionUrl() {
|
||||
String url = urlHandler.createFlowExecutionUrl("foo", "12345", renderResponse);
|
||||
assertEquals("http://localhost/mockportlet?urlType=action;param_execution=12345", url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 java.util.Map.Entry;
|
||||
|
||||
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 otherMap = new HashMap();
|
||||
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", ((Entry) tested.entrySet().iterator().next()).getKey());
|
||||
assertEquals("SomeValue", ((Entry) tested.entrySet().iterator().next()).getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 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.MockPortletRequest;
|
||||
import org.springframework.mock.web.portlet.MockPortletResponse;
|
||||
import org.springframework.webflow.context.servlet.ServletExternalContext;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ServletExternalContext}.
|
||||
*/
|
||||
public class PortletExternalContextTests extends TestCase {
|
||||
|
||||
private MockPortletContext portletContext;
|
||||
|
||||
private MockPortletRequest request;
|
||||
|
||||
private MockPortletResponse response;
|
||||
|
||||
private PortletExternalContext context;
|
||||
|
||||
protected void setUp() {
|
||||
portletContext = new MockPortletContext();
|
||||
request = new MockActionRequest();
|
||||
response = new MockActionResponse();
|
||||
context = new PortletExternalContext(portletContext, request, response);
|
||||
}
|
||||
|
||||
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() {
|
||||
context.setAjaxRequest(true);
|
||||
assertTrue(context.isAjaxRequest());
|
||||
}
|
||||
|
||||
public void testNotResponseCommitted() {
|
||||
assertFalse(context.isResponseCommitted());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirect() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.flowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirect() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.flowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirect() {
|
||||
context.requestExternalRedirect("foo");
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.externalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
}
|
||||
|
||||
public void testCommitExecutionRedirectPopup() {
|
||||
context.requestFlowExecutionRedirect();
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.flowExecutionRedirectRequested());
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
public void testCommitFlowRedirectPopup() {
|
||||
context.requestFlowDefinitionRedirect("foo", null);
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.flowDefinitionRedirectRequested());
|
||||
assertEquals("foo", context.getFlowRedirectFlowId());
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
public void testCommitExternalRedirectPopup() {
|
||||
context.requestExternalRedirect("foo");
|
||||
context.requestRedirectInPopup();
|
||||
assertTrue(context.isResponseCommitted());
|
||||
assertTrue(context.externalRedirectRequested());
|
||||
assertEquals("foo", context.getExternalRedirectUrl());
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
public void testResponseAllowed() {
|
||||
assertFalse(context.isResponseAllowed());
|
||||
}
|
||||
|
||||
public void testIsActionPhase() {
|
||||
assertTrue(context.isActionPhase());
|
||||
}
|
||||
|
||||
public void testIsRenderPhase() {
|
||||
assertFalse(context.isRenderPhase());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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");
|
||||
request.removeAttribute("javax.servlet.context.tempdir");
|
||||
// perform test
|
||||
Iterator names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertTrue("More elements", names.hasNext());
|
||||
String name = (String) names.next();
|
||||
assertEquals("Some key", name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertTrue("More elements", names.hasNext());
|
||||
String name = (String) names.next();
|
||||
assertEquals("Some param", name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 names = tested.getAttributeNames();
|
||||
assertNotNull("Null result unexpected", names);
|
||||
assertTrue("More elements", names.hasNext());
|
||||
String name = (String) names.next();
|
||||
assertEquals("Some key", name);
|
||||
}
|
||||
|
||||
public void testGetAttributeNamesNullSession() {
|
||||
request.setSession(null);
|
||||
// perform test
|
||||
Iterator 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);
|
||||
}
|
||||
}
|
||||
@@ -115,4 +115,8 @@ public class ServletExternalContextTests extends TestCase {
|
||||
assertTrue(context.redirectInPopup());
|
||||
}
|
||||
|
||||
public void testResponseAllowed() {
|
||||
assertTrue(context.isResponseAllowed());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.context.servlet;
|
||||
package org.springframework.webflow.context.web;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
@@ -21,6 +21,7 @@ import javax.servlet.http.HttpSession;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.webflow.context.servlet.HttpSessionMap;
|
||||
import org.springframework.webflow.core.collection.AttributeMapBindingEvent;
|
||||
import org.springframework.webflow.core.collection.AttributeMapBindingListener;
|
||||
|
||||
Reference in New Issue
Block a user