mirror of
https://github.com/apache/struts.git
synced 2026-08-31 19:35:40 +00:00
WW-1645 Refactored portlet support into a plugin.
git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@557544 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
<module>struts1</module>
|
||||
<module>tiles</module>
|
||||
<module>dojo</module>
|
||||
<module>portlet</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-portlet-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Struts 2 Portlet Plugin</name>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/portlet/</connection>
|
||||
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/portlet/</developerConnection>
|
||||
<url>http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/plugins/portlet/</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>3.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jsp-api</artifactId>
|
||||
<version>2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Velocity -->
|
||||
<dependency>
|
||||
<groupId>velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
<version>1.4</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>velocity-tools</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
<version>1.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Portlet -->
|
||||
<dependency>
|
||||
<groupId>portlet-api</groupId>
|
||||
<artifactId>portlet-api</artifactId>
|
||||
<version>1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mockobjects</groupId>
|
||||
<artifactId>mockobjects-jdk1.3-j2ee1.3</artifactId>
|
||||
<version>0.09</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jmock</groupId>
|
||||
<artifactId>jmock</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jmock</groupId>
|
||||
<artifactId>jmock-cglib</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mockobjects</groupId>
|
||||
<artifactId>mockobjects-core</artifactId>
|
||||
<version>0.09</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Mocks for unit testing (by Spring) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-mock</artifactId>
|
||||
<version>1.2.8</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>1.2.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,104 @@
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.components.URL;
|
||||
import org.apache.struts2.components.UrlRenderer;
|
||||
import org.apache.struts2.portlet.util.PortletUrlHelper;
|
||||
|
||||
import com.opensymphony.xwork2.util.TextUtils;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link URLRenderer} interface that renders URLs for portlet environments.
|
||||
*
|
||||
* @see URLRenderer
|
||||
*
|
||||
*/
|
||||
public class PortletUrlRenderer implements UrlRenderer {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void renderUrl(Writer writer, URL urlComponent) {
|
||||
String scheme = urlComponent.req.getScheme();
|
||||
|
||||
if (urlComponent.scheme != null) {
|
||||
scheme = urlComponent.scheme;
|
||||
}
|
||||
|
||||
String result;
|
||||
if (urlComponent.value == null && urlComponent.action != null) {
|
||||
result = PortletUrlHelper.buildUrl(urlComponent.action, urlComponent.namespace, urlComponent.parameters, urlComponent.portletUrlType, urlComponent.portletMode, urlComponent.windowState);
|
||||
} else {
|
||||
result = PortletUrlHelper.buildResourceUrl(urlComponent.value, urlComponent.parameters);
|
||||
}
|
||||
if ( urlComponent.anchor != null && urlComponent.anchor.length() > 0 ) {
|
||||
result += '#' + urlComponent.anchor;
|
||||
}
|
||||
|
||||
String var = urlComponent.getVar();
|
||||
|
||||
if (var != null) {
|
||||
urlComponent.putInContext(result);
|
||||
|
||||
// add to the request and page scopes as well
|
||||
urlComponent.req.setAttribute(var, result);
|
||||
} else {
|
||||
try {
|
||||
writer.write(result);
|
||||
} catch (IOException e) {
|
||||
throw new StrutsException("IOError: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void renderFormUrl(Form formComponent) {
|
||||
String action = null;
|
||||
if (formComponent.action != null) {
|
||||
// if it isn't specified, we'll make somethig up
|
||||
action = formComponent.findString(formComponent.action);
|
||||
}
|
||||
|
||||
String type = "action";
|
||||
if (TextUtils.stringSet(formComponent.method)) {
|
||||
if ("GET".equalsIgnoreCase(formComponent.method.trim())) {
|
||||
type = "render";
|
||||
}
|
||||
}
|
||||
if (action != null) {
|
||||
String result = PortletUrlHelper.buildUrl(action, formComponent.namespace,
|
||||
formComponent.getParameters(), type, formComponent.portletMode, formComponent.windowState);
|
||||
formComponent.addParameter("action", result);
|
||||
|
||||
// namespace: cut out anything between the start and the last /
|
||||
int slash = result.lastIndexOf('/');
|
||||
if (slash != -1) {
|
||||
formComponent.addParameter("namespace", result.substring(0, slash));
|
||||
} else {
|
||||
formComponent.addParameter("namespace", "");
|
||||
}
|
||||
|
||||
// name/id: cut out anything between / and . should be the id and
|
||||
// name
|
||||
String id = formComponent.getId();
|
||||
if (id == null) {
|
||||
slash = action.lastIndexOf('/');
|
||||
int dot = action.indexOf('.', slash);
|
||||
if (dot != -1) {
|
||||
id = action.substring(slash + 1, dot);
|
||||
} else {
|
||||
id = action.substring(slash + 1);
|
||||
}
|
||||
formComponent.addParameter("id", formComponent.escape(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
/**
|
||||
* Interface defining some constants used in the Struts portlet implementation
|
||||
*
|
||||
*/
|
||||
public interface PortletActionConstants {
|
||||
/**
|
||||
* Default action name to use when no default action has been configured in the portlet
|
||||
* init parameters.
|
||||
*/
|
||||
String DEFAULT_ACTION_NAME = "default";
|
||||
|
||||
/**
|
||||
* Action name parameter name
|
||||
*/
|
||||
String ACTION_PARAM = "struts.portlet.action";
|
||||
|
||||
/**
|
||||
* Key for parameter holding the last executed portlet mode.
|
||||
*/
|
||||
String MODE_PARAM = "struts.portlet.mode";
|
||||
|
||||
/**
|
||||
* Key used for looking up and storing the portlet phase
|
||||
*/
|
||||
String PHASE = "struts.portlet.phase";
|
||||
|
||||
/**
|
||||
* Constant used for the render phase (
|
||||
* {@link javax.portlet.Portlet#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse)})
|
||||
*/
|
||||
Integer RENDER_PHASE = new Integer(1);
|
||||
|
||||
/**
|
||||
* Constant used for the event phase (
|
||||
* {@link javax.portlet.Portlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)})
|
||||
*/
|
||||
Integer EVENT_PHASE = new Integer(2);
|
||||
|
||||
/**
|
||||
* Key used for looking up and storing the
|
||||
* {@link javax.portlet.PortletRequest}
|
||||
*/
|
||||
String REQUEST = "struts.portlet.request";
|
||||
|
||||
/**
|
||||
* Key used for looking up and storing the
|
||||
* {@link javax.portlet.PortletResponse}
|
||||
*/
|
||||
String RESPONSE = "struts.portlet.response";
|
||||
|
||||
/**
|
||||
* Key used for looking up and storing the action that was invoked in the event phase.
|
||||
*/
|
||||
String EVENT_ACTION = "struts.portlet.eventAction";
|
||||
|
||||
/**
|
||||
* Key used for looking up and storing the
|
||||
* {@link javax.portlet.PortletConfig}
|
||||
*/
|
||||
String PORTLET_CONFIG = "struts.portlet.config";
|
||||
|
||||
/**
|
||||
* Name of the action used as error handler
|
||||
*/
|
||||
String ERROR_ACTION = "errorHandler";
|
||||
|
||||
/**
|
||||
* Key for the portlet namespace stored in the
|
||||
* {@link org.apache.struts2.portlet.context.PortletActionContext}.
|
||||
*/
|
||||
String PORTLET_NAMESPACE = "struts.portlet.portletNamespace";
|
||||
|
||||
/**
|
||||
* Key for the mode-to-namespace map stored in the
|
||||
* {@link org.apache.struts2.portlet.context.PortletActionContext}.
|
||||
*/
|
||||
String MODE_NAMESPACE_MAP = "struts.portlet.modeNamespaceMap";
|
||||
|
||||
/**
|
||||
* Key for the default action name for the portlet, stored in the
|
||||
* {@link org.apache.struts2.portlet.context.PortletActionContext}.
|
||||
*/
|
||||
String DEFAULT_ACTION_FOR_MODE = "struts.portlet.defaultActionForMode";
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
|
||||
/**
|
||||
* Portlet specific {@link java.util.Map} implementation representing the
|
||||
* {@link javax.portlet.PortletContext} of a Portlet.
|
||||
*
|
||||
*/
|
||||
public class PortletApplicationMap extends AbstractMap implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2296107511063504414L;
|
||||
|
||||
private PortletContext context;
|
||||
|
||||
private Set<Object> entries;
|
||||
|
||||
/**
|
||||
* Creates a new map object given the {@link PortletContext}.
|
||||
*
|
||||
* @param ctx The portlet context.
|
||||
*/
|
||||
public PortletApplicationMap(PortletContext ctx) {
|
||||
this.context = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all entries from the Map and removes all attributes from the
|
||||
* portlet context.
|
||||
*/
|
||||
public void clear() {
|
||||
entries = null;
|
||||
|
||||
Enumeration e = context.getAttributeNames();
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
context.removeAttribute(e.nextElement().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Set of all portlet context attributes as well as context init
|
||||
* parameters.
|
||||
*
|
||||
* @return a Set of all portlet context attributes as well as context init
|
||||
* parameters.
|
||||
*/
|
||||
public Set entrySet() {
|
||||
if (entries == null) {
|
||||
entries = new HashSet<Object>();
|
||||
|
||||
// Add portlet context attributes
|
||||
Enumeration enumeration = context.getAttributeNames();
|
||||
|
||||
while (enumeration.hasMoreElements()) {
|
||||
final String key = enumeration.nextElement().toString();
|
||||
final Object value = context.getAttribute(key);
|
||||
entries.add(new Map.Entry() {
|
||||
public boolean equals(Object obj) {
|
||||
Map.Entry entry = (Map.Entry) obj;
|
||||
|
||||
return ((key == null) ? (entry.getKey() == null) : key
|
||||
.equals(entry.getKey()))
|
||||
&& ((value == null) ? (entry.getValue() == null)
|
||||
: value.equals(entry.getValue()));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((key == null) ? 0 : key.hashCode())
|
||||
^ ((value == null) ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object setValue(Object obj) {
|
||||
context.setAttribute(key.toString(), obj);
|
||||
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add portlet context init params
|
||||
enumeration = context.getInitParameterNames();
|
||||
|
||||
while (enumeration.hasMoreElements()) {
|
||||
final String key = enumeration.nextElement().toString();
|
||||
final Object value = context.getInitParameter(key);
|
||||
entries.add(new Map.Entry() {
|
||||
public boolean equals(Object obj) {
|
||||
Map.Entry entry = (Map.Entry) obj;
|
||||
|
||||
return ((key == null) ? (entry.getKey() == null) : key
|
||||
.equals(entry.getKey()))
|
||||
&& ((value == null) ? (entry.getValue() == null)
|
||||
: value.equals(entry.getValue()));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((key == null) ? 0 : key.hashCode())
|
||||
^ ((value == null) ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object setValue(Object obj) {
|
||||
context.setAttribute(key.toString(), obj);
|
||||
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the portlet context attribute or init parameter based on the
|
||||
* given key. If the entry is not found, <tt>null</tt> is returned.
|
||||
*
|
||||
* @param key
|
||||
* the entry key.
|
||||
* @return the portlet context attribute or init parameter or <tt>null</tt>
|
||||
* if the entry is not found.
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
// Try context attributes first, then init params
|
||||
// This gives the proper shadowing effects
|
||||
String keyString = key.toString();
|
||||
Object value = context.getAttribute(keyString);
|
||||
|
||||
return (value == null) ? context.getInitParameter(keyString) : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a portlet context attribute given a attribute name and value.
|
||||
*
|
||||
* @param key
|
||||
* the name of the attribute.
|
||||
* @param value
|
||||
* the value to set.
|
||||
* @return the attribute that was just set.
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
entries = null;
|
||||
context.setAttribute(key.toString(), value);
|
||||
|
||||
return get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified portlet context attribute.
|
||||
*
|
||||
* @param key
|
||||
* the attribute to remove.
|
||||
* @return the entry that was just removed.
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
entries = null;
|
||||
|
||||
Object value = get(key);
|
||||
context.removeAttribute(key.toString());
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A simple implementation of the {@link java.util.Map} interface to handle a collection of request attributes.
|
||||
*
|
||||
*/
|
||||
public class PortletRequestMap extends AbstractMap {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(PortletRequestMap.class);
|
||||
|
||||
private Set<Object> entries = null;
|
||||
private PortletRequest request = null;
|
||||
|
||||
/**
|
||||
* Saves the request to use as the backing for getting and setting values
|
||||
*
|
||||
* @param request the portlet request.
|
||||
*/
|
||||
public PortletRequestMap(PortletRequest request) {
|
||||
this.request = request;
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debug("Dumping request parameters: ");
|
||||
Iterator params = request.getParameterMap().keySet().iterator();
|
||||
while(params.hasNext()) {
|
||||
String key = (String)params.next();
|
||||
String val = request.getParameter(key);
|
||||
LOG.debug(key + " = " + val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all attributes from the request as well as clears entries in this
|
||||
* map.
|
||||
*/
|
||||
public void clear() {
|
||||
entries = null;
|
||||
Enumeration keys = request.getAttributeNames();
|
||||
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = (String) keys.nextElement();
|
||||
request.removeAttribute(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Set of attributes from the portlet request.
|
||||
*
|
||||
* @return a Set of attributes from the portlet request.
|
||||
*/
|
||||
public Set entrySet() {
|
||||
if (entries == null) {
|
||||
entries = new HashSet<Object>();
|
||||
|
||||
Enumeration enumeration = request.getAttributeNames();
|
||||
|
||||
while (enumeration.hasMoreElements()) {
|
||||
final String key = enumeration.nextElement().toString();
|
||||
final Object value = request.getAttribute(key);
|
||||
entries.add(new Entry() {
|
||||
public boolean equals(Object obj) {
|
||||
Entry entry = (Entry) obj;
|
||||
|
||||
return ((key == null) ? (entry.getKey() == null) : key
|
||||
.equals(entry.getKey()))
|
||||
&& ((value == null) ? (entry.getValue() == null)
|
||||
: value.equals(entry.getValue()));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((key == null) ? 0 : key.hashCode())
|
||||
^ ((value == null) ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object setValue(Object obj) {
|
||||
request.setAttribute(key, obj);
|
||||
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request attribute associated with the given key or
|
||||
* <tt>null</tt> if it doesn't exist.
|
||||
*
|
||||
* @param key the name of the request attribute.
|
||||
* @return the request attribute or <tt>null</tt> if it doesn't exist.
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
return request.getAttribute(key.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an attribute in the request.
|
||||
*
|
||||
* @param key the name of the request attribute.
|
||||
* @param value the value to set.
|
||||
* @return the object that was just set.
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
entries = null;
|
||||
request.setAttribute(key.toString(), value);
|
||||
|
||||
return get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified request attribute.
|
||||
*
|
||||
* @param key the name of the attribute to remove.
|
||||
* @return the value that was removed or <tt>null</tt> if the value was
|
||||
* not found (and hence, not removed).
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
entries = null;
|
||||
|
||||
Object value = get(key);
|
||||
request.removeAttribute(key.toString());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletSession;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A simple implementation of the {@link java.util.Map} interface to handle a collection of portlet session
|
||||
* attributes. The {@link #entrySet()} method enumerates over all session attributes and creates a Set of entries.
|
||||
* Note, this will occur lazily - only when the entry set is asked for.
|
||||
*
|
||||
*/
|
||||
public class PortletSessionMap extends AbstractMap {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(PortletSessionMap.class);
|
||||
|
||||
private PortletSession session = null;
|
||||
private Set<Object> entries = null;
|
||||
|
||||
/**
|
||||
* Creates a new session map given a portlet request.
|
||||
*
|
||||
* @param request the portlet request object.
|
||||
*/
|
||||
public PortletSessionMap(PortletRequest request) {
|
||||
this.session = request.getPortletSession();
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debug("Dumping session info: ");
|
||||
Enumeration enumeration = session.getAttributeNames();
|
||||
while(enumeration.hasMoreElements()) {
|
||||
String key = (String)enumeration.nextElement();
|
||||
Object val = session.getAttribute(key);
|
||||
LOG.debug(key + " = " + val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#entrySet()
|
||||
*/
|
||||
public Set entrySet() {
|
||||
synchronized (session) {
|
||||
if (entries == null) {
|
||||
entries = new HashSet<Object>();
|
||||
|
||||
Enumeration enumeration = session.getAttributeNames();
|
||||
|
||||
while (enumeration.hasMoreElements()) {
|
||||
final String key = enumeration.nextElement().toString();
|
||||
final Object value = session.getAttribute(key);
|
||||
entries.add(new Map.Entry() {
|
||||
public boolean equals(Object obj) {
|
||||
Map.Entry entry = (Map.Entry) obj;
|
||||
|
||||
return ((key == null) ? (entry.getKey() == null)
|
||||
: key.equals(entry.getKey()))
|
||||
&& ((value == null) ? (entry.getValue() == null)
|
||||
: value.equals(entry.getValue()));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((key == null) ? 0 : key.hashCode())
|
||||
^ ((value == null) ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object setValue(Object obj) {
|
||||
session.setAttribute(key, obj);
|
||||
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session attribute associated with the given key or
|
||||
* <tt>null</tt> if it doesn't exist.
|
||||
*
|
||||
* @param key the name of the session attribute.
|
||||
* @return the session attribute or <tt>null</tt> if it doesn't exist.
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
synchronized (session) {
|
||||
return session.getAttribute(key.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an attribute in the session.
|
||||
*
|
||||
* @param key the name of the session attribute.
|
||||
* @param value the value to set.
|
||||
* @return the object that was just set.
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
synchronized (session) {
|
||||
entries = null;
|
||||
session.setAttribute(key.toString(), value);
|
||||
|
||||
return get(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Map#clear()
|
||||
*/
|
||||
public void clear() {
|
||||
synchronized (session) {
|
||||
entries = null;
|
||||
session.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified session attribute.
|
||||
*
|
||||
* @param key the name of the attribute to remove.
|
||||
* @return the value that was removed or <tt>null</tt> if the value was
|
||||
* not found (and hence, not removed).
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
synchronized (session) {
|
||||
entries = null;
|
||||
|
||||
Object value = get(key);
|
||||
session.removeAttribute(key.toString());
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.context;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
|
||||
|
||||
/**
|
||||
* PortletActionContext. ActionContext thread local for the portlet environment.
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class PortletActionContext implements PortletActionConstants {
|
||||
|
||||
/**
|
||||
* Get the PortletConfig of the portlet that is executing.
|
||||
*
|
||||
* @return The PortletConfig of the executing portlet.
|
||||
*/
|
||||
public static PortletConfig getPortletConfig() {
|
||||
return (PortletConfig) getContext().get(PORTLET_CONFIG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RenderRequest. Can only be invoked in the render phase.
|
||||
*
|
||||
* @return The current RenderRequest.
|
||||
* @throws IllegalStateException If the method is invoked in the wrong phase.
|
||||
*/
|
||||
public static RenderRequest getRenderRequest() {
|
||||
if (!isRender()) {
|
||||
throw new IllegalStateException(
|
||||
"RenderRequest cannot be obtained in event phase");
|
||||
}
|
||||
return (RenderRequest) getContext().get(REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RenderResponse. Can only be invoked in the render phase.
|
||||
*
|
||||
* @return The current RenderResponse.
|
||||
* @throws IllegalStateException If the method is invoked in the wrong phase.
|
||||
*/
|
||||
public static RenderResponse getRenderResponse() {
|
||||
if (!isRender()) {
|
||||
throw new IllegalStateException(
|
||||
"RenderResponse cannot be obtained in event phase");
|
||||
}
|
||||
return (RenderResponse) getContext().get(RESPONSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ActionRequest. Can only be invoked in the event phase.
|
||||
*
|
||||
* @return The current ActionRequest.
|
||||
* @throws IllegalStateException If the method is invoked in the wrong phase.
|
||||
*/
|
||||
public static ActionRequest getActionRequest() {
|
||||
if (!isEvent()) {
|
||||
throw new IllegalStateException(
|
||||
"ActionRequest cannot be obtained in render phase");
|
||||
}
|
||||
return (ActionRequest) getContext().get(REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ActionRequest. Can only be invoked in the event phase.
|
||||
*
|
||||
* @return The current ActionRequest.
|
||||
* @throws IllegalStateException If the method is invoked in the wrong phase.
|
||||
*/
|
||||
public static ActionResponse getActionResponse() {
|
||||
if (!isEvent()) {
|
||||
throw new IllegalStateException(
|
||||
"ActionResponse cannot be obtained in render phase");
|
||||
}
|
||||
return (ActionResponse) getContext().get(RESPONSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action namespace of the portlet. Used to organize actions for multiple portlets in
|
||||
* the same portlet application.
|
||||
*
|
||||
* @return The portlet namespace as defined in <code>portlet.xml</code> and <code>struts.xml</code>
|
||||
*/
|
||||
public static String getPortletNamespace() {
|
||||
return (String)getContext().get(PORTLET_NAMESPACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current PortletRequest.
|
||||
*
|
||||
* @return The current PortletRequest.
|
||||
*/
|
||||
public static PortletRequest getRequest() {
|
||||
return (PortletRequest) getContext().get(REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current PortletResponse
|
||||
*
|
||||
* @return The current PortletResponse.
|
||||
*/
|
||||
public static PortletResponse getResponse() {
|
||||
return (PortletResponse) getContext().get(RESPONSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the phase that the portlet is executing in.
|
||||
*
|
||||
* @return {@link PortletActionConstants#RENDER_PHASE} in render phase, and
|
||||
* {@link PortletActionConstants#EVENT_PHASE} in the event phase.
|
||||
*/
|
||||
public static Integer getPhase() {
|
||||
return (Integer) getContext().get(PHASE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the Portlet is executing in render phase.
|
||||
*/
|
||||
public static boolean isRender() {
|
||||
return PortletActionConstants.RENDER_PHASE.equals(getPhase());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the Portlet is executing in the event phase.
|
||||
*/
|
||||
public static boolean isEvent() {
|
||||
return PortletActionConstants.EVENT_PHASE.equals(getPhase());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The current ActionContext.
|
||||
*/
|
||||
private static ActionContext getContext() {
|
||||
return ActionContext.getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the current request is a portlet request.
|
||||
*
|
||||
* @return <code>true</code> if the current request is a portlet request.
|
||||
*/
|
||||
public static boolean isPortletRequest() {
|
||||
return getRequest() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default action mapping for the current mode.
|
||||
*
|
||||
* @return The default action mapping for the current portlet mode.
|
||||
*/
|
||||
public static ActionMapping getDefaultActionForMode() {
|
||||
return (ActionMapping)getContext().get(DEFAULT_ACTION_FOR_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace to mode mappings.
|
||||
*
|
||||
* @return The map of the namespaces for each mode.
|
||||
*/
|
||||
public static Map getModeNamespaceMap() {
|
||||
return (Map)getContext().get(MODE_NAMESPACE_MAP);
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.context;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
|
||||
/**
|
||||
* Since a portlet is not dispatched the same way as a servlet, the
|
||||
* {@link org.apache.struts2.ServletActionContext} is not immediately available, as it
|
||||
* depends on objects from the servlet API. However, the WW2 view implementations require access
|
||||
* to the objects in the {@link org.apache.struts2.ServletActionContext}, and this servlet
|
||||
* makes sure that these are available when the portlet actions are executing the render results.
|
||||
*
|
||||
*/
|
||||
public class PreparatorServlet extends HttpServlet implements StrutsStatics {
|
||||
|
||||
private static final long serialVersionUID = 1853399729352984089L;
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(PreparatorServlet.class);
|
||||
|
||||
/**
|
||||
* Prepares the {@link org.apache.struts2.ServletActionContext} with the
|
||||
* {@link ServletContext}, {@link HttpServletRequest} and {@link HttpServletResponse}.
|
||||
*/
|
||||
public void service(HttpServletRequest servletRequest,
|
||||
HttpServletResponse servletResponse) throws ServletException,
|
||||
IOException {
|
||||
LOG.debug("Preparing servlet objects for dispatch");
|
||||
ServletContext ctx = getServletContext();
|
||||
ActionContext.getContext().put(SERVLET_CONTEXT, ctx);
|
||||
ActionContext.getContext().put(HTTP_REQUEST, servletRequest);
|
||||
ActionContext.getContext().put(HTTP_RESPONSE, servletResponse);
|
||||
LOG.debug("Preparation complete");
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.context;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
/**
|
||||
* Some of the factory/managers (e.g. the ObjectFactory) need access to
|
||||
* the {@link org.apache.struts2.ServletActionContext} object when initializing.
|
||||
* This {@link javax.servlet.ServletContextListener} keeps a reference to the
|
||||
* {@link javax.servlet.ServletContext} and exposes it through a <code>public static</code>
|
||||
* method.
|
||||
*
|
||||
*/
|
||||
public class ServletContextHolderListener implements ServletContextListener {
|
||||
|
||||
private static ServletContext context = null;
|
||||
|
||||
/**
|
||||
* @return The current servlet context
|
||||
*/
|
||||
public static ServletContext getServletContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the reference to the {@link ServletContext}.
|
||||
*
|
||||
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
|
||||
*/
|
||||
public void contextInitialized(ServletContextEvent event) {
|
||||
context = event.getServletContext();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
|
||||
*/
|
||||
public void contextDestroyed(ServletContextEvent event) {
|
||||
context = null;
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.dispatcher;
|
||||
|
||||
import com.opensymphony.xwork2.Action;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* When a portlet is targetted for an <code>event</code>, the portlet will receive two
|
||||
* portlet requests, one for the <code>event</code> phase, and then followed by a <code>render</code>
|
||||
* operation. When in the <code>event</code> phase, the action that is executed can't render
|
||||
* any output. This means that if an action in the XWork configuration is executed in the event
|
||||
* phase, and the action is set up with a result that should render something, the result can't
|
||||
* immediately be executed. The portlet needs to "wait" to the render phase to do the
|
||||
* rendering.
|
||||
* <p/>
|
||||
* When the {@link org.apache.struts2.portlet.result.PortletResult} detects such a
|
||||
* scenario, instead of executing the actual view, it prepares a couple of render parameters
|
||||
* specifying this action and the location of the view, which then will be executed in the
|
||||
* following render request.
|
||||
*/
|
||||
public class DirectRenderFromEventAction implements Action, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1814807772308405785L;
|
||||
|
||||
private String location = null;
|
||||
|
||||
/**
|
||||
* Get the location of the view.
|
||||
*
|
||||
* @return Returns the location.
|
||||
*/
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of the view.
|
||||
*
|
||||
* @param location The location to set.
|
||||
*/
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always return success.
|
||||
*
|
||||
* @return SUCCESS
|
||||
*/
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
+608
@@ -0,0 +1,608 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.dispatcher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.GenericPortlet;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.WindowState;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.dispatcher.ApplicationMap;
|
||||
import org.apache.struts2.dispatcher.Dispatcher;
|
||||
import org.apache.struts2.dispatcher.RequestMap;
|
||||
import org.apache.struts2.dispatcher.SessionMap;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.PortletApplicationMap;
|
||||
import org.apache.struts2.portlet.PortletRequestMap;
|
||||
import org.apache.struts2.portlet.PortletSessionMap;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import org.apache.struts2.portlet.context.ServletContextHolderListener;
|
||||
import org.apache.struts2.portlet.util.HttpServletRequestMock;
|
||||
import org.apache.struts2.util.AttributeMap;
|
||||
|
||||
import com.opensymphony.xwork2.util.FileManager;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.ActionProxyFactory;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.util.LocalizedTextUtil;
|
||||
import com.opensymphony.xwork2.util.TextUtils;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: javadoc -->
|
||||
* <p>
|
||||
* Struts JSR-168 portlet dispatcher. Similar to the WW2 Servlet dispatcher,
|
||||
* but adjusted to a portal environment. The portlet is configured through the <tt>portlet.xml</tt>
|
||||
* descriptor. Examples and descriptions follow below:
|
||||
* </p>
|
||||
* <!-- END SNIPPET: javadoc -->
|
||||
*
|
||||
* @author <a href="nils-helge.garli@bekk.no">Nils-Helge Garli </a>
|
||||
* @author Rainer Hermanns
|
||||
*
|
||||
* <p><b>Init parameters</b></p>
|
||||
* <!-- START SNIPPET: params -->
|
||||
* <table class="confluenceTable">
|
||||
* <tr>
|
||||
* <th class="confluenceTh">Name</th>
|
||||
* <th class="confluenceTh">Description</th>
|
||||
* <th class="confluenceTh">Default value</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">portletNamespace</td><td class="confluenceTd">The namespace for the portlet in the xwork configuration. This
|
||||
* namespace is prepended to all action lookups, and makes it possible to host multiple
|
||||
* portlets in the same portlet application. If this parameter is set, the complete namespace
|
||||
* will be <tt>/portletNamespace/modeNamespace/actionName</tt></td><td class="confluenceTd">The default namespace</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">viewNamespace</td><td class="confluenceTd">Base namespace in the xwork configuration for the <tt>view</tt> portlet
|
||||
* mode</td><td class="confluenceTd">The default namespace</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">editNamespace</td><td class="confluenceTd">Base namespace in the xwork configuration for the <tt>edit</tt> portlet
|
||||
* mode</td><td class="confluenceTd">The default namespace</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">helpNamespace</td><td class="confluenceTd">Base namespace in the xwork configuration for the <tt>help</tt> portlet
|
||||
* mode</td><td class="confluenceTd">The default namespace</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">defaultViewAction</td><td class="confluenceTd">Default action to invoke in the <tt>view</tt> portlet mode if no action is
|
||||
* specified</td><td class="confluenceTd"><tt>default</tt></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">defaultEditAction</td><td class="confluenceTd">Default action to invoke in the <tt>edit</tt> portlet mode if no action is
|
||||
* specified</td><td class="confluenceTd"><tt>default</tt></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td class="confluenceTd">defaultHelpAction</td><td class="confluenceTd">Default action to invoke in the <tt>help</tt> portlet mode if no action is
|
||||
* specified</td><td class="confluenceTd"><tt>default</tt></td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* <!-- END SNIPPET: params -->
|
||||
* <p><b>Example:</b></p>
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
*
|
||||
* <init-param>
|
||||
* <!-- The view mode namespace. Maps to a namespace in the xwork config file -->
|
||||
* <name>viewNamespace</name>
|
||||
* <value>/view</value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <!-- The default action to invoke in view mode -->
|
||||
* <name>defaultViewAction</name>
|
||||
* <value>index</value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <!-- The view mode namespace. Maps to a namespace in the xwork config file -->
|
||||
* <name>editNamespace</name>
|
||||
* <value>/edit</value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <!-- The default action to invoke in view mode -->
|
||||
* <name>defaultEditAction</name>
|
||||
* <value>index</value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <!-- The view mode namespace. Maps to a namespace in the xwork config file -->
|
||||
* <name>helpNamespace</name>
|
||||
* <value>/help</value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <!-- The default action to invoke in view mode -->
|
||||
* <name>defaultHelpAction</name>
|
||||
* <value>index</value>
|
||||
* </init-param>
|
||||
*
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*/
|
||||
public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics,
|
||||
PortletActionConstants {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(Jsr168Dispatcher.class);
|
||||
|
||||
private ActionProxyFactory factory = null;
|
||||
|
||||
private Map<PortletMode,String> modeMap = new HashMap<PortletMode,String>(3);
|
||||
|
||||
private Map<PortletMode,ActionMapping> actionMap = new HashMap<PortletMode,ActionMapping>(3);
|
||||
|
||||
private String portletNamespace = null;
|
||||
|
||||
private Dispatcher dispatcherUtils;
|
||||
|
||||
private ActionMapper actionMapper;
|
||||
|
||||
/**
|
||||
* Initialize the portlet with the init parameters from <tt>portlet.xml</tt>
|
||||
*/
|
||||
public void init(PortletConfig cfg) throws PortletException {
|
||||
super.init(cfg);
|
||||
LOG.debug("Initializing portlet " + getPortletName());
|
||||
|
||||
Map<String,String> params = new HashMap<String,String>();
|
||||
for (Enumeration e = cfg.getInitParameterNames(); e.hasMoreElements(); ) {
|
||||
String name = (String) e.nextElement();
|
||||
String value = cfg.getInitParameter(name);
|
||||
params.put(name, value);
|
||||
}
|
||||
|
||||
Dispatcher.setPortletSupportActive(true);
|
||||
dispatcherUtils = new Dispatcher(ServletContextHolderListener.getServletContext(), params);
|
||||
dispatcherUtils.init();
|
||||
|
||||
// For testability
|
||||
if (factory == null) {
|
||||
factory = dispatcherUtils.getConfigurationManager().getConfiguration().getContainer().getInstance(ActionProxyFactory.class);
|
||||
}
|
||||
portletNamespace = cfg.getInitParameter("portletNamespace");
|
||||
LOG.debug("PortletNamespace: " + portletNamespace);
|
||||
parseModeConfig(cfg, PortletMode.VIEW, "viewNamespace",
|
||||
"defaultViewAction");
|
||||
parseModeConfig(cfg, PortletMode.EDIT, "editNamespace",
|
||||
"defaultEditAction");
|
||||
parseModeConfig(cfg, PortletMode.HELP, "helpNamespace",
|
||||
"defaultHelpAction");
|
||||
parseModeConfig(cfg, new PortletMode("config"), "configNamespace",
|
||||
"defaultConfigAction");
|
||||
parseModeConfig(cfg, new PortletMode("about"), "aboutNamespace",
|
||||
"defaultAboutAction");
|
||||
parseModeConfig(cfg, new PortletMode("print"), "printNamespace",
|
||||
"defaultPrintAction");
|
||||
parseModeConfig(cfg, new PortletMode("preview"), "previewNamespace",
|
||||
"defaultPreviewAction");
|
||||
parseModeConfig(cfg, new PortletMode("edit_defaults"),
|
||||
"editDefaultsNamespace", "defaultEditDefaultsAction");
|
||||
if (!TextUtils.stringSet(portletNamespace)) {
|
||||
portletNamespace = "";
|
||||
}
|
||||
LocalizedTextUtil
|
||||
.addDefaultResourceBundle("org/apache/struts2/struts-messages");
|
||||
|
||||
Container container = dispatcherUtils.getContainer();
|
||||
//check for configuration reloading
|
||||
if ("true".equalsIgnoreCase(container.getInstance(String.class, StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD))) {
|
||||
FileManager.setReloadingConfigs(true);
|
||||
}
|
||||
|
||||
actionMapper = container.getInstance(ActionMapper.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the mode to namespace mappings configured in portlet.xml
|
||||
* @param portletConfig The PortletConfig
|
||||
* @param portletMode The PortletMode
|
||||
* @param nameSpaceParam Name of the init parameter where the namespace for the mode
|
||||
* is configured.
|
||||
* @param defaultActionParam Name of the init parameter where the default action to
|
||||
* execute for the mode is configured.
|
||||
*/
|
||||
private void parseModeConfig(PortletConfig portletConfig,
|
||||
PortletMode portletMode, String nameSpaceParam,
|
||||
String defaultActionParam) {
|
||||
String namespace = portletConfig.getInitParameter(nameSpaceParam);
|
||||
if (!TextUtils.stringSet(namespace)) {
|
||||
namespace = "";
|
||||
}
|
||||
modeMap.put(portletMode, namespace);
|
||||
String defaultAction = portletConfig
|
||||
.getInitParameter(defaultActionParam);
|
||||
if (!TextUtils.stringSet(defaultAction)) {
|
||||
defaultAction = DEFAULT_ACTION_NAME;
|
||||
}
|
||||
StringBuffer fullPath = new StringBuffer();
|
||||
if (TextUtils.stringSet(portletNamespace)) {
|
||||
fullPath.append(portletNamespace);
|
||||
}
|
||||
if (TextUtils.stringSet(namespace)) {
|
||||
fullPath.append(namespace).append("/");
|
||||
} else {
|
||||
fullPath.append("/");
|
||||
}
|
||||
fullPath.append(defaultAction);
|
||||
ActionMapping mapping = new ActionMapping();
|
||||
mapping.setName(getActionName(fullPath.toString()));
|
||||
mapping.setNamespace(getNamespace(fullPath.toString()));
|
||||
actionMap.put(portletMode, mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Service an action from the <tt>event</tt> phase.
|
||||
*
|
||||
* @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest,
|
||||
* javax.portlet.ActionResponse)
|
||||
*/
|
||||
public void processAction(ActionRequest request, ActionResponse response)
|
||||
throws PortletException, IOException {
|
||||
LOG.debug("Entering processAction");
|
||||
resetActionContext();
|
||||
try {
|
||||
serviceAction(request, response, getActionMapping(request),
|
||||
getRequestMap(request), getParameterMap(request),
|
||||
getSessionMap(request), getApplicationMap(),
|
||||
portletNamespace, EVENT_PHASE);
|
||||
LOG.debug("Leaving processAction");
|
||||
} finally {
|
||||
ActionContext.setContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Service an action from the <tt>render</tt> phase.
|
||||
*
|
||||
* @see javax.portlet.Portlet#render(javax.portlet.RenderRequest,
|
||||
* javax.portlet.RenderResponse)
|
||||
*/
|
||||
public void render(RenderRequest request, RenderResponse response)
|
||||
throws PortletException, IOException {
|
||||
|
||||
LOG.debug("Entering render");
|
||||
resetActionContext();
|
||||
response.setTitle(getTitle(request));
|
||||
if(!request.getWindowState().equals(WindowState.MINIMIZED)) {
|
||||
try {
|
||||
// Check to see if an event set the render to be included directly
|
||||
serviceAction(request, response, getActionMapping(request),
|
||||
getRequestMap(request), getParameterMap(request),
|
||||
getSessionMap(request), getApplicationMap(),
|
||||
portletNamespace, RENDER_PHASE);
|
||||
LOG.debug("Leaving render");
|
||||
} finally {
|
||||
resetActionContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the action context.
|
||||
*/
|
||||
private void resetActionContext() {
|
||||
ActionContext.setContext(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all application and portlet attributes into a single
|
||||
* <tt>HashMap</tt> to represent the entire <tt>Action</tt> context.
|
||||
*
|
||||
* @param requestMap a Map of all request attributes.
|
||||
* @param parameterMap a Map of all request parameters.
|
||||
* @param sessionMap a Map of all session attributes.
|
||||
* @param applicationMap a Map of all servlet context attributes.
|
||||
* @param request the PortletRequest object.
|
||||
* @param response the PortletResponse object.
|
||||
* @param portletConfig the PortletConfig object.
|
||||
* @param phase The portlet phase (render or action, see
|
||||
* {@link PortletActionConstants})
|
||||
* @return a HashMap representing the <tt>Action</tt> context.
|
||||
*/
|
||||
public HashMap createContextMap(Map requestMap, Map parameterMap,
|
||||
Map sessionMap, Map applicationMap, PortletRequest request,
|
||||
PortletResponse response, PortletConfig portletConfig, Integer phase) {
|
||||
|
||||
// TODO Must put http request/response objects into map for use with
|
||||
// ServletActionContext
|
||||
HashMap<String,Object> extraContext = new HashMap<String,Object>();
|
||||
extraContext.put(ActionContext.PARAMETERS, parameterMap);
|
||||
extraContext.put(ActionContext.SESSION, sessionMap);
|
||||
extraContext.put(ActionContext.APPLICATION, applicationMap);
|
||||
|
||||
String defaultLocale = dispatcherUtils.getContainer().getInstance(String.class, StrutsConstants.STRUTS_LOCALE);
|
||||
Locale locale = null;
|
||||
if (defaultLocale != null) {
|
||||
locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
|
||||
} else {
|
||||
locale = request.getLocale();
|
||||
}
|
||||
extraContext.put(ActionContext.LOCALE, locale);
|
||||
|
||||
extraContext.put(StrutsStatics.STRUTS_PORTLET_CONTEXT, getPortletContext());
|
||||
extraContext.put(REQUEST, request);
|
||||
extraContext.put(RESPONSE, response);
|
||||
extraContext.put(PORTLET_CONFIG, portletConfig);
|
||||
extraContext.put(PORTLET_NAMESPACE, portletNamespace);
|
||||
extraContext.put(DEFAULT_ACTION_FOR_MODE, actionMap.get(request.getPortletMode()));
|
||||
// helpers to get access to request/session/application scope
|
||||
extraContext.put("request", requestMap);
|
||||
extraContext.put("session", sessionMap);
|
||||
extraContext.put("application", applicationMap);
|
||||
extraContext.put("parameters", parameterMap);
|
||||
extraContext.put(MODE_NAMESPACE_MAP, modeMap);
|
||||
|
||||
extraContext.put(PHASE, phase);
|
||||
|
||||
AttributeMap attrMap = new AttributeMap(extraContext);
|
||||
extraContext.put("attr", attrMap);
|
||||
|
||||
return extraContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the action and executes it. This method first creates the action
|
||||
* context from the given parameters then loads an <tt>ActionProxy</tt>
|
||||
* from the given action name and namespace. After that, the action is
|
||||
* executed and output channels throught the response object.
|
||||
*
|
||||
* @param request the HttpServletRequest object.
|
||||
* @param response the HttpServletResponse object.
|
||||
* @param mapping the action mapping.
|
||||
* @param requestMap a Map of request attributes.
|
||||
* @param parameterMap a Map of request parameters.
|
||||
* @param sessionMap a Map of all session attributes.
|
||||
* @param applicationMap a Map of all application attributes.
|
||||
* @param portletNamespace the namespace or context of the action.
|
||||
* @param phase The portlet phase (render or action, see
|
||||
* {@link PortletActionConstants})
|
||||
*/
|
||||
public void serviceAction(PortletRequest request, PortletResponse response,
|
||||
ActionMapping mapping, Map requestMap, Map parameterMap,
|
||||
Map sessionMap, Map applicationMap, String portletNamespace,
|
||||
Integer phase) throws PortletException {
|
||||
LOG.debug("serviceAction");
|
||||
HashMap extraContext = createContextMap(requestMap, parameterMap,
|
||||
sessionMap, applicationMap, request, response,
|
||||
getPortletConfig(), phase);
|
||||
String actionName = mapping.getName();
|
||||
String namespace = mapping.getNamespace();
|
||||
Dispatcher.setInstance(dispatcherUtils);
|
||||
try {
|
||||
LOG.debug("Creating action proxy for name = " + actionName
|
||||
+ ", namespace = " + namespace);
|
||||
ActionProxy proxy = factory.createActionProxy(namespace,
|
||||
actionName, extraContext);
|
||||
proxy.setMethod(mapping.getMethod());
|
||||
request.setAttribute("struts.valueStack", proxy.getInvocation()
|
||||
.getStack());
|
||||
if (PortletActionConstants.RENDER_PHASE.equals(phase)
|
||||
&& TextUtils.stringSet(request
|
||||
.getParameter(EVENT_ACTION))) {
|
||||
|
||||
ActionProxy action = (ActionProxy) request.getPortletSession()
|
||||
.getAttribute(EVENT_ACTION);
|
||||
if (action != null) {
|
||||
ValueStack stack = proxy.getInvocation().getStack();
|
||||
Object top = stack.pop();
|
||||
stack.push(action.getInvocation().getAction());
|
||||
stack.push(top);
|
||||
}
|
||||
}
|
||||
proxy.execute();
|
||||
if (PortletActionConstants.EVENT_PHASE.equals(phase)) {
|
||||
// Store the executed action in the session for retrieval in the
|
||||
// render phase.
|
||||
ActionResponse actionResp = (ActionResponse) response;
|
||||
request.getPortletSession().setAttribute(EVENT_ACTION, proxy);
|
||||
actionResp.setRenderParameter(EVENT_ACTION, "true");
|
||||
}
|
||||
} catch (ConfigurationException e) {
|
||||
LOG.error("Could not find action", e);
|
||||
throw new PortletException("Could not find action " + actionName, e);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not execute action", e);
|
||||
throw new PortletException("Error executing action " + actionName,
|
||||
e);
|
||||
} finally {
|
||||
Dispatcher.setInstance(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map of all application attributes. Copies all attributes from
|
||||
* the {@link PortletActionContext}into an {@link ApplicationMap}.
|
||||
*
|
||||
* @return a Map of all application attributes.
|
||||
*/
|
||||
protected Map getApplicationMap() {
|
||||
return new PortletApplicationMap(getPortletContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the namespace of the action from the request. The namespace is the
|
||||
* same as the portlet mode. E.g, view mode is mapped to namespace
|
||||
* <code>view</code>, and edit mode is mapped to the namespace
|
||||
* <code>edit</code>
|
||||
*
|
||||
* @param request the PortletRequest object.
|
||||
* @return the namespace of the action.
|
||||
*/
|
||||
protected ActionMapping getActionMapping(final PortletRequest request) {
|
||||
ActionMapping mapping = null;
|
||||
String actionPath = null;
|
||||
if (resetAction(request)) {
|
||||
mapping = (ActionMapping) actionMap.get(request.getPortletMode());
|
||||
} else {
|
||||
actionPath = request.getParameter(ACTION_PARAM);
|
||||
if (!TextUtils.stringSet(actionPath)) {
|
||||
mapping = (ActionMapping) actionMap.get(request
|
||||
.getPortletMode());
|
||||
} else {
|
||||
|
||||
// Use the usual action mapper, but it is expecting an action extension
|
||||
// on the uri, so we add the default one, which should be ok as the
|
||||
// portlet is a portlet first, a servlet second
|
||||
HttpServletRequestMock httpRequest = new HttpServletRequestMock()
|
||||
.setServletPath(actionPath + ".action")
|
||||
.setParameterMap(request.getParameterMap());
|
||||
mapping = actionMapper.getMapping(httpRequest, dispatcherUtils.getConfigurationManager());
|
||||
}
|
||||
}
|
||||
|
||||
if (mapping == null) {
|
||||
throw new StrutsException("Unable to locate action mapping for request, probably due to " +
|
||||
"an invalid action path: "+actionPath);
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace part of the action path.
|
||||
* @param actionPath Full path to action
|
||||
* @return The namespace part.
|
||||
*/
|
||||
String getNamespace(String actionPath) {
|
||||
int idx = actionPath.lastIndexOf('/');
|
||||
String namespace = "";
|
||||
if (idx >= 0) {
|
||||
namespace = actionPath.substring(0, idx);
|
||||
}
|
||||
return namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action name part of the action path.
|
||||
* @param actionPath Full path to action
|
||||
* @return The action name.
|
||||
*/
|
||||
String getActionName(String actionPath) {
|
||||
int idx = actionPath.lastIndexOf('/');
|
||||
String action = actionPath;
|
||||
if (idx >= 0) {
|
||||
action = actionPath.substring(idx + 1);
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map of all request parameters. This implementation just calls
|
||||
* {@link PortletRequest#getParameterMap()}.
|
||||
*
|
||||
* @param request the PortletRequest object.
|
||||
* @return a Map of all request parameters.
|
||||
* @throws IOException if an exception occurs while retrieving the parameter
|
||||
* map.
|
||||
*/
|
||||
protected Map getParameterMap(PortletRequest request) throws IOException {
|
||||
return new HashMap(request.getParameterMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map of all request attributes. The default implementation is to
|
||||
* wrap the request in a {@link RequestMap}. Override this method to
|
||||
* customize how request attributes are mapped.
|
||||
*
|
||||
* @param request the PortletRequest object.
|
||||
* @return a Map of all request attributes.
|
||||
*/
|
||||
protected Map getRequestMap(PortletRequest request) {
|
||||
return new PortletRequestMap(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map of all session attributes. The default implementation is to
|
||||
* wrap the reqeust in a {@link SessionMap}. Override this method to
|
||||
* customize how session attributes are mapped.
|
||||
*
|
||||
* @param request the PortletRequest object.
|
||||
* @return a Map of all session attributes.
|
||||
*/
|
||||
protected Map getSessionMap(PortletRequest request) {
|
||||
return new PortletSessionMap(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to ease testing.
|
||||
* @param factory
|
||||
*/
|
||||
protected void setActionProxyFactory(ActionProxyFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the action parameter is valid for the current portlet mode. If the portlet
|
||||
* mode has been changed with the portal widgets, the action name is invalid, since the
|
||||
* action name belongs to the previous executing portlet mode. If this method evaluates to
|
||||
* <code>true</code> the <code>default<Mode>Action</code> is used instead.
|
||||
* @param request The portlet request.
|
||||
* @return <code>true</code> if the action should be reset.
|
||||
*/
|
||||
private boolean resetAction(PortletRequest request) {
|
||||
boolean reset = false;
|
||||
Map paramMap = request.getParameterMap();
|
||||
String[] modeParam = (String[]) paramMap.get(MODE_PARAM);
|
||||
if (modeParam != null && modeParam.length == 1) {
|
||||
String originatingMode = modeParam[0];
|
||||
String currentMode = request.getPortletMode().toString();
|
||||
if (!currentMode.equals(originatingMode)) {
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
return reset;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (dispatcherUtils == null) {
|
||||
LOG.warn("something is seriously wrong, DispatcherUtil is not initialized (null) ");
|
||||
} else {
|
||||
dispatcherUtils.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actionMapper the actionMapper to set
|
||||
*/
|
||||
public void setActionMapper(ActionMapper actionMapper) {
|
||||
this.actionMapper = actionMapper;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.interceptor;
|
||||
|
||||
import javax.portlet.PortletPreferences;
|
||||
|
||||
|
||||
/**
|
||||
* All Actions that want to have access to the portlet preferences should
|
||||
* implement this interface. If running in a servlet environment, an
|
||||
* appropriate testing implementation will be provided.
|
||||
*/
|
||||
public interface PortletPreferencesAware {
|
||||
|
||||
/**
|
||||
* Sets the HTTP request object in implementing classes.
|
||||
*
|
||||
* @param request the HTTP request.
|
||||
*/
|
||||
public void setPortletPreferences(PortletPreferences prefs);
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.interceptor;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
*
|
||||
* An interceptor which provides an implementation of PortletPreferences if the Action implements
|
||||
* PortletPreferencesAware.
|
||||
*
|
||||
* If running in a servlet environment, a testing implementation of PortletPreferences will be
|
||||
* created and provided, but it should not be used in a production environment.
|
||||
*
|
||||
* <!-- END SNIPPET: description -->
|
||||
*
|
||||
* <p/> <u>Interceptor parameters:</u>
|
||||
*
|
||||
* <!-- START SNIPPET: parameters -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>None</li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <!-- END SNIPPET: parameters -->
|
||||
*
|
||||
* <p/> <u>Extending the interceptor:</u>
|
||||
*
|
||||
* <p/>
|
||||
*
|
||||
* <!-- START SNIPPET: extending -->
|
||||
*
|
||||
* There are no known extension points for this interceptor.
|
||||
*
|
||||
* <!-- END SNIPPET: extending -->
|
||||
*
|
||||
* <p/> <u>Example code:</u>
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <action name="someAction" class="com.examples.SomeAction">
|
||||
* <interceptor-ref name="portlet-preferences"/>
|
||||
* <interceptor-ref name="basicStack"/>
|
||||
* <result name="success">good_result.ftl</result>
|
||||
* </action>
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
* @see PortletPreferencesAware
|
||||
*/
|
||||
public class PortletPreferencesInterceptor extends AbstractInterceptor implements StrutsStatics {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(PortletPreferencesInterceptor.class);
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
final Object action = invocation.getAction();
|
||||
final ActionContext context = invocation.getInvocationContext();
|
||||
|
||||
if (action instanceof PortletPreferencesAware) {
|
||||
PortletRequest request = PortletActionContext.getRequest();
|
||||
PortletPreferencesAware awareAction = (PortletPreferencesAware) action;
|
||||
|
||||
// Check if running in a servlet environment
|
||||
if (request == null) {
|
||||
LOG.warn("This portlet preferences implementation should only be used during development");
|
||||
awareAction.setPortletPreferences(new ServletPortletPreferences(ActionContext.getContext().getSession()));
|
||||
} else {
|
||||
awareAction.setPortletPreferences(request.getPreferences());
|
||||
}
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package org.apache.struts2.portlet.interceptor;
|
||||
|
||||
import org.apache.struts2.interceptor.PrincipalProxy;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.security.Principal;
|
||||
|
||||
/**
|
||||
* PrincipalProxy implementation for using PortletRequest Principal related methods.
|
||||
*/
|
||||
public class PortletPrincipalProxy implements PrincipalProxy {
|
||||
|
||||
private PortletRequest request;
|
||||
|
||||
/**
|
||||
* Constructs a proxy
|
||||
*
|
||||
* @param request The underlying request
|
||||
*/
|
||||
public PortletPrincipalProxy(PortletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the user is in the given role
|
||||
*
|
||||
* @param role The role
|
||||
* @return True if the user is in that role
|
||||
*/
|
||||
public boolean isUserInRole(String role) {
|
||||
return request.isUserInRole(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user principal
|
||||
*
|
||||
* @return The principal
|
||||
*/
|
||||
public Principal getUserPrincipal() {
|
||||
return request.getUserPrincipal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user id
|
||||
*
|
||||
* @return The user id
|
||||
*/
|
||||
public String getRemoteUser() {
|
||||
return request.getRemoteUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the request using https?
|
||||
*
|
||||
* @return True if using https
|
||||
*/
|
||||
public boolean isRequestSecure() {
|
||||
return request.isSecure();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request.
|
||||
*
|
||||
* @return The request
|
||||
* @throws UnsupportedOperationException not supported in this implementation.
|
||||
* @deprecated To obtain the HttpServletRequest in your action, use
|
||||
* {@link org.apache.struts2.servlet.ServletRequestAware}, since this method will be dropped in future.
|
||||
*/
|
||||
public HttpServletRequest getRequest() {
|
||||
throw new UnsupportedOperationException("Usage of getRequest() method is deprecadet and not supported for this implementation");
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.interceptor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.portlet.PortletPreferences;
|
||||
import javax.portlet.ReadOnlyException;
|
||||
import javax.portlet.ValidatorException;
|
||||
|
||||
/**
|
||||
* Simple portlet preferences implementation that uses a map in the Session
|
||||
* as storage.
|
||||
*/
|
||||
public class ServletPortletPreferences implements PortletPreferences {
|
||||
|
||||
private Map session;
|
||||
private String PREFERENCES_KEY = "_portlet-preferences";
|
||||
|
||||
public ServletPortletPreferences(Map session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public Map getMap() {
|
||||
Map map = (Map) session.get(PREFERENCES_KEY);
|
||||
if (map == null) {
|
||||
map = new HashMap();
|
||||
session.put(PREFERENCES_KEY, map);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public Enumeration getNames() {
|
||||
return new Vector(getMap().keySet()).elements();
|
||||
}
|
||||
|
||||
public String getValue(String key, String def) {
|
||||
String val = (String) getMap().get(key);
|
||||
if (val == null) {
|
||||
val = def;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public String[] getValues(String key, String[] def) {
|
||||
String[] val = (String[]) getMap().get(key);
|
||||
if (val == null) {
|
||||
val = def;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public boolean isReadOnly(String arg0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset(String arg0) throws ReadOnlyException {
|
||||
session.put(PREFERENCES_KEY, new HashMap());
|
||||
}
|
||||
|
||||
public void setValue(String key, String value) throws ReadOnlyException {
|
||||
getMap().put(key, value);
|
||||
}
|
||||
|
||||
public void setValues(String key, String[] value) throws ReadOnlyException {
|
||||
getMap().put(key, value);
|
||||
}
|
||||
|
||||
public void store() throws IOException, ValidatorException {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.result;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.dispatcher.StrutsResultSupport;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.util.TextUtils;
|
||||
|
||||
/**
|
||||
* Result type that includes a JSP to render.
|
||||
*
|
||||
*/
|
||||
public class PortletResult extends StrutsResultSupport {
|
||||
|
||||
private static final long serialVersionUID = 434251393926178567L;
|
||||
|
||||
/**
|
||||
* Logger instance.
|
||||
*/
|
||||
private static final Log LOG = LogFactory.getLog(PortletResult.class);
|
||||
|
||||
private String contentType = "text/html";
|
||||
|
||||
private String title;
|
||||
|
||||
public PortletResult() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PortletResult(String location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the result. Obtains the
|
||||
* {@link javax.portlet.PortletRequestDispatcher}from the
|
||||
* {@link PortletActionContext}and includes the JSP.
|
||||
*
|
||||
* @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
|
||||
*/
|
||||
public void doExecute(String finalLocation,
|
||||
ActionInvocation actionInvocation) throws Exception {
|
||||
|
||||
if (PortletActionContext.isRender()) {
|
||||
executeRenderResult(finalLocation);
|
||||
} else if (PortletActionContext.isEvent()) {
|
||||
executeActionResult(finalLocation, actionInvocation);
|
||||
} else {
|
||||
executeRegularServletResult(finalLocation, actionInvocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the regular servlet result.
|
||||
*
|
||||
* @param finalLocation
|
||||
* @param actionInvocation
|
||||
*/
|
||||
private void executeRegularServletResult(String finalLocation,
|
||||
ActionInvocation actionInvocation) throws ServletException, IOException {
|
||||
ServletContext ctx = ServletActionContext.getServletContext();
|
||||
HttpServletRequest req = ServletActionContext.getRequest();
|
||||
HttpServletResponse res = ServletActionContext.getResponse();
|
||||
try {
|
||||
ctx.getRequestDispatcher(finalLocation).include(req, res);
|
||||
} catch (ServletException e) {
|
||||
LOG.error("ServletException including " + finalLocation, e);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
LOG.error("IOException while including result '" + finalLocation + "'", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the action result.
|
||||
*
|
||||
* @param finalLocation
|
||||
* @param invocation
|
||||
*/
|
||||
protected void executeActionResult(String finalLocation,
|
||||
ActionInvocation invocation) {
|
||||
LOG.debug("Executing result in Event phase");
|
||||
ActionResponse res = PortletActionContext.getActionResponse();
|
||||
LOG.debug("Setting event render parameter: " + finalLocation);
|
||||
if (finalLocation.indexOf('?') != -1) {
|
||||
convertQueryParamsToRenderParams(res, finalLocation
|
||||
.substring(finalLocation.indexOf('?') + 1));
|
||||
finalLocation = finalLocation.substring(0, finalLocation
|
||||
.indexOf('?'));
|
||||
}
|
||||
if (finalLocation.endsWith(".action")) {
|
||||
// View is rendered with a view action...luckily...
|
||||
finalLocation = finalLocation.substring(0, finalLocation
|
||||
.lastIndexOf("."));
|
||||
res.setRenderParameter(PortletActionConstants.ACTION_PARAM, finalLocation);
|
||||
} else {
|
||||
// View is rendered outside an action...uh oh...
|
||||
res.setRenderParameter(PortletActionConstants.ACTION_PARAM, "renderDirect");
|
||||
res.setRenderParameter("location", finalLocation);
|
||||
}
|
||||
res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext
|
||||
.getRequest().getPortletMode().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the query params to render params.
|
||||
*
|
||||
* @param response
|
||||
* @param queryParams
|
||||
*/
|
||||
protected static void convertQueryParamsToRenderParams(
|
||||
ActionResponse response, String queryParams) {
|
||||
StringTokenizer tok = new StringTokenizer(queryParams, "&");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String token = tok.nextToken();
|
||||
String key = token.substring(0, token.indexOf('='));
|
||||
String value = token.substring(token.indexOf('=') + 1);
|
||||
response.setRenderParameter(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the render result.
|
||||
*
|
||||
* @param finalLocation
|
||||
* @throws PortletException
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void executeRenderResult(final String finalLocation) throws PortletException, IOException {
|
||||
LOG.debug("Executing result in Render phase");
|
||||
PortletConfig cfg = PortletActionContext.getPortletConfig();
|
||||
RenderRequest req = PortletActionContext.getRenderRequest();
|
||||
RenderResponse res = PortletActionContext.getRenderResponse();
|
||||
LOG.debug("PortletConfig: " + cfg);
|
||||
LOG.debug("RenderRequest: " + req);
|
||||
LOG.debug("RenderResponse: " + res);
|
||||
res.setContentType(contentType);
|
||||
if (TextUtils.stringSet(title)) {
|
||||
res.setTitle(title);
|
||||
}
|
||||
LOG.debug("Location: " + finalLocation);
|
||||
PortletRequestDispatcher preparator = cfg.getPortletContext()
|
||||
.getNamedDispatcher("preparator");
|
||||
if(preparator == null) {
|
||||
throw new PortletException("Cannot look up 'preparator' servlet. Make sure that you" +
|
||||
"have configured it correctly in the web.xml file.");
|
||||
}
|
||||
new IncludeTemplate() {
|
||||
protected void when(PortletException e) {
|
||||
LOG.error("PortletException while dispatching to 'preparator' servlet", e);
|
||||
}
|
||||
protected void when(IOException e) {
|
||||
LOG.error("IOException while dispatching to 'preparator' servlet", e);
|
||||
}
|
||||
}.include(preparator, req, res);
|
||||
PortletRequestDispatcher dispatcher = cfg.getPortletContext().getRequestDispatcher(finalLocation);
|
||||
if(dispatcher == null) {
|
||||
throw new PortletException("Could not locate dispatcher for '" + finalLocation + "'");
|
||||
}
|
||||
new IncludeTemplate() {
|
||||
protected void when(PortletException e) {
|
||||
LOG.error("PortletException while dispatching to '" + finalLocation + "'");
|
||||
}
|
||||
protected void when(IOException e) {
|
||||
LOG.error("IOException while dispatching to '" + finalLocation + "'");
|
||||
}
|
||||
}.include(dispatcher, req, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content type.
|
||||
*
|
||||
* @param contentType The content type to set.
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title.
|
||||
*
|
||||
* @param title The title to set.
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
static class IncludeTemplate {
|
||||
protected void include(PortletRequestDispatcher dispatcher, RenderRequest req, RenderResponse res) throws PortletException, IOException{
|
||||
try {
|
||||
dispatcher.include(req, res);
|
||||
}
|
||||
catch(PortletException e) {
|
||||
when(e);
|
||||
throw e;
|
||||
}
|
||||
catch(IOException e) {
|
||||
when(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected void when(PortletException e) {}
|
||||
|
||||
protected void when(IOException e) {}
|
||||
}
|
||||
}
|
||||
+307
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.result;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.jsp.JspFactory;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.StrutsResultSupport;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import org.apache.struts2.views.JspSupportServlet;
|
||||
import org.apache.struts2.views.velocity.VelocityManager;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
*
|
||||
* Using the Servlet container's {@link JspFactory}, this result mocks a JSP
|
||||
* execution environment and then displays a Velocity template that will be
|
||||
* streamed directly to the servlet output.
|
||||
*
|
||||
* <!-- END SNIPPET: description --> <p/><b>This result type takes the
|
||||
* following parameters: </b>
|
||||
*
|
||||
* <!-- START SNIPPET: params -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><b>location (default) </b>- the location of the template to process.
|
||||
* </li>
|
||||
*
|
||||
* <li><b>parse </b>- true by default. If set to false, the location param
|
||||
* will not be parsed for Ognl expressions.</li>
|
||||
*
|
||||
* </ul>
|
||||
* <p>
|
||||
* This result follows the same rules from {@link StrutsResultSupport}.
|
||||
* </p>
|
||||
*
|
||||
* <!-- END SNIPPET: params -->
|
||||
*
|
||||
* <b>Example: </b>
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <result name="success" type="velocity">
|
||||
* <param name="location">foo.vm</param>
|
||||
* </result>
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class PortletVelocityResult extends StrutsResultSupport {
|
||||
|
||||
private static final long serialVersionUID = -8241086555872212274L;
|
||||
|
||||
private static final Log log = LogFactory
|
||||
.getLog(PortletVelocityResult.class);
|
||||
|
||||
private String defaultEncoding;
|
||||
private VelocityManager velocityManager;
|
||||
|
||||
public PortletVelocityResult() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PortletVelocityResult(String location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setVelocityManager(VelocityManager mgr) {
|
||||
this.velocityManager = mgr;
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
|
||||
public void setDefaultEncoding(String encoding) {
|
||||
this.defaultEncoding = encoding;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.struts2.dispatcher.StrutsResultSupport#doExecute(java.lang.String, com.opensymphony.xwork2.ActionInvocation)
|
||||
*/
|
||||
public void doExecute(String location, ActionInvocation invocation)
|
||||
throws Exception {
|
||||
if (PortletActionContext.isEvent()) {
|
||||
executeActionResult(location, invocation);
|
||||
} else if (PortletActionContext.isRender()) {
|
||||
executeRenderResult(location, invocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the result
|
||||
*
|
||||
* @param location The location string
|
||||
* @param invocation The action invocation
|
||||
*/
|
||||
private void executeActionResult(String location,
|
||||
ActionInvocation invocation) {
|
||||
ActionResponse res = PortletActionContext.getActionResponse();
|
||||
// View is rendered outside an action...uh oh...
|
||||
res.setRenderParameter(PortletActionConstants.ACTION_PARAM,
|
||||
"freemarkerDirect");
|
||||
res.setRenderParameter("location", location);
|
||||
res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext
|
||||
.getRequest().getPortletMode().toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Velocity context from the action, loads a Velocity template and
|
||||
* executes the template. Output is written to the servlet output stream.
|
||||
*
|
||||
* @param finalLocation the location of the Velocity template
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @throws Exception if an error occurs when creating the Velocity context,
|
||||
* loading or executing the template or writing output to the
|
||||
* servlet response stream.
|
||||
*/
|
||||
public void executeRenderResult(String finalLocation,
|
||||
ActionInvocation invocation) throws Exception {
|
||||
prepareServletActionContext();
|
||||
ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
|
||||
HttpServletRequest request = ServletActionContext.getRequest();
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
JspFactory jspFactory = null;
|
||||
ServletContext servletContext = ServletActionContext
|
||||
.getServletContext();
|
||||
Servlet servlet = JspSupportServlet.jspSupportServlet;
|
||||
|
||||
velocityManager.init(servletContext);
|
||||
|
||||
boolean usedJspFactory = false;
|
||||
PageContext pageContext = (PageContext) ActionContext.getContext().get(
|
||||
ServletActionContext.PAGE_CONTEXT);
|
||||
|
||||
if (pageContext == null && servlet != null) {
|
||||
jspFactory = JspFactory.getDefaultFactory();
|
||||
pageContext = jspFactory.getPageContext(servlet, request, response,
|
||||
null, true, 8192, true);
|
||||
ActionContext.getContext().put(ServletActionContext.PAGE_CONTEXT,
|
||||
pageContext);
|
||||
usedJspFactory = true;
|
||||
}
|
||||
|
||||
try {
|
||||
String encoding = getEncoding(finalLocation);
|
||||
String contentType = getContentType(finalLocation);
|
||||
|
||||
if (encoding != null) {
|
||||
contentType = contentType + ";charset=" + encoding;
|
||||
}
|
||||
|
||||
Template t = getTemplate(stack,
|
||||
velocityManager.getVelocityEngine(), invocation,
|
||||
finalLocation, encoding);
|
||||
|
||||
Context context = createContext(velocityManager, stack, request,
|
||||
response, finalLocation);
|
||||
Writer writer = new OutputStreamWriter(response.getOutputStream(),
|
||||
encoding);
|
||||
|
||||
response.setContentType(contentType);
|
||||
|
||||
t.merge(context, writer);
|
||||
|
||||
// always flush the writer (we used to only flush it if this was a
|
||||
// jspWriter, but someone asked
|
||||
// to do it all the time (WW-829). Since Velocity support is being
|
||||
// deprecated, we'll oblige :)
|
||||
writer.flush();
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to render Velocity Template, '" + finalLocation
|
||||
+ "'", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (usedJspFactory) {
|
||||
jspFactory.releasePageContext(pageContext);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the content type for this template. <p/>People can override
|
||||
* this method if they want to provide specific content types for specific
|
||||
* templates (eg text/xml).
|
||||
*
|
||||
* @return The content type associated with this template (default
|
||||
* "text/html")
|
||||
*/
|
||||
protected String getContentType(String templateLocation) {
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the encoding for this template. <p/>People can override this
|
||||
* method if they want to provide specific encodings for specific templates.
|
||||
*
|
||||
* @return The encoding associated with this template (defaults to the value
|
||||
* of 'struts.i18n.encoding' property)
|
||||
*/
|
||||
protected String getEncoding(String templateLocation) {
|
||||
String encoding = defaultEncoding;
|
||||
if (encoding == null) {
|
||||
encoding = System.getProperty("file.encoding");
|
||||
}
|
||||
if (encoding == null) {
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a value stack, a Velocity engine, and an action invocation, this
|
||||
* method returns the appropriate Velocity template to render.
|
||||
*
|
||||
* @param stack the value stack to resolve the location again (when parse
|
||||
* equals true)
|
||||
* @param velocity the velocity engine to process the request against
|
||||
* @param invocation an encapsulation of the action execution state.
|
||||
* @param location the location of the template
|
||||
* @param encoding the charset encoding of the template
|
||||
* @return the template to render
|
||||
* @throws Exception when the requested template could not be found
|
||||
*/
|
||||
protected Template getTemplate(ValueStack stack,
|
||||
VelocityEngine velocity, ActionInvocation invocation,
|
||||
String location, String encoding) throws Exception {
|
||||
if (!location.startsWith("/")) {
|
||||
location = invocation.getProxy().getNamespace() + "/" + location;
|
||||
}
|
||||
|
||||
Template template = velocity.getTemplate(location, encoding);
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the VelocityContext that we'll use to render this page.
|
||||
*
|
||||
* @param velocityManager a reference to the velocityManager to use
|
||||
* @param stack the value stack to resolve the location against (when parse
|
||||
* equals true)
|
||||
* @param location the name of the template that is being used
|
||||
* @return the a minted Velocity context.
|
||||
*/
|
||||
protected Context createContext(VelocityManager velocityManager,
|
||||
ValueStack stack, HttpServletRequest request,
|
||||
HttpServletResponse response, String location) {
|
||||
return velocityManager.createContext(stack, request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the servlet action context for this request
|
||||
*/
|
||||
private void prepareServletActionContext() throws PortletException,
|
||||
IOException {
|
||||
PortletRequestDispatcher disp = PortletActionContext.getPortletConfig()
|
||||
.getPortletContext().getNamedDispatcher("preparator");
|
||||
disp.include(PortletActionContext.getRenderRequest(),
|
||||
PortletActionContext.getRenderResponse());
|
||||
}
|
||||
}
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.Principal;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* A simple mock class to interact with Struts 2 API's that require a servlet request
|
||||
*/
|
||||
public class HttpServletRequestMock implements HttpServletRequest {
|
||||
|
||||
private String servletPath;
|
||||
private Map parameterMap;
|
||||
|
||||
public String getAuthType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getContextPath() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Cookie[] getCookies() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getDateHeader(String arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getHeader(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enumeration getHeaderNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enumeration getHeaders(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getIntHeader(String arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getPathInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getPathTranslated() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getQueryString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRemoteUser() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRequestURI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public StringBuffer getRequestURL() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRequestedSessionId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getServletPath() {
|
||||
return servletPath;
|
||||
}
|
||||
|
||||
public HttpSession getSession() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public HttpSession getSession(boolean arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Principal getUserPrincipal() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdFromCookie() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdFromURL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdFromUrl() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdValid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUserInRole(String arg0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object getAttribute(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enumeration getAttributeNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCharacterEncoding() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLocalAddr() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLocalName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getLocalPort() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enumeration getLocales() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getParameter(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map getParameterMap() {
|
||||
return parameterMap;
|
||||
}
|
||||
|
||||
public Enumeration getParameterNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String[] getParameterValues(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public BufferedReader getReader() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRealPath(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRemoteAddr() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRemoteHost() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRemotePort() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public RequestDispatcher getRequestDispatcher(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getServerPort() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAttribute(String arg0) {
|
||||
}
|
||||
|
||||
public void setAttribute(String arg0, Object arg1) {
|
||||
}
|
||||
|
||||
public void setCharacterEncoding(String arg0)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parameterMap the parameterMap to set
|
||||
*/
|
||||
public HttpServletRequestMock setParameterMap(Map parameterMap) {
|
||||
this.parameterMap = parameterMap;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param servletPath the servletPath to set
|
||||
*/
|
||||
public HttpServletRequestMock setServletPath(String servletPath) {
|
||||
this.servletPath = servletPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletSecurityException;
|
||||
import javax.portlet.PortletURL;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.WindowState;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import com.opensymphony.xwork2.util.TextUtils;
|
||||
|
||||
/**
|
||||
* Helper class for creating Portlet URLs. Portlet URLs are fundamentally different from regular
|
||||
* servlet URLs since they never target the application itself; all requests go through the portlet
|
||||
* container and must therefore be programatically constructed using the
|
||||
* {@link javax.portlet.RenderResponse#createActionURL()} and
|
||||
* {@link javax.portlet.RenderResponse#createRenderURL()} APIs.
|
||||
*
|
||||
*/
|
||||
public class PortletUrlHelper {
|
||||
public static final String ENCODING = "UTF-8";
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(PortletUrlHelper.class);
|
||||
|
||||
/**
|
||||
* Create a portlet URL with for the specified action and namespace.
|
||||
*
|
||||
* @param action The action the URL should invoke.
|
||||
* @param namespace The namespace of the action to invoke.
|
||||
* @param params The parameters of the URL.
|
||||
* @param type The type of the url, either <tt>action</tt> or <tt>render</tt>
|
||||
* @param mode The PortletMode of the URL.
|
||||
* @param state The WindowState of the URL.
|
||||
* @return The URL String.
|
||||
*/
|
||||
public static String buildUrl(String action, String namespace, Map params,
|
||||
String type, String mode, String state) {
|
||||
return buildUrl(action, namespace, params, null, type, mode, state,
|
||||
true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a portlet URL with for the specified action and namespace.
|
||||
*
|
||||
* @see #buildUrl(String, String, Map, String, String, String)
|
||||
*/
|
||||
public static String buildUrl(String action, String namespace, Map params,
|
||||
String scheme, String type, String portletMode, String windowState,
|
||||
boolean includeContext, boolean encodeResult) {
|
||||
RenderRequest request = PortletActionContext.getRenderRequest();
|
||||
RenderResponse response = PortletActionContext.getRenderResponse();
|
||||
LOG.debug("Creating url. Action = " + action + ", Namespace = "
|
||||
+ namespace + ", Type = " + type);
|
||||
namespace = prependNamespace(namespace, portletMode);
|
||||
if (!TextUtils.stringSet(portletMode)) {
|
||||
portletMode = PortletActionContext.getRenderRequest().getPortletMode().toString();
|
||||
}
|
||||
String result = null;
|
||||
int paramStartIndex = action.indexOf('?');
|
||||
if (paramStartIndex > 0) {
|
||||
String value = action;
|
||||
action = value.substring(0, value.indexOf('?'));
|
||||
String queryStr = value.substring(paramStartIndex + 1);
|
||||
StringTokenizer tok = new StringTokenizer(queryStr, "&");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String paramVal = tok.nextToken();
|
||||
String key = paramVal.substring(0, paramVal.indexOf('='));
|
||||
String val = paramVal.substring(paramVal.indexOf('=') + 1);
|
||||
params.put(key, new String[] { val });
|
||||
}
|
||||
}
|
||||
if (TextUtils.stringSet(namespace)) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(namespace);
|
||||
if(!action.startsWith("/") && !namespace.endsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
action = sb.append(action).toString();
|
||||
LOG.debug("Resulting actionPath: " + action);
|
||||
}
|
||||
params.put(PortletActionConstants.ACTION_PARAM, new String[] { action });
|
||||
|
||||
PortletURL url = null;
|
||||
if ("action".equalsIgnoreCase(type)) {
|
||||
LOG.debug("Creating action url");
|
||||
url = response.createActionURL();
|
||||
} else {
|
||||
LOG.debug("Creating render url");
|
||||
url = response.createRenderURL();
|
||||
}
|
||||
|
||||
params.put(PortletActionConstants.MODE_PARAM, portletMode);
|
||||
url.setParameters(ensureParamsAreStringArrays(params));
|
||||
|
||||
if ("HTTPS".equalsIgnoreCase(scheme)) {
|
||||
try {
|
||||
url.setSecure(true);
|
||||
} catch (PortletSecurityException e) {
|
||||
LOG.error("Cannot set scheme to https", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
url.setPortletMode(getPortletMode(request, portletMode));
|
||||
url.setWindowState(getWindowState(request, windowState));
|
||||
} catch (Exception e) {
|
||||
LOG.error("Unable to set mode or state:" + e.getMessage(), e);
|
||||
}
|
||||
result = url.toString();
|
||||
// TEMP BUG-WORKAROUND FOR DOUBLE ESCAPING OF AMPERSAND
|
||||
if(result.indexOf("&") >= 0) {
|
||||
result = result.replace("&", "&");
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Prepend the namespace configuration for the specified namespace and PortletMode.
|
||||
*
|
||||
* @param namespace The base namespace.
|
||||
* @param portletMode The PortletMode.
|
||||
*
|
||||
* @return prepended namespace.
|
||||
*/
|
||||
private static String prependNamespace(String namespace, String portletMode) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
PortletMode mode = PortletActionContext.getRenderRequest().getPortletMode();
|
||||
if(TextUtils.stringSet(portletMode)) {
|
||||
mode = new PortletMode(portletMode);
|
||||
}
|
||||
String portletNamespace = PortletActionContext.getPortletNamespace();
|
||||
String modeNamespace = (String)PortletActionContext.getModeNamespaceMap().get(mode);
|
||||
LOG.debug("PortletNamespace: " + portletNamespace + ", modeNamespace: " + modeNamespace);
|
||||
if(TextUtils.stringSet(portletNamespace)) {
|
||||
sb.append(portletNamespace);
|
||||
}
|
||||
if(TextUtils.stringSet(modeNamespace)) {
|
||||
if(!modeNamespace.startsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
sb.append(modeNamespace);
|
||||
}
|
||||
if(TextUtils.stringSet(namespace)) {
|
||||
if(!namespace.startsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
sb.append(namespace);
|
||||
}
|
||||
LOG.debug("Resulting namespace: " + sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode an url to a non Struts action resource, like stylesheet, image or
|
||||
* servlet.
|
||||
*
|
||||
* @param value
|
||||
* @return encoded url to non Struts action resources.
|
||||
*/
|
||||
public static String buildResourceUrl(String value, Map params) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
// Relative URLs are not allowed in a portlet
|
||||
if (!value.startsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
sb.append(value);
|
||||
if(params != null && params.size() > 0) {
|
||||
sb.append("?");
|
||||
Iterator it = params.keySet().iterator();
|
||||
try {
|
||||
while(it.hasNext()) {
|
||||
String key = (String)it.next();
|
||||
String val = (String)params.get(key);
|
||||
|
||||
sb.append(URLEncoder.encode(key, ENCODING)).append("=");
|
||||
sb.append(URLEncoder.encode(val, ENCODING));
|
||||
if(it.hasNext()) {
|
||||
sb.append("&");
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new StrutsException("Encoding "+ENCODING+" not found");
|
||||
}
|
||||
}
|
||||
RenderResponse resp = PortletActionContext.getRenderResponse();
|
||||
RenderRequest req = PortletActionContext.getRenderRequest();
|
||||
return resp.encodeURL(req.getContextPath() + sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Will ensure that all entries in <code>params</code> are String arrays,
|
||||
* as requried by the setParameters on the PortletURL.
|
||||
*
|
||||
* @param params The parameters to the URL.
|
||||
* @return A Map with all parameters as String arrays.
|
||||
*/
|
||||
public static Map ensureParamsAreStringArrays(Map params) {
|
||||
Map result = null;
|
||||
if (params != null) {
|
||||
result = new LinkedHashMap(params.size());
|
||||
Iterator it = params.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Object key = it.next();
|
||||
Object val = params.get(key);
|
||||
if (val instanceof String[]) {
|
||||
result.put(key, val);
|
||||
} else {
|
||||
result.put(key, new String[] { val.toString() });
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given String to a WindowState object.
|
||||
*
|
||||
* @param portletReq The RenderRequest.
|
||||
* @param windowState The WindowState as a String.
|
||||
* @return The WindowState that mathces the <tt>windowState</tt> String, or if
|
||||
* the Sring is blank, the current WindowState.
|
||||
*/
|
||||
private static WindowState getWindowState(RenderRequest portletReq,
|
||||
String windowState) {
|
||||
WindowState state = portletReq.getWindowState();
|
||||
if (TextUtils.stringSet(windowState)) {
|
||||
state = portletReq.getWindowState();
|
||||
if ("maximized".equalsIgnoreCase(windowState)) {
|
||||
state = WindowState.MAXIMIZED;
|
||||
} else if ("normal".equalsIgnoreCase(windowState)) {
|
||||
state = WindowState.NORMAL;
|
||||
} else if ("minimized".equalsIgnoreCase(windowState)) {
|
||||
state = WindowState.MINIMIZED;
|
||||
}
|
||||
}
|
||||
if(state == null) {
|
||||
state = WindowState.NORMAL;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given String to a PortletMode object.
|
||||
*
|
||||
* @param portletReq The RenderRequest.
|
||||
* @param portletMode The PortletMode as a String.
|
||||
* @return The PortletMode that mathces the <tt>portletMode</tt> String, or if
|
||||
* the Sring is blank, the current PortletMode.
|
||||
*/
|
||||
private static PortletMode getPortletMode(RenderRequest portletReq,
|
||||
String portletMode) {
|
||||
PortletMode mode = portletReq.getPortletMode();
|
||||
|
||||
if (TextUtils.stringSet(portletMode)) {
|
||||
mode = portletReq.getPortletMode();
|
||||
if ("edit".equalsIgnoreCase(portletMode)) {
|
||||
mode = PortletMode.EDIT;
|
||||
} else if ("view".equalsIgnoreCase(portletMode)) {
|
||||
mode = PortletMode.VIEW;
|
||||
} else if ("help".equalsIgnoreCase(portletMode)) {
|
||||
mode = PortletMode.HELP;
|
||||
}
|
||||
}
|
||||
if(mode == null) {
|
||||
mode = PortletMode.VIEW;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.views.freemarker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.dispatcher.StrutsResultSupport;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import org.apache.struts2.views.util.ResourceUtil;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.ObjectWrapper;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import freemarker.template.TemplateModel;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PortletFreemarkerResult extends StrutsResultSupport {
|
||||
|
||||
private static final long serialVersionUID = -5570612389289887543L;
|
||||
|
||||
protected ActionInvocation invocation;
|
||||
|
||||
protected Configuration configuration;
|
||||
|
||||
protected ObjectWrapper wrapper;
|
||||
protected FreemarkerManager freemarkerManager;
|
||||
|
||||
/*
|
||||
* Struts results are constructed for each result execeution
|
||||
*
|
||||
* the current context is availible to subclasses via these protected fields
|
||||
*/
|
||||
protected String location;
|
||||
|
||||
private String pContentType = "text/html";
|
||||
|
||||
public PortletFreemarkerResult() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PortletFreemarkerResult(String location) {
|
||||
super(location);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setFreemarkerManager(FreemarkerManager mgr) {
|
||||
this.freemarkerManager = mgr;
|
||||
}
|
||||
|
||||
public void setContentType(String aContentType) {
|
||||
pContentType = aContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* allow parameterization of the contentType the default being text/html
|
||||
*/
|
||||
public String getContentType() {
|
||||
return pContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute this result, using the specified template location. <p/>The
|
||||
* template location has already been interoplated for any variable
|
||||
* substitutions <p/>this method obtains the freemarker configuration and
|
||||
* the object wrapper from the provided hooks. It them implements the
|
||||
* template processing workflow by calling the hooks for preTemplateProcess
|
||||
* and postTemplateProcess
|
||||
*/
|
||||
public void doExecute(String location, ActionInvocation invocation)
|
||||
throws IOException, TemplateException, PortletException {
|
||||
if (PortletActionContext.isEvent()) {
|
||||
executeActionResult(location, invocation);
|
||||
} else if (PortletActionContext.isRender()) {
|
||||
executeRenderResult(location, invocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location
|
||||
* @param invocation
|
||||
*/
|
||||
private void executeActionResult(String location,
|
||||
ActionInvocation invocation) {
|
||||
ActionResponse res = PortletActionContext.getActionResponse();
|
||||
// View is rendered outside an action...uh oh...
|
||||
res.setRenderParameter(PortletActionConstants.ACTION_PARAM, "freemarkerDirect");
|
||||
res.setRenderParameter("location", location);
|
||||
res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext
|
||||
.getRequest().getPortletMode().toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location
|
||||
* @param invocation
|
||||
* @throws TemplateException
|
||||
* @throws IOException
|
||||
* @throws TemplateModelException
|
||||
*/
|
||||
private void executeRenderResult(String location,
|
||||
ActionInvocation invocation) throws TemplateException, IOException,
|
||||
TemplateModelException, PortletException {
|
||||
prepareServletActionContext();
|
||||
this.location = location;
|
||||
this.invocation = invocation;
|
||||
this.configuration = getConfiguration();
|
||||
this.wrapper = getObjectWrapper();
|
||||
|
||||
HttpServletRequest req = ServletActionContext.getRequest();
|
||||
|
||||
if (!location.startsWith("/")) {
|
||||
String base = ResourceUtil.getResourceBase(req);
|
||||
location = base + "/" + location;
|
||||
}
|
||||
|
||||
Template template = configuration.getTemplate(location, deduceLocale());
|
||||
TemplateModel model = createModel();
|
||||
// Give subclasses a chance to hook into preprocessing
|
||||
if (preTemplateProcess(template, model)) {
|
||||
try {
|
||||
// Process the template
|
||||
PortletActionContext.getRenderResponse().setContentType(pContentType);
|
||||
template.process(model, getWriter());
|
||||
} finally {
|
||||
// Give subclasses a chance to hook into postprocessing
|
||||
postTemplateProcess(template, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void prepareServletActionContext() throws PortletException,
|
||||
IOException {
|
||||
PortletRequestDispatcher disp = PortletActionContext.getPortletConfig()
|
||||
.getPortletContext().getNamedDispatcher("preparator");
|
||||
disp.include(PortletActionContext.getRenderRequest(),
|
||||
PortletActionContext.getRenderResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from {@link #doExecute(String, ActionInvocation)}
|
||||
* to obtain the FreeMarker configuration object that this result will use
|
||||
* for template loading. This is a hook that allows you to custom-configure
|
||||
* the configuration object in a subclass, or to fetch it from an IoC
|
||||
* container. <p/><b>The default implementation obtains the configuration
|
||||
* from the ConfigurationManager instance. </b>
|
||||
*/
|
||||
protected Configuration getConfiguration() throws TemplateException {
|
||||
return freemarkerManager.getConfiguration(
|
||||
ServletActionContext.getServletContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from {@link #doExecute(String, ActionInvocation)}
|
||||
* to obtain the FreeMarker object wrapper object that this result will use
|
||||
* for adapting objects into template models. This is a hook that allows you
|
||||
* to custom-configure the wrapper object in a subclass. <p/><b>The default
|
||||
* implementation returns {@link Configuration#getObjectWrapper()}</b>
|
||||
*/
|
||||
protected ObjectWrapper getObjectWrapper() {
|
||||
return configuration.getObjectWrapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default writer writes directly to the response writer.
|
||||
*/
|
||||
protected Writer getWriter() throws IOException {
|
||||
return PortletActionContext.getRenderResponse().getWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the instance of the ScopesHashModel, including JspTagLib support
|
||||
* <p/>Objects added to the model are <p/>
|
||||
* <ul>
|
||||
* <li>Application - servlet context attributes hash model
|
||||
* <li>JspTaglibs - jsp tag lib factory model
|
||||
* <li>Request - request attributes hash model
|
||||
* <li>Session - session attributes hash model
|
||||
* <li>request - the HttpServletRequst object for direct access
|
||||
* <li>response - the HttpServletResponse object for direct access
|
||||
* <li>stack - the OgnLValueStack instance for direct access
|
||||
* <li>ognl - the instance of the OgnlTool
|
||||
* <li>action - the action itself
|
||||
* <li>exception - optional : the JSP or Servlet exception as per the
|
||||
* servlet spec (for JSP Exception pages)
|
||||
* <li>struts - instance of the StrutsUtil class
|
||||
* </ul>
|
||||
*/
|
||||
protected TemplateModel createModel() throws TemplateModelException {
|
||||
ServletContext servletContext = ServletActionContext
|
||||
.getServletContext();
|
||||
HttpServletRequest request = ServletActionContext.getRequest();
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
ValueStack stack = ServletActionContext.getContext()
|
||||
.getValueStack();
|
||||
return freemarkerManager.buildTemplateModel(stack,
|
||||
invocation.getAction(), servletContext, request, response,
|
||||
wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale used for the
|
||||
* {@link Configuration#getTemplate(String, Locale)}call. The base
|
||||
* implementation simply returns the locale setting of the configuration.
|
||||
* Override this method to provide different behaviour,
|
||||
*/
|
||||
protected Locale deduceLocale() {
|
||||
return configuration.getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* the default implementation of postTemplateProcess applies the contentType
|
||||
* parameter
|
||||
*/
|
||||
protected void postTemplateProcess(Template template, TemplateModel data)
|
||||
throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before the execution is passed to template.process(). This is a
|
||||
* generic hook you might use in subclasses to perform a specific action
|
||||
* before the template is processed. By default does nothing. A typical
|
||||
* action to perform here is to inject application-specific objects into the
|
||||
* model root
|
||||
*
|
||||
* @return true to process the template, false to suppress template
|
||||
* processing.
|
||||
*/
|
||||
protected boolean preTemplateProcess(Template template, TemplateModel model)
|
||||
throws IOException {
|
||||
Object attrContentType = template.getCustomAttribute("content_type");
|
||||
|
||||
if (attrContentType != null) {
|
||||
ServletActionContext.getResponse().setContentType(
|
||||
attrContentType.toString());
|
||||
} else {
|
||||
String contentType = getContentType();
|
||||
|
||||
if (contentType == null) {
|
||||
contentType = "text/html";
|
||||
}
|
||||
|
||||
String encoding = template.getEncoding();
|
||||
|
||||
if (encoding != null) {
|
||||
contentType = contentType + "; charset=" + encoding;
|
||||
}
|
||||
|
||||
ServletActionContext.getResponse().setContentType(contentType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
@@ -0,0 +1,5 @@
|
||||
Apache Struts
|
||||
Copyright 2000-2007 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.0.dtd">
|
||||
|
||||
<struts>
|
||||
|
||||
<bean type="org.apache.struts2.components.UrlRenderer" name="portlet" class="org.apache.struts2.components.PortletUrlRenderer"/>
|
||||
<constant name="struts.urlRenderer" value="portlet" />
|
||||
|
||||
<package name="struts-portlet-default" extends="struts-default">
|
||||
|
||||
<result-types>
|
||||
<result-type name="dispatcher" class="org.apache.struts2.portlet.result.PortletResult" default="true"/>
|
||||
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.PortletFreemarkerResult"/>
|
||||
<result-type name="velocity" class="org.apache.struts2.portlet.result.PortletVelocityResult"/>
|
||||
</result-types>
|
||||
|
||||
<interceptors>
|
||||
<interceptor name="portlet-preferences" class="org.apache.struts2.portlet.interceptor.PortletPreferencesInterceptor"/>
|
||||
<interceptor name="servletConfig" class="org.apache.struts2.portlet.interceptor.PortletConfigInterceptor"/>
|
||||
<interceptor-stack name="portletDefaultStack">
|
||||
<interceptor-ref name="defaultStack"/>
|
||||
<interceptor-ref name="portlet-preferences" />
|
||||
</interceptor-stack>
|
||||
|
||||
</interceptors>
|
||||
|
||||
<default-interceptor-ref name="portletDefaultStack"/>
|
||||
|
||||
<action name="renderDirect" class="org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction">
|
||||
<result name="success">${location}</result>
|
||||
</action>
|
||||
<action name="freemarkerDirect" class="org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction">
|
||||
<result type="freemarker" name="success">${location}</result>
|
||||
</action>
|
||||
<action name="velocityDirect" class="org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction">
|
||||
<result type="velocity" name="success">${location}</result>
|
||||
</action>
|
||||
</package>
|
||||
</struts>
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletContext;
|
||||
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.MockObjectTestCase;
|
||||
import org.jmock.core.Constraint;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PortletApplicationMapTest extends MockObjectTestCase {
|
||||
|
||||
Mock mockPortletContext;
|
||||
|
||||
PortletContext portletContext;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockPortletContext = mock(PortletContext.class);
|
||||
portletContext = (PortletContext) mockPortletContext.proxy();
|
||||
}
|
||||
|
||||
public void testGetFromAttributes() {
|
||||
mockPortletContext.stubs().method("getAttribute").with(eq("dummyKey"))
|
||||
.will(returnValue("dummyValue"));
|
||||
|
||||
PortletApplicationMap map = new PortletApplicationMap(
|
||||
(PortletContext) mockPortletContext.proxy());
|
||||
|
||||
assertEquals("dummyValue", map.get("dummyKey"));
|
||||
}
|
||||
|
||||
public void testGetFromInitParameters() {
|
||||
mockPortletContext.stubs().method("getAttribute").with(eq("dummyKey"));
|
||||
mockPortletContext.stubs().method("getInitParameter").with(
|
||||
eq("dummyKey")).will(returnValue("dummyValue"));
|
||||
|
||||
PortletApplicationMap map = new PortletApplicationMap(
|
||||
(PortletContext) mockPortletContext.proxy());
|
||||
|
||||
assertEquals("dummyValue", map.get("dummyKey"));
|
||||
}
|
||||
|
||||
public void testPut() {
|
||||
mockPortletContext.expects(once()).method("setAttribute").with(
|
||||
new Constraint[] { eq("dummyKey"), eq("dummyValue") });
|
||||
mockPortletContext.expects(once()).method("getAttribute").with(
|
||||
eq("dummyKey")).will(returnValue("dummyValue"));
|
||||
PortletApplicationMap map = new PortletApplicationMap(portletContext);
|
||||
Object val = map.put("dummyKey", "dummyValue");
|
||||
assertEquals("dummyValue", val);
|
||||
}
|
||||
|
||||
public void testRemove() {
|
||||
mockPortletContext.expects(once()).method("getAttribute").with(
|
||||
eq("dummyKey")).will(returnValue("dummyValue"));
|
||||
mockPortletContext.expects(once()).method("removeAttribute").with(
|
||||
eq("dummyKey"));
|
||||
PortletApplicationMap map = new PortletApplicationMap(portletContext);
|
||||
Object val = map.remove("dummyKey");
|
||||
assertEquals("dummyValue", val);
|
||||
}
|
||||
|
||||
public void testEntrySet() {
|
||||
|
||||
Enumeration names = new Enumeration() {
|
||||
|
||||
List keys = Arrays.asList(new Object[] { "key1", "key2" });
|
||||
|
||||
Iterator it = keys.iterator();
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
return it.next();
|
||||
}
|
||||
|
||||
};
|
||||
Enumeration initParamNames = new Enumeration() {
|
||||
|
||||
List keys = Arrays.asList(new Object[] { "key3" });
|
||||
|
||||
Iterator it = keys.iterator();
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
return it.next();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
mockPortletContext.stubs().method("getAttributeNames").will(
|
||||
returnValue(names));
|
||||
mockPortletContext.stubs().method("getInitParameterNames").will(
|
||||
returnValue(initParamNames));
|
||||
mockPortletContext.stubs().method("getAttribute").with(eq("key1"))
|
||||
.will(returnValue("value1"));
|
||||
mockPortletContext.stubs().method("getAttribute").with(eq("key2"))
|
||||
.will(returnValue("value2"));
|
||||
mockPortletContext.stubs().method("getInitParameter").with(eq("key3"))
|
||||
.will(returnValue("value3"));
|
||||
|
||||
PortletApplicationMap map = new PortletApplicationMap(portletContext);
|
||||
Set entries = map.entrySet();
|
||||
|
||||
assertEquals(3, entries.size());
|
||||
Iterator it = entries.iterator();
|
||||
Map.Entry entry = (Map.Entry) it.next();
|
||||
assertEquals("key2", entry.getKey());
|
||||
assertEquals("value2", entry.getValue());
|
||||
entry = (Map.Entry) it.next();
|
||||
assertEquals("key1", entry.getKey());
|
||||
assertEquals("value1", entry.getValue());
|
||||
entry = (Map.Entry) it.next();
|
||||
assertEquals("key3", entry.getKey());
|
||||
assertEquals("value3", entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
public void testClear() {
|
||||
|
||||
mockPortletContext.expects(once()).method("removeAttribute").with(eq("key1"));
|
||||
mockPortletContext.expects(once()).method("removeAttribute").with(eq("key2"));
|
||||
|
||||
ArrayList dummy = new ArrayList();
|
||||
dummy.add("key1");
|
||||
dummy.add("key2");
|
||||
|
||||
mockPortletContext.expects(once()).method("getAttributeNames").will(
|
||||
returnValue(Collections.enumeration(dummy)));
|
||||
|
||||
PortletApplicationMap map = new PortletApplicationMap(portletContext);
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.MockObjectTestCase;
|
||||
import org.jmock.core.Constraint;
|
||||
|
||||
|
||||
/**
|
||||
* PortletRequestMapTest. Insert description.
|
||||
*
|
||||
*/
|
||||
public class PortletRequestMapTest extends MockObjectTestCase {
|
||||
|
||||
public void testSetAttribute() {
|
||||
|
||||
}
|
||||
|
||||
public void testGet() {
|
||||
Mock mockRequest = mock(PortletRequest.class, "testGet");
|
||||
mockRequest.expects(once()).method("getAttribute").with(eq("testAttribute")).will(returnValue("testValue"));
|
||||
PortletRequestMap map = new PortletRequestMap((PortletRequest)mockRequest.proxy());
|
||||
String value = (String)map.get("testAttribute");
|
||||
mockRequest.verify();
|
||||
assertEquals("testValue", value);
|
||||
}
|
||||
|
||||
public void testPut() {
|
||||
Mock mockRequest = mock(PortletRequest.class, "testPut");
|
||||
Object value = new String("testValue");
|
||||
Constraint[] params = new Constraint[]{eq("testAttribute"), eq(value)};
|
||||
mockRequest.expects(once()).method("setAttribute").with(params);
|
||||
mockRequest.expects(once()).method("getAttribute").with(eq("testAttribute")).will(returnValue(value));
|
||||
PortletRequestMap map = new PortletRequestMap((PortletRequest)mockRequest.proxy());
|
||||
Object obj = map.put("testAttribute", value);
|
||||
mockRequest.verify();
|
||||
assertEquals(obj, value);
|
||||
}
|
||||
|
||||
public void testClear() {
|
||||
Mock mockRequest = mock(PortletRequest.class, "testClear");
|
||||
|
||||
mockRequest.expects(once()).method("removeAttribute").with(eq("a"));
|
||||
mockRequest.expects(once()).method("removeAttribute").with(eq("b"));
|
||||
|
||||
ArrayList dummy = new ArrayList();
|
||||
dummy.add("a");
|
||||
dummy.add("b");
|
||||
|
||||
mockRequest.expects(once()).method("getAttributeNames").will(returnValue(Collections.enumeration(dummy)));
|
||||
|
||||
PortletRequestMap map = new PortletRequestMap((PortletRequest)mockRequest.proxy());
|
||||
map.clear();
|
||||
mockRequest.verify();
|
||||
}
|
||||
|
||||
public void testRemove() {
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
|
||||
|
||||
mockRequest.expects(once()).method("getAttribute").with(eq("dummyKey")).will(returnValue("dummyValue"));
|
||||
|
||||
mockRequest.expects(once()).method("removeAttribute").with(eq("dummyKey"));
|
||||
|
||||
PortletRequestMap map = new PortletRequestMap(req);
|
||||
Object ret = map.remove("dummyKey");
|
||||
assertEquals("dummyValue", ret);
|
||||
}
|
||||
|
||||
public void testEntrySet() {
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
|
||||
Enumeration names = new Enumeration() {
|
||||
|
||||
List keys = Arrays.asList(new Object[]{"key1", "key2"});
|
||||
Iterator it = keys.iterator();
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
return it.next();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
mockRequest.stubs().method("getAttributeNames").will(returnValue(names));
|
||||
mockRequest.stubs().method("getAttribute").with(eq("key1")).will(returnValue("value1"));
|
||||
mockRequest.stubs().method("getAttribute").with(eq("key2")).will(returnValue("value2"));
|
||||
|
||||
PortletRequestMap map = new PortletRequestMap(req);
|
||||
Set entries = map.entrySet();
|
||||
|
||||
assertEquals(2, entries.size());
|
||||
Iterator it = entries.iterator();
|
||||
Map.Entry entry = (Map.Entry)it.next();
|
||||
assertEquals("key2", entry.getKey());
|
||||
assertEquals("value2", entry.getValue());
|
||||
entry = (Map.Entry)it.next();
|
||||
assertEquals("key1", entry.getKey());
|
||||
assertEquals("value1", entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletSession;
|
||||
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.MockObjectTestCase;
|
||||
import org.jmock.core.Constraint;
|
||||
|
||||
|
||||
/**
|
||||
* PortletSessionMapTest. Insert description.
|
||||
*
|
||||
*/
|
||||
public class PortletSessionMapTest extends MockObjectTestCase {
|
||||
|
||||
public void testPut() {
|
||||
|
||||
Mock mockSession = mock(PortletSession.class);
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
PortletSession session = (PortletSession)mockSession.proxy();
|
||||
|
||||
mockRequest.expects(once()).method("getPortletSession").will(returnValue(session));
|
||||
Constraint[] params = new Constraint[]{eq("testAttribute1"), eq("testValue1")};
|
||||
mockSession.expects(once()).method("setAttribute").with(params);
|
||||
mockSession.expects(once()).method("getAttribute").with(eq("testAttribute1")).will(returnValue("testValue1"));
|
||||
params = new Constraint[]{eq("testAttribute2"), eq("testValue2")};
|
||||
mockSession.expects(once()).method("setAttribute").with(params);
|
||||
mockSession.expects(once()).method("getAttribute").with(eq("testAttribute2")).will(returnValue("testValue2"));
|
||||
|
||||
PortletSessionMap map = new PortletSessionMap(req);
|
||||
map.put("testAttribute1", "testValue1");
|
||||
map.put("testAttribute2", "testValue2");
|
||||
|
||||
}
|
||||
|
||||
public void testGet() {
|
||||
Mock mockSession = mock(PortletSession.class);
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
PortletSession session = (PortletSession)mockSession.proxy();
|
||||
|
||||
mockRequest.expects(once()).method("getPortletSession").will(returnValue(session));
|
||||
mockSession.expects(once()).method("getAttribute").with(eq("testAttribute1")).will(returnValue("testValue1"));
|
||||
mockSession.expects(once()).method("getAttribute").with(eq("testAttribute2")).will(returnValue("testValue2"));
|
||||
|
||||
PortletSessionMap map = new PortletSessionMap(req);
|
||||
Object val1 = map.get("testAttribute1");
|
||||
Object val2 = map.get("testAttribute2");
|
||||
assertEquals("testValue1", val1);
|
||||
assertEquals("testValue2", val2);
|
||||
}
|
||||
|
||||
public void testClear() {
|
||||
Mock mockSession = mock(PortletSession.class);
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
PortletSession session = (PortletSession)mockSession.proxy();
|
||||
|
||||
mockRequest.expects(once()).method("getPortletSession").will(returnValue(session));
|
||||
mockSession.expects(once()).method("invalidate");
|
||||
|
||||
PortletSessionMap map = new PortletSessionMap(req);
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public void testRemove() {
|
||||
Mock mockSession = mock(PortletSession.class);
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
PortletSession session = (PortletSession)mockSession.proxy();
|
||||
|
||||
|
||||
mockRequest.expects(once()).method("getPortletSession").will(returnValue(session));
|
||||
mockSession.stubs().method("getAttribute").with(eq("dummyKey")).will(returnValue("dummyValue"));
|
||||
mockSession.expects(once()).method("removeAttribute").with(eq("dummyKey"));
|
||||
|
||||
PortletSessionMap map = new PortletSessionMap(req);
|
||||
Object ret = map.remove("dummyKey");
|
||||
assertEquals("dummyValue", ret);
|
||||
}
|
||||
|
||||
public void testEntrySet() {
|
||||
Mock mockSession = mock(PortletSession.class);
|
||||
Mock mockRequest = mock(PortletRequest.class);
|
||||
|
||||
PortletRequest req = (PortletRequest)mockRequest.proxy();
|
||||
PortletSession session = (PortletSession)mockSession.proxy();
|
||||
|
||||
Enumeration names = new Enumeration() {
|
||||
|
||||
List keys = Arrays.asList(new Object[]{"key1", "key2"});
|
||||
Iterator it = keys.iterator();
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
return it.next();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
mockSession.stubs().method("getAttributeNames").will(returnValue(names));
|
||||
mockSession.stubs().method("getAttribute").with(eq("key1")).will(returnValue("value1"));
|
||||
mockSession.stubs().method("getAttribute").with(eq("key2")).will(returnValue("value2"));
|
||||
|
||||
mockRequest.expects(once()).method("getPortletSession").will(returnValue(session));
|
||||
|
||||
PortletSessionMap map = new PortletSessionMap(req);
|
||||
Set entries = map.entrySet();
|
||||
|
||||
assertEquals(2, entries.size());
|
||||
Iterator it = entries.iterator();
|
||||
Map.Entry entry = (Map.Entry)it.next();
|
||||
assertEquals("key2", entry.getKey());
|
||||
assertEquals("value2", entry.getValue());
|
||||
entry = (Map.Entry)it.next();
|
||||
assertEquals("key1", entry.getKey());
|
||||
assertEquals("value1", entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import junit.textui.TestRunner;
|
||||
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.MockObjectTestCase;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PortletActionContextTest extends MockObjectTestCase {
|
||||
|
||||
Mock mockRenderRequest;
|
||||
Mock mockRenderResponse;
|
||||
Mock mockPortletConfig;
|
||||
Mock mockActionRequest;
|
||||
Mock mockActionResponse;
|
||||
|
||||
RenderRequest renderRequest;
|
||||
RenderResponse renderResponse;
|
||||
|
||||
ActionRequest actionRequest;
|
||||
ActionResponse actionResponse;
|
||||
|
||||
PortletConfig portletConfig;
|
||||
|
||||
Map context = new HashMap();
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockRenderRequest = mock(RenderRequest.class);
|
||||
mockRenderResponse = mock(RenderResponse.class);
|
||||
mockActionRequest = mock(ActionRequest.class);
|
||||
mockActionResponse = mock(ActionResponse.class);
|
||||
mockPortletConfig = mock(PortletConfig.class);
|
||||
|
||||
renderRequest = (RenderRequest)mockRenderRequest.proxy();
|
||||
renderResponse = (RenderResponse)mockRenderResponse.proxy();
|
||||
actionRequest = (ActionRequest)mockActionRequest.proxy();
|
||||
actionResponse = (ActionResponse)mockActionResponse.proxy();
|
||||
portletConfig = (PortletConfig)mockPortletConfig.proxy();
|
||||
|
||||
|
||||
ActionContext.setContext(new ActionContext(context));
|
||||
}
|
||||
|
||||
public void testGetPhase() {
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
|
||||
assertEquals(PortletActionConstants.RENDER_PHASE, PortletActionContext.getPhase());
|
||||
}
|
||||
|
||||
public void testIsRender() {
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
|
||||
assertTrue(PortletActionContext.isRender());
|
||||
assertFalse(PortletActionContext.isEvent());
|
||||
}
|
||||
|
||||
public void testIsEvent() {
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.EVENT_PHASE);
|
||||
|
||||
assertTrue(PortletActionContext.isEvent());
|
||||
assertFalse(PortletActionContext.isRender());
|
||||
}
|
||||
|
||||
public void testGetPortletConfig() {
|
||||
context.put(PortletActionConstants.PORTLET_CONFIG, portletConfig);
|
||||
assertSame(portletConfig, PortletActionContext.getPortletConfig());
|
||||
}
|
||||
|
||||
public void testGetRenderRequestAndResponse() {
|
||||
context.put(PortletActionConstants.REQUEST, renderRequest);
|
||||
context.put(PortletActionConstants.RESPONSE, renderResponse);
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
assertSame(renderRequest, PortletActionContext.getRenderRequest());
|
||||
assertSame(renderResponse, PortletActionContext.getRenderResponse());
|
||||
assertSame(renderRequest, PortletActionContext.getRequest());
|
||||
assertSame(renderResponse, PortletActionContext.getResponse());
|
||||
}
|
||||
|
||||
public void testGetRenderRequestAndResponseInEventPhase() {
|
||||
context.put(PortletActionConstants.REQUEST, renderRequest);
|
||||
context.put(PortletActionConstants.RESPONSE, renderResponse);
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.EVENT_PHASE);
|
||||
try {
|
||||
PortletActionContext.getRenderRequest();
|
||||
fail("Should throw IllegalStateException!");
|
||||
}
|
||||
catch(IllegalStateException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
try {
|
||||
PortletActionContext.getRenderResponse();
|
||||
fail("Should throw IllegalStateException!");
|
||||
}
|
||||
catch(IllegalStateException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetActionRequestAndResponse() {
|
||||
context.put(PortletActionConstants.REQUEST, actionRequest);
|
||||
context.put(PortletActionConstants.RESPONSE, actionResponse);
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.EVENT_PHASE);
|
||||
assertSame(actionRequest, PortletActionContext.getActionRequest());
|
||||
assertSame(actionResponse, PortletActionContext.getActionResponse());
|
||||
assertSame(actionRequest, PortletActionContext.getRequest());
|
||||
assertSame(actionResponse, PortletActionContext.getResponse());
|
||||
}
|
||||
|
||||
public void testGetActionRequestAndResponseInRenderPhase() {
|
||||
context.put(PortletActionConstants.REQUEST, actionRequest);
|
||||
context.put(PortletActionConstants.RESPONSE, actionResponse);
|
||||
context.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
try {
|
||||
PortletActionContext.getActionRequest();
|
||||
fail("Should throw IllegalStateException!");
|
||||
}
|
||||
catch(IllegalStateException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
try {
|
||||
PortletActionContext.getActionResponse();
|
||||
fail("Should throw IllegalStateException!");
|
||||
}
|
||||
catch(IllegalStateException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetNamespace() {
|
||||
context.put(PortletActionConstants.PORTLET_NAMESPACE, "testNamespace");
|
||||
assertEquals("testNamespace", PortletActionContext.getPortletNamespace());
|
||||
}
|
||||
|
||||
public void testGetDefaultActionForMode() {
|
||||
ActionMapping mapping = new ActionMapping();
|
||||
context.put(PortletActionConstants.DEFAULT_ACTION_FOR_MODE, mapping);
|
||||
assertEquals(mapping, PortletActionContext.getDefaultActionForMode());
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
ActionContext.setContext(null);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestRunner.run(PortletActionContextTest.class);
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.context;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsTestCase;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
/**
|
||||
*
|
||||
* Test for the {@link PreparatorServletTest}
|
||||
*
|
||||
*/
|
||||
public class PreparatorServletTest extends StrutsTestCase {
|
||||
|
||||
/**
|
||||
* Test that the service method stores the request, response and servlet context
|
||||
* in the {@link com.opensymphony.xwork2.ActionContext}
|
||||
*/
|
||||
public void testServiceHttpServletRequestHttpServletResponse() throws Exception {
|
||||
MockControl mockRequest = MockControl.createNiceControl(HttpServletRequest.class);
|
||||
MockControl mockResponse = MockControl.createNiceControl(HttpServletResponse.class);
|
||||
MockControl mockContext = MockControl.createNiceControl(ServletContext.class);
|
||||
MockControl mockConfig = MockControl.createNiceControl(ServletConfig.class);
|
||||
|
||||
HttpServletRequest req = (HttpServletRequest)mockRequest.getMock();
|
||||
HttpServletResponse res = (HttpServletResponse)mockResponse.getMock();
|
||||
ServletContext context = (ServletContext)mockContext.getMock();
|
||||
ServletConfig config = (ServletConfig)mockConfig.getMock();
|
||||
|
||||
mockConfig.expectAndDefaultReturn(config.getServletContext(), context);
|
||||
mockConfig.replay();
|
||||
|
||||
PreparatorServlet servlet = new PreparatorServlet();
|
||||
servlet.init(config);
|
||||
servlet.service(req, res);
|
||||
assertSame(req, ServletActionContext.getRequest());
|
||||
assertSame(res, ServletActionContext.getResponse());
|
||||
assertSame(context, ServletActionContext.getServletContext());
|
||||
|
||||
mockConfig.verify();
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.context;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ServletContextHolderListenerTest extends TestCase {
|
||||
|
||||
public void testContextInitialized() {
|
||||
MockControl mockContext = MockControl.createNiceControl(ServletContext.class);
|
||||
ServletContext context = (ServletContext)mockContext.getMock();
|
||||
ServletContextEvent event = new ServletContextEvent(context);
|
||||
ServletContextHolderListener listener = new ServletContextHolderListener();
|
||||
listener.contextInitialized(event);
|
||||
assertSame(ServletContextHolderListener.getServletContext(), context);
|
||||
|
||||
listener.contextDestroyed(event);
|
||||
assertNull(ServletContextHolderListener.getServletContext());
|
||||
}
|
||||
|
||||
}
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.dispatcher;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListResourceBundle;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.WindowState;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
import junit.textui.TestRunner;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.context.ServletContextHolderListener;
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.cglib.MockObjectTestCase;
|
||||
import org.jmock.core.Constraint;
|
||||
|
||||
import com.opensymphony.xwork2.Action;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.ActionProxyFactory;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
|
||||
/**
|
||||
* Jsr168DispatcherTest. Insert description.
|
||||
*
|
||||
*/
|
||||
public class Jsr168DispatcherTest extends MockObjectTestCase implements PortletActionConstants {
|
||||
|
||||
Jsr168Dispatcher dispatcher = null;
|
||||
Mock mockConfig = null;
|
||||
Mock mockCtx = null;
|
||||
Mock mockRequest = null;
|
||||
Mock mockSession = null;
|
||||
Mock mockActionFactory = null;
|
||||
Mock mockActionProxy = null;
|
||||
Mock mockAction = null;
|
||||
Mock mockInvocation = null;
|
||||
|
||||
public void setUp() {
|
||||
dispatcher = new Jsr168Dispatcher();
|
||||
}
|
||||
|
||||
private void initPortletConfig(final Map initParams, final Map attributes) {
|
||||
mockConfig = mock(PortletConfig.class);
|
||||
mockCtx = mock(PortletContext.class);
|
||||
mockConfig.stubs().method(ANYTHING);
|
||||
setupStub(initParams, mockConfig, "getInitParameter");
|
||||
mockCtx.stubs().method("getAttributeNames").will(returnValue(Collections.enumeration(attributes.keySet())));
|
||||
setupStub(attributes, mockCtx, "getAttribute");
|
||||
mockConfig.stubs().method("getPortletContext").will(returnValue(mockCtx.proxy()));
|
||||
mockCtx.stubs().method("getInitParameterNames").will(returnValue(Collections.enumeration(initParams.keySet())));
|
||||
setupStub(initParams, mockCtx, "getInitParameter");
|
||||
mockConfig.stubs().method("getInitParameterNames").will(returnValue(Collections.enumeration(initParams.keySet())));
|
||||
setupStub(initParams, mockConfig, "getInitParameter");
|
||||
|
||||
mockConfig.stubs().method("getResourceBundle").will(returnValue(new ListResourceBundle() {
|
||||
protected Object[][] getContents() {
|
||||
return new String[][]{{"javax.portlet.title", "MyTitle"}};
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void setupActionFactory(String namespace, String actionName, String result, ValueStack stack) {
|
||||
if(mockActionFactory == null) {
|
||||
mockActionFactory = mock(ActionProxyFactory.class);
|
||||
}
|
||||
mockAction = mock(Action.class);
|
||||
mockActionProxy = mock(ActionProxy.class);
|
||||
mockInvocation = mock(ActionInvocation.class);
|
||||
|
||||
mockActionFactory.expects(once()).method("createActionProxy").with(new Constraint[]{eq(namespace), eq(actionName), isA(Map.class)}).will(returnValue(mockActionProxy.proxy()));
|
||||
mockActionProxy.stubs().method("getAction").will(returnValue(mockAction.proxy()));
|
||||
mockActionProxy.expects(once()).method("execute").will(returnValue(result));
|
||||
mockActionProxy.expects(once()).method("getInvocation").will(returnValue(mockInvocation.proxy()));
|
||||
mockActionProxy.expects(once()).method("setMethod");
|
||||
mockInvocation.stubs().method("getStack").will(returnValue(stack));
|
||||
|
||||
}
|
||||
|
||||
public void testRender_ok() {
|
||||
final Mock mockResponse = mock(RenderResponse.class);
|
||||
mockResponse.stubs().method(ANYTHING);
|
||||
final Mock servletContext = mock(ServletContext.class);
|
||||
servletContext.stubs().method(ANYTHING);
|
||||
ServletContextEvent event = new ServletContextEvent((ServletContext)servletContext.proxy());
|
||||
new ServletContextHolderListener().contextInitialized(event);
|
||||
PortletMode mode = PortletMode.VIEW;
|
||||
|
||||
Map requestParams = new HashMap();
|
||||
requestParams.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
|
||||
requestParams.put(EVENT_ACTION, new String[]{"true"});
|
||||
requestParams.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
|
||||
|
||||
Map sessionMap = new HashMap();
|
||||
|
||||
|
||||
|
||||
Map initParams = new HashMap();
|
||||
initParams.put("viewNamespace", "/view");
|
||||
initParams.put(StrutsConstants.STRUTS_ALWAYS_SELECT_FULL_NAMESPACE, "true");
|
||||
|
||||
initPortletConfig(initParams, new HashMap());
|
||||
initRequest(requestParams, new HashMap(), sessionMap, new HashMap(), PortletMode.VIEW, WindowState.NORMAL, false, null);
|
||||
setupActionFactory("/view", "testAction", "success", ValueStackFactory.getFactory().createValueStack());
|
||||
|
||||
mockInvocation.expects(once()).method("getStack").will(
|
||||
returnValue(null));
|
||||
//mockSession.expects(once()).method("setAttribute").with(new Constraint[]{eq(PortletActionConstants.LAST_MODE), eq(PortletMode.VIEW)});
|
||||
try {
|
||||
dispatcher
|
||||
.setActionProxyFactory((ActionProxyFactory) mockActionFactory
|
||||
.proxy());
|
||||
dispatcher.init((PortletConfig) mockConfig.proxy());
|
||||
dispatcher.render((RenderRequest) mockRequest.proxy(),
|
||||
(RenderResponse) mockResponse.proxy());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured");
|
||||
}
|
||||
}
|
||||
|
||||
public void testProcessAction_ok() {
|
||||
final Mock mockResponse = mock(ActionResponse.class);
|
||||
|
||||
PortletMode mode = PortletMode.VIEW;
|
||||
Map initParams = new HashMap();
|
||||
initParams.put("viewNamespace", "/view");
|
||||
|
||||
Map requestParams = new HashMap();
|
||||
requestParams.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
|
||||
requestParams.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
|
||||
|
||||
initParams.put(StrutsConstants.STRUTS_ALWAYS_SELECT_FULL_NAMESPACE, "true");
|
||||
initPortletConfig(initParams, new HashMap());
|
||||
initRequest(requestParams, new HashMap(), new HashMap(), new HashMap(), PortletMode.VIEW, WindowState.NORMAL, true, null);
|
||||
setupActionFactory("/view", "testAction", "success", ValueStackFactory.getFactory().createValueStack());
|
||||
Constraint[] paramConstraints = new Constraint[] {
|
||||
eq(PortletActionConstants.EVENT_ACTION), same(mockActionProxy.proxy()) };
|
||||
|
||||
mockSession.expects(once()).method("setAttribute").with(
|
||||
paramConstraints);
|
||||
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(
|
||||
new Constraint[] { eq(PortletActionConstants.EVENT_ACTION),
|
||||
eq("true") });
|
||||
|
||||
//mockSession.expects(once()).method("setAttribute").with(new Constraint[]{eq(PortletActionConstants.LAST_MODE), eq(PortletMode.VIEW)});
|
||||
try {
|
||||
dispatcher
|
||||
.setActionProxyFactory((ActionProxyFactory) mockActionFactory
|
||||
.proxy());
|
||||
dispatcher.init((PortletConfig) mockConfig.proxy());
|
||||
dispatcher.processAction((ActionRequest) mockRequest.proxy(),
|
||||
(ActionResponse) mockResponse.proxy());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the mock request (and as a result, the mock session)
|
||||
* @param requestParams The request parameters
|
||||
* @param requestAttributes The request attributes
|
||||
* @param sessionParams The session attributes
|
||||
* @param renderParams The render parameters. Will only be set if <code>isEvent</code> is <code>true</code>
|
||||
* @param mode The portlet mode
|
||||
* @param state The portlet window state
|
||||
* @param isEvent <code>true</code> when the request is an ActionRequest.
|
||||
* @param locale The locale. If <code>null</code>, the request will return <code>Locale.getDefault()</code>
|
||||
*/
|
||||
private void initRequest(Map requestParams, Map requestAttributes, Map sessionParams, Map renderParams, PortletMode mode, WindowState state, boolean isEvent, Locale locale) {
|
||||
mockRequest = isEvent ? mock(ActionRequest.class) : mock(RenderRequest.class);
|
||||
mockSession = mock(PortletSession.class);
|
||||
mockSession.stubs().method(ANYTHING);
|
||||
mockRequest.stubs().method(ANYTHING);
|
||||
setupStub(sessionParams, mockSession, "getAttribute");
|
||||
mockSession.stubs().method("getAttributeNames").will(returnValue(Collections.enumeration(sessionParams.keySet())));
|
||||
setupParamStub(requestParams, mockRequest, "getParameter");
|
||||
setupStub(requestAttributes, mockRequest, "getAttribute");
|
||||
mockRequest.stubs().method("getAttributeNames").will(returnValue(Collections.enumeration(requestAttributes.keySet())));
|
||||
mockRequest.stubs().method("getParameterMap").will(returnValue(requestParams));
|
||||
mockRequest.stubs().method("getParameterNames").will(returnValue(Collections.enumeration(requestParams.keySet())));
|
||||
mockRequest.stubs().method("getPortletSession").will(returnValue(mockSession.proxy()));
|
||||
if(locale != null) {
|
||||
mockRequest.stubs().method("getLocale").will(returnValue(locale));
|
||||
}
|
||||
else {
|
||||
mockRequest.stubs().method("getLocale").will(returnValue(Locale.getDefault()));
|
||||
}
|
||||
mockRequest.stubs().method("getPortletMode").will(returnValue(mode));
|
||||
mockRequest.stubs().method("getWindowState").will(returnValue(state));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestParams
|
||||
* @param mockRequest2
|
||||
* @param string
|
||||
*/
|
||||
private void setupParamStub(Map requestParams, Mock mockRequest, String method) {
|
||||
Map newMap = new HashMap();
|
||||
Iterator it = requestParams.keySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
Object key = it.next();
|
||||
String[] val = (String[])requestParams.get(key);
|
||||
newMap.put(key, val[0]);
|
||||
}
|
||||
setupStub(newMap, mockRequest, method);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up stubs for the mock.
|
||||
* @param map The map containing the <code>key</code> and <code>values</code>. The key is the
|
||||
* expected parameter to <code>method</code>, and value is the value that should be returned from
|
||||
* the stub.
|
||||
* @param mock The mock to initialize.
|
||||
* @param method The name of the method to stub.
|
||||
*/
|
||||
private void setupStub(Map map, Mock mock, String method) {
|
||||
Iterator it = map.keySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
Object key = it.next();
|
||||
Object val = map.get(key);
|
||||
mock.stubs().method(method).with(eq(key)).will(returnValue(val));
|
||||
}
|
||||
}
|
||||
|
||||
public void testModeChangeUsingPortletWidgets() {
|
||||
final Mock mockResponse = mock(RenderResponse.class);
|
||||
mockResponse.stubs().method(ANYTHING);
|
||||
PortletMode mode = PortletMode.EDIT;
|
||||
|
||||
Map requestParams = new HashMap();
|
||||
requestParams.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
|
||||
requestParams.put(EVENT_ACTION, new String[]{"false"});
|
||||
requestParams.put(PortletActionConstants.MODE_PARAM, new String[]{PortletMode.VIEW.toString()});
|
||||
|
||||
Map sessionMap = new HashMap();
|
||||
|
||||
Map initParams = new HashMap();
|
||||
initParams.put("viewNamespace", "/view");
|
||||
initParams.put("editNamespace", "/edit");
|
||||
|
||||
initPortletConfig(initParams, new HashMap());
|
||||
initRequest(requestParams, new HashMap(), sessionMap, new HashMap(), mode, WindowState.NORMAL, false, null);
|
||||
setupActionFactory("/edit", "default", "success", ValueStackFactory.getFactory().createValueStack());
|
||||
|
||||
mockInvocation.expects(once()).method("getStack").will(
|
||||
returnValue(null));
|
||||
//mockSession.expects(once()).method("setAttribute").with(new Constraint[]{eq(PortletActionConstants.LAST_MODE), eq(PortletMode.VIEW)});
|
||||
try {
|
||||
dispatcher
|
||||
.setActionProxyFactory((ActionProxyFactory) mockActionFactory
|
||||
.proxy());
|
||||
dispatcher.init((PortletConfig) mockConfig.proxy());
|
||||
dispatcher.render((RenderRequest) mockRequest.proxy(),
|
||||
(RenderResponse) mockResponse.proxy());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestRunner.run(Jsr168DispatcherTest.class);
|
||||
}
|
||||
|
||||
}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.result;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import junit.textui.TestRunner;
|
||||
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.cglib.MockObjectTestCase;
|
||||
import org.jmock.core.Constraint;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
/**
|
||||
* PortletResultTest. Insert description.
|
||||
*
|
||||
*/
|
||||
public class PortletResultTest extends MockObjectTestCase {
|
||||
|
||||
Mock mockInvocation = null;
|
||||
Mock mockConfig = null;
|
||||
Mock mockCtx = null;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockInvocation = mock(ActionInvocation.class);
|
||||
mockConfig = mock(PortletConfig.class);
|
||||
mockCtx = mock(PortletContext.class);
|
||||
|
||||
mockConfig.stubs().method(ANYTHING);
|
||||
mockConfig.stubs().method("getPortletContext").will(returnValue(mockCtx.proxy()));
|
||||
|
||||
Map paramMap = new HashMap();
|
||||
Map sessionMap = new HashMap();
|
||||
|
||||
Map context = new HashMap();
|
||||
context.put(ActionContext.SESSION, sessionMap);
|
||||
context.put(ActionContext.PARAMETERS, paramMap);
|
||||
context.put(PortletActionConstants.PORTLET_CONFIG, mockConfig.proxy());
|
||||
|
||||
ActionContext.setContext(new ActionContext(context));
|
||||
|
||||
mockInvocation.stubs().method("getInvocationContext").will(returnValue(ActionContext.getContext()));
|
||||
|
||||
}
|
||||
|
||||
public void testDoExecute_render() {
|
||||
Mock mockRequest = mock(RenderRequest.class);
|
||||
Mock mockResponse = mock(RenderResponse.class);
|
||||
Mock mockRd = mock(PortletRequestDispatcher.class);
|
||||
Mock mockPrep = mock(PortletRequestDispatcher.class);
|
||||
|
||||
RenderRequest req = (RenderRequest)mockRequest.proxy();
|
||||
RenderResponse res = (RenderResponse)mockResponse.proxy();
|
||||
PortletRequestDispatcher rd = (PortletRequestDispatcher)mockRd.proxy();
|
||||
PortletConfig cfg = (PortletConfig)mockConfig.proxy();
|
||||
PortletContext ctx = (PortletContext)mockCtx.proxy();
|
||||
ActionInvocation inv = (ActionInvocation)mockInvocation.proxy();
|
||||
|
||||
Constraint[] params = new Constraint[]{same(req), same(res)};
|
||||
mockRd.expects(once()).method("include").with(params);
|
||||
mockPrep.expects(once()).method("include").with(params);
|
||||
mockCtx.expects(once()).method("getRequestDispatcher").with(eq("/WEB-INF/pages/testPage.jsp")).will(returnValue(rd));
|
||||
mockCtx.expects(once()).method("getNamedDispatcher").with(eq("preparator")).will(returnValue(mockPrep.proxy()));
|
||||
mockResponse.expects(once()).method("setContentType").with(eq("text/html"));
|
||||
mockConfig.expects(once()).method("getPortletContext").will(returnValue(ctx));
|
||||
|
||||
mockRequest.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
|
||||
|
||||
ActionContext ctxMap = ActionContext.getContext();
|
||||
ctxMap.put(PortletActionConstants.RESPONSE, res);
|
||||
ctxMap.put(PortletActionConstants.REQUEST, req);
|
||||
ctxMap.put(PortletActionConstants.PORTLET_CONFIG, cfg);
|
||||
ctxMap.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
|
||||
PortletResult result = new PortletResult();
|
||||
try {
|
||||
result.doExecute("/WEB-INF/pages/testPage.jsp", inv);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testDoExecute_event_locationIsAction() {
|
||||
|
||||
Mock mockRequest = mock(ActionRequest.class);
|
||||
Mock mockResponse = mock(ActionResponse.class);
|
||||
|
||||
Constraint[] params = new Constraint[]{eq(PortletActionConstants.ACTION_PARAM), eq("testView")};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
params = new Constraint[]{eq(PortletActionConstants.MODE_PARAM), eq(PortletMode.VIEW.toString())};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
mockRequest.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
|
||||
ActionContext ctx = ActionContext.getContext();
|
||||
|
||||
ctx.put(PortletActionConstants.REQUEST, mockRequest.proxy());
|
||||
ctx.put(PortletActionConstants.RESPONSE, mockResponse.proxy());
|
||||
ctx.put(PortletActionConstants.PHASE, PortletActionConstants.EVENT_PHASE);
|
||||
|
||||
PortletResult result = new PortletResult();
|
||||
try {
|
||||
result.doExecute("testView.action", (ActionInvocation)mockInvocation.proxy());
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testDoExecute_event_locationIsJsp() {
|
||||
Mock mockRequest = mock(ActionRequest.class);
|
||||
Mock mockResponse = mock(ActionResponse.class);
|
||||
|
||||
Constraint[] params = new Constraint[]{eq(PortletActionConstants.ACTION_PARAM), eq("renderDirect")};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
params = new Constraint[]{eq("location"), eq("/WEB-INF/pages/testJsp.jsp")};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
params = new Constraint[]{eq(PortletActionConstants.MODE_PARAM), eq(PortletMode.VIEW.toString())};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
mockRequest.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
|
||||
|
||||
ActionContext ctx = ActionContext.getContext();
|
||||
|
||||
ctx.put(PortletActionConstants.REQUEST, mockRequest.proxy());
|
||||
ctx.put(PortletActionConstants.RESPONSE, mockResponse.proxy());
|
||||
ctx.put(PortletActionConstants.PHASE, PortletActionConstants.EVENT_PHASE);
|
||||
|
||||
PortletResult result = new PortletResult();
|
||||
try {
|
||||
result.doExecute("/WEB-INF/pages/testJsp.jsp", (ActionInvocation)mockInvocation.proxy());
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured!");
|
||||
}
|
||||
}
|
||||
|
||||
public void testDoExecute_event_locationHasQueryParams() {
|
||||
Mock mockRequest = mock(ActionRequest.class);
|
||||
Mock mockResponse = mock(ActionResponse.class);
|
||||
|
||||
Constraint[] params = new Constraint[]{eq(PortletActionConstants.ACTION_PARAM), eq("testView")};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
params = new Constraint[]{eq("testParam1"), eq("testValue1")};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
params = new Constraint[]{eq("testParam2"), eq("testValue2")};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
params = new Constraint[]{eq(PortletActionConstants.MODE_PARAM), eq(PortletMode.VIEW.toString())};
|
||||
mockResponse.expects(once()).method("setRenderParameter").with(params);
|
||||
mockRequest.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
|
||||
|
||||
ActionContext ctx = ActionContext.getContext();
|
||||
|
||||
ctx.put(PortletActionConstants.REQUEST, mockRequest.proxy());
|
||||
ctx.put(PortletActionConstants.RESPONSE, mockResponse.proxy());
|
||||
ctx.put(PortletActionConstants.PHASE, PortletActionConstants.EVENT_PHASE);
|
||||
|
||||
PortletResult result = new PortletResult();
|
||||
try {
|
||||
result.doExecute("testView.action?testParam1=testValue1&testParam2=testValue2", (ActionInvocation)mockInvocation.proxy());
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error occured!");
|
||||
}
|
||||
}
|
||||
|
||||
public void testTitleAndContentType() throws Exception {
|
||||
Mock mockRequest = mock(RenderRequest.class);
|
||||
Mock mockResponse = mock(RenderResponse.class);
|
||||
Mock mockRd = mock(PortletRequestDispatcher.class);
|
||||
Mock mockPrep = mock(PortletRequestDispatcher.class);
|
||||
|
||||
RenderRequest req = (RenderRequest)mockRequest.proxy();
|
||||
RenderResponse res = (RenderResponse)mockResponse.proxy();
|
||||
PortletRequestDispatcher rd = (PortletRequestDispatcher)mockRd.proxy();
|
||||
PortletConfig cfg = (PortletConfig)mockConfig.proxy();
|
||||
PortletContext ctx = (PortletContext)mockCtx.proxy();
|
||||
|
||||
Constraint[] params = new Constraint[]{same(req), same(res)};
|
||||
mockRd.expects(once()).method("include").with(params);
|
||||
mockPrep.expects(once()).method("include").with(params);
|
||||
mockCtx.expects(once()).method("getRequestDispatcher").with(eq("/WEB-INF/pages/testPage.jsp")).will(returnValue(rd));
|
||||
mockCtx.expects(once()).method("getNamedDispatcher").with(eq("preparator")).will(returnValue(mockPrep.proxy()));
|
||||
mockConfig.expects(once()).method("getPortletContext").will(returnValue(ctx));
|
||||
|
||||
mockRequest.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
|
||||
|
||||
ActionContext ctxMap = ActionContext.getContext();
|
||||
ctxMap.put(PortletActionConstants.RESPONSE, res);
|
||||
ctxMap.put(PortletActionConstants.REQUEST, req);
|
||||
ctxMap.put(PortletActionConstants.PORTLET_CONFIG, cfg);
|
||||
ctxMap.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
|
||||
mockResponse.expects(atLeastOnce()).method("setTitle").with(eq("testTitle"));
|
||||
mockResponse.expects(atLeastOnce()).method("setContentType").with(eq("testContentType"));
|
||||
|
||||
PortletResult result = new PortletResult();
|
||||
result.setTitle("testTitle");
|
||||
result.setContentType("testContentType");
|
||||
result.doExecute("/WEB-INF/pages/testPage.jsp", (ActionInvocation)mockInvocation.proxy());
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
ActionContext.setContext(null);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestRunner.run(PortletResultTest.class);
|
||||
}
|
||||
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.portlet.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletURL;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.WindowState;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.struts2.portlet.context.PortletActionContext;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PortletUrlHelperTest extends TestCase {
|
||||
|
||||
RenderResponse renderResponse;
|
||||
|
||||
RenderRequest renderRequest;
|
||||
|
||||
PortletURL url;
|
||||
|
||||
MockControl renderResponseControl;
|
||||
|
||||
MockControl renderRequestControl;
|
||||
|
||||
MockControl portletUrlControl;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
renderRequestControl = MockControl.createControl(RenderRequest.class);
|
||||
renderResponseControl = MockControl.createControl(RenderResponse.class);
|
||||
portletUrlControl = MockControl.createControl(PortletURL.class);
|
||||
|
||||
renderRequest = (RenderRequest) renderRequestControl.getMock();
|
||||
renderResponse = (RenderResponse) renderResponseControl.getMock();
|
||||
url = (PortletURL) portletUrlControl.getMock();
|
||||
|
||||
renderRequestControl.expectAndDefaultReturn(renderRequest
|
||||
.getPortletMode(), PortletMode.VIEW);
|
||||
renderRequestControl.expectAndDefaultReturn(renderRequest
|
||||
.getWindowState(), WindowState.NORMAL);
|
||||
|
||||
Map modeNamespaceMap = new HashMap();
|
||||
modeNamespaceMap.put("view", "/view");
|
||||
modeNamespaceMap.put("edit", "/edit");
|
||||
modeNamespaceMap.put("help", "/help");
|
||||
|
||||
Map context = new HashMap();
|
||||
context.put(PortletActionContext.REQUEST, renderRequest);
|
||||
context.put(PortletActionContext.RESPONSE, renderResponse);
|
||||
context.put(PortletActionContext.PHASE,
|
||||
PortletActionContext.RENDER_PHASE);
|
||||
context.put(PortletActionContext.MODE_NAMESPACE_MAP, modeNamespaceMap);
|
||||
|
||||
ActionContext.setContext(new ActionContext(context));
|
||||
|
||||
}
|
||||
|
||||
public void testCreateRenderUrlWithNoModeOrState() throws Exception {
|
||||
renderResponseControl.expectAndReturn(renderResponse.createRenderURL(),
|
||||
url);
|
||||
|
||||
url.setPortletMode(PortletMode.VIEW);
|
||||
url.setWindowState(WindowState.NORMAL);
|
||||
url.setParameters(null);
|
||||
portletUrlControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
renderRequestControl.replay();
|
||||
renderResponseControl.replay();
|
||||
portletUrlControl.replay();
|
||||
PortletUrlHelper.buildUrl("testAction", null,
|
||||
new HashMap(), null, null, null);
|
||||
portletUrlControl.verify();
|
||||
renderRequestControl.verify();
|
||||
renderResponseControl.verify();
|
||||
}
|
||||
|
||||
public void testCreateRenderUrlWithDifferentPortletMode() throws Exception {
|
||||
renderResponseControl.expectAndReturn(renderResponse.createRenderURL(),
|
||||
url);
|
||||
|
||||
url.setPortletMode(PortletMode.EDIT);
|
||||
url.setWindowState(WindowState.NORMAL);
|
||||
url.setParameters(null);
|
||||
portletUrlControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
renderRequestControl.replay();
|
||||
renderResponseControl.replay();
|
||||
portletUrlControl.replay();
|
||||
PortletUrlHelper.buildUrl("testAction", null,
|
||||
new HashMap(), null, "edit", null);
|
||||
portletUrlControl.verify();
|
||||
renderRequestControl.verify();
|
||||
renderResponseControl.verify();
|
||||
}
|
||||
|
||||
public void testCreateRenderUrlWithDifferentWindowState() throws Exception {
|
||||
renderResponseControl.expectAndReturn(renderResponse.createRenderURL(),
|
||||
url);
|
||||
|
||||
url.setPortletMode(PortletMode.VIEW);
|
||||
url.setWindowState(WindowState.MAXIMIZED);
|
||||
url.setParameters(null);
|
||||
portletUrlControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
renderRequestControl.replay();
|
||||
renderResponseControl.replay();
|
||||
portletUrlControl.replay();
|
||||
PortletUrlHelper.buildUrl("testAction", null,
|
||||
new HashMap(), null, null, "maximized");
|
||||
portletUrlControl.verify();
|
||||
renderRequestControl.verify();
|
||||
renderResponseControl.verify();
|
||||
}
|
||||
|
||||
public void testCreateActionUrl() throws Exception {
|
||||
renderResponseControl.expectAndReturn(renderResponse.createActionURL(),
|
||||
url);
|
||||
|
||||
url.setPortletMode(PortletMode.VIEW);
|
||||
url.setWindowState(WindowState.NORMAL);
|
||||
url.setParameters(null);
|
||||
portletUrlControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
renderRequestControl.replay();
|
||||
renderResponseControl.replay();
|
||||
portletUrlControl.replay();
|
||||
PortletUrlHelper.buildUrl("testAction", null,
|
||||
new HashMap(), "action", null, null);
|
||||
portletUrlControl.verify();
|
||||
renderRequestControl.verify();
|
||||
renderResponseControl.verify();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.views.jsp;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletURL;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.WindowState;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
|
||||
import junit.textui.TestRunner;
|
||||
|
||||
import org.apache.struts2.dispatcher.Dispatcher;
|
||||
import org.apache.struts2.portlet.PortletActionConstants;
|
||||
import org.apache.struts2.portlet.util.PortletUrlHelper;
|
||||
import org.jmock.Mock;
|
||||
import org.jmock.cglib.MockObjectTestCase;
|
||||
import org.jmock.core.Constraint;
|
||||
|
||||
import com.mockobjects.servlet.MockJspWriter;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PortletUrlTagTest extends MockObjectTestCase {
|
||||
|
||||
URLTag tag = new URLTag();
|
||||
|
||||
Mock mockHttpReq = null;
|
||||
|
||||
Mock mockHttpRes = null;
|
||||
|
||||
Mock mockPortletReq = null;
|
||||
|
||||
Mock mockPortletRes = null;
|
||||
|
||||
Mock mockPageCtx = null;
|
||||
|
||||
Mock mockPortletUrl = null;
|
||||
|
||||
MockJspWriter mockJspWriter = null;
|
||||
|
||||
ValueStack stack = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestRunner.run(PortletUrlTagTest.class);
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
Dispatcher du = new Dispatcher(null, new HashMap());
|
||||
du.init();
|
||||
Dispatcher.setInstance(du);
|
||||
|
||||
mockPortletApiAvailable();
|
||||
|
||||
stack = ValueStackFactory.getFactory().createValueStack();
|
||||
|
||||
|
||||
mockHttpReq = mock(HttpServletRequest.class);
|
||||
mockHttpRes = mock(HttpServletResponse.class);
|
||||
mockPortletReq = mock(RenderRequest.class);
|
||||
mockPortletRes = mock(RenderResponse.class);
|
||||
mockPageCtx = mock(PageContext.class);
|
||||
mockPortletUrl = mock(PortletURL.class);
|
||||
mockJspWriter = new MockJspWriter();
|
||||
|
||||
mockPageCtx.stubs().method("getRequest").will(
|
||||
returnValue((HttpServletRequest) mockHttpReq.proxy()));
|
||||
mockPageCtx.stubs().method("getResponse").will(
|
||||
returnValue((HttpServletResponse) mockHttpRes.proxy()));
|
||||
mockPageCtx.stubs().method("getOut").will(returnValue(mockJspWriter));
|
||||
|
||||
mockHttpReq.stubs().method("getScheme").will(returnValue("http"));
|
||||
mockHttpReq.stubs().method("getAttribute").with(
|
||||
eq("struts.valueStack")).will(returnValue(stack));
|
||||
mockHttpReq.stubs().method("getAttribute").with(
|
||||
eq("javax.portlet.response")).will(
|
||||
returnValue((PortletResponse) mockPortletRes.proxy()));
|
||||
mockHttpReq.stubs().method("getAttribute").with(
|
||||
eq("javax.portlet.request")).will(
|
||||
returnValue((PortletRequest) mockPortletReq.proxy()));
|
||||
|
||||
mockPortletReq.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
|
||||
mockPortletReq.stubs().method("getWindowState").will(returnValue(WindowState.NORMAL));
|
||||
mockPortletReq.stubs().method("getContextPath").will(returnValue("/contextPath"));
|
||||
|
||||
tag.setPageContext((PageContext) mockPageCtx.proxy());
|
||||
|
||||
Map modeMap = new HashMap();
|
||||
modeMap.put(PortletMode.VIEW, "/view");
|
||||
modeMap.put(PortletMode.HELP, "/help");
|
||||
modeMap.put(PortletMode.EDIT, "/edit");
|
||||
Map sessionMap = new HashMap();
|
||||
Map contextMap = new HashMap();
|
||||
contextMap.put(ActionContext.SESSION, sessionMap);
|
||||
contextMap.put(PortletActionConstants.REQUEST, mockPortletReq.proxy());
|
||||
contextMap.put(PortletActionConstants.RESPONSE, mockPortletRes.proxy());
|
||||
contextMap.put(PortletActionConstants.PHASE, PortletActionConstants.RENDER_PHASE);
|
||||
contextMap.put(PortletActionConstants.MODE_NAMESPACE_MAP, modeMap);
|
||||
ActionContext ctx = new ActionContext(contextMap);
|
||||
ctx.setValueStack(stack);
|
||||
ActionContext.setContext(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void mockPortletApiAvailable() {
|
||||
try {
|
||||
Field field = Dispatcher.class.getDeclaredField("portletSupportActive");
|
||||
field.setAccessible(true);
|
||||
field.set(null, Boolean.TRUE);
|
||||
}
|
||||
catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testEnsureParamsAreStringArrays() {
|
||||
Map params = new HashMap();
|
||||
params.put("param1", "Test1");
|
||||
params.put("param2", new String[] { "Test2" });
|
||||
|
||||
Map result = PortletUrlHelper.ensureParamsAreStringArrays(params);
|
||||
assertEquals(2, result.size());
|
||||
assertTrue(result.get("param1") instanceof String[]);
|
||||
}
|
||||
|
||||
public void testSetWindowState() throws Exception {
|
||||
|
||||
PortletMode mode = PortletMode.VIEW;
|
||||
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
|
||||
mockPortletRes.expects(once()).method("createRenderURL").will(
|
||||
returnValue((PortletURL) mockPortletUrl.proxy()));
|
||||
|
||||
Map paramMap = new HashMap();
|
||||
paramMap.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
|
||||
paramMap.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
|
||||
|
||||
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
|
||||
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.MAXIMIZED));
|
||||
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
|
||||
|
||||
tag.setAction("testAction");
|
||||
tag.setWindowState("maximized");
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
}
|
||||
|
||||
public void testSetPortletMode() throws Exception {
|
||||
|
||||
PortletMode mode = PortletMode.HELP;
|
||||
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
|
||||
mockPortletRes.expects(once()).method("createRenderURL").will(
|
||||
returnValue((PortletURL) mockPortletUrl.proxy()));
|
||||
|
||||
Map paramMap = new HashMap();
|
||||
paramMap.put(PortletActionConstants.ACTION_PARAM, new String[]{"/help/testAction"});
|
||||
paramMap.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
|
||||
|
||||
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
|
||||
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.HELP));
|
||||
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
|
||||
|
||||
tag.setAction("testAction");
|
||||
tag.setPortletMode("help");
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
}
|
||||
|
||||
public void testUrlWithQueryParams() throws Exception {
|
||||
|
||||
PortletMode mode = PortletMode.VIEW;
|
||||
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
|
||||
mockPortletRes.expects(once()).method("createRenderURL").will(
|
||||
returnValue((PortletURL) mockPortletUrl.proxy()));
|
||||
|
||||
Map paramMap = new HashMap();
|
||||
paramMap.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
|
||||
paramMap.put("testParam1", new String[]{"testValue1"});
|
||||
paramMap.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
|
||||
|
||||
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
|
||||
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
|
||||
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
|
||||
|
||||
tag.setAction("testAction?testParam1=testValue1");
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
}
|
||||
|
||||
public void testActionUrl() throws Exception {
|
||||
|
||||
PortletMode mode = PortletMode.VIEW;
|
||||
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
|
||||
mockPortletRes.expects(once()).method("createActionURL").will(
|
||||
returnValue((PortletURL) mockPortletUrl.proxy()));
|
||||
|
||||
Map paramMap = new HashMap();
|
||||
paramMap.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
|
||||
paramMap.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
|
||||
|
||||
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
|
||||
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
|
||||
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
|
||||
|
||||
tag.setAction("testAction");
|
||||
tag.setPortletUrlType("action");
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
}
|
||||
|
||||
public void testResourceUrl() throws Exception {
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
mockPortletRes.expects(once()).method("encodeURL").will(returnValue("/contextPath/image.gif"));
|
||||
mockJspWriter.setExpectedData("/contextPath/image.gif");
|
||||
tag.setValue("image.gif");
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
mockJspWriter.verify();
|
||||
}
|
||||
|
||||
public void testResourceUrlWithNestedParam() throws Exception {
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
mockPortletRes.expects(once()).method("encodeURL").with(eq("/contextPath/image.gif?testParam1=testValue1")).will(returnValue("/contextPath/image.gif?testParam1=testValue1"));
|
||||
mockJspWriter.setExpectedData("/contextPath/image.gif?testParam1=testValue1");
|
||||
|
||||
ParamTag paramTag = new ParamTag();
|
||||
paramTag.setPageContext((PageContext)mockPageCtx.proxy());
|
||||
paramTag.setParent(tag);
|
||||
paramTag.setName("testParam1");
|
||||
paramTag.setValue("'testValue1'");
|
||||
tag.setValue("image.gif");
|
||||
tag.doStartTag();
|
||||
paramTag.doStartTag();
|
||||
paramTag.doEndTag();
|
||||
tag.doEndTag();
|
||||
mockJspWriter.verify();
|
||||
}
|
||||
|
||||
public void testResourceUrlWithTwoNestedParam() throws Exception {
|
||||
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
|
||||
mockPortletRes.expects(once()).method("encodeURL").with(eq("/contextPath/image.gif?testParam1=testValue1&testParam2=testValue2")).will(returnValue("/contextPath/image.gif?testParam1=testValue1&testParam2=testValue2"));
|
||||
mockJspWriter.setExpectedData("/contextPath/image.gif?testParam1=testValue1&testParam2=testValue2");
|
||||
|
||||
ParamTag paramTag = new ParamTag();
|
||||
paramTag.setPageContext((PageContext)mockPageCtx.proxy());
|
||||
paramTag.setParent(tag);
|
||||
paramTag.setName("testParam1");
|
||||
paramTag.setValue("'testValue1'");
|
||||
ParamTag paramTag2 = new ParamTag();
|
||||
paramTag2.setPageContext((PageContext)mockPageCtx.proxy());
|
||||
paramTag2.setParent(tag);
|
||||
paramTag2.setName("testParam2");
|
||||
paramTag2.setValue("'testValue2'");
|
||||
tag.setValue("image.gif");
|
||||
tag.doStartTag();
|
||||
paramTag.doStartTag();
|
||||
paramTag.doEndTag();
|
||||
paramTag2.doStartTag();
|
||||
paramTag2.doEndTag();
|
||||
tag.doEndTag();
|
||||
mockJspWriter.verify();
|
||||
}
|
||||
|
||||
private static class ParamMapConstraint implements Constraint {
|
||||
|
||||
private Map myExpectedMap = null;
|
||||
private Map myActualMap = null;
|
||||
|
||||
public ParamMapConstraint(Map expectedMap) {
|
||||
if(expectedMap == null) {
|
||||
throw new IllegalArgumentException("Use an isNull constraint instead!");
|
||||
}
|
||||
myExpectedMap = expectedMap;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.jmock.core.Constraint#eval(java.lang.Object)
|
||||
*/
|
||||
public boolean eval(Object val) {
|
||||
myActualMap = (Map)val;
|
||||
boolean result = false;
|
||||
if(val != null) {
|
||||
if(myExpectedMap.size() == myActualMap.size()) {
|
||||
Iterator keys = myExpectedMap.keySet().iterator();
|
||||
boolean allSame = true;
|
||||
while(keys.hasNext()) {
|
||||
Object key = keys.next();
|
||||
if(!myActualMap.containsKey(key)) {
|
||||
allSame = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
String[] expected = (String[])myExpectedMap.get(key);
|
||||
String[] actual = (String[])myActualMap.get(key);
|
||||
if(!Arrays.equals(expected, actual)) {
|
||||
allSame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = allSame;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.jmock.core.SelfDescribing#describeTo(java.lang.StringBuffer)
|
||||
*/
|
||||
public StringBuffer describeTo(StringBuffer sb) {
|
||||
return sb.append(myExpectedMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user