I'm one of the core developers from the uPortal project. While working
on administrative portlets for uPortal 3 I ran across the displaytag
library and would love to use it for rendering paged lists of data.
I was very excited when I found the documentation on the
RequestHelperFactory, RequestHelper and Href classes. Looking through
the documentation it looked like I could implement those three classes
and provide the appropriate PortletUrl generation. After doing so and
seeing the pagination URLs being generated without any change I looked
through the code and noticed many locations where "new Href()" is
being called, which rather defeats the usefulness of the RequestHelper
classes.
Looking through the archives I see there has been some discussion on
getting displaytag working with portlets. I tried looking at
http://jira.codehaus.org/browse/DISPL-268 but it looks like the Jira
instance is down right now.
I'd like to get some feedback on what changes need to be made in
displaytag to get it completely functional from within a JSR-168
portlet. I've attached the files that I created to attempt to get it
to work. They should work in any portal that uses jakarta Pluto as the
portlet container.
-Eric Dalquist
------------------------------------------------------------------------
/* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
* See license distributed with this file and
* available online at http://www.uportal.org/license.html
*/
package org.jasig.portal.portlets;
import javax.servlet.jsp.PageContext;
import org.displaytag.util.RequestHelper;
import org.displaytag.util.RequestHelperFactory;
/**
* @author Eric Dalquist <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>
* @version $Revision$
*/
public class PortletRequestHelperFactory implements RequestHelperFactory {
/**
* @see
org.displaytag.util.RequestHelperFactory#getRequestHelperInstance(javax.servlet.jsp.PageContext)
*/
public RequestHelper getRequestHelperInstance(PageContext context) {
return new PorletRequestHelper(context);
}
}
------------------------------------------------------------------------
/* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
* See license distributed with this file and
* available online at http://www.uportal.org/license.html
*/
package org.jasig.portal.portlets;
import java.util.Map;
import javax.portlet.PortletRequest;
import javax.portlet.RenderResponse;
import javax.servlet.ServletRequest;
import javax.servlet.jsp.PageContext;
import org.apache.pluto.Constants;
import org.displaytag.util.Href;
import org.displaytag.util.RequestHelper;
/**
* @author Eric Dalquist <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>
* @version $Revision$
*/
public class PorletRequestHelper implements RequestHelper {
private final PortletRequest portletRequest;
private final RenderResponse renderResponse;
public PorletRequestHelper(PageContext pageContext) {
if (pageContext == null) {
throw new IllegalArgumentException("pageContext may not be null");
}
//This is likely pluto specific
final ServletRequest servletRequest = pageContext.getRequest();
this.portletRequest =
(PortletRequest)servletRequest.getAttribute(Constants.PORTLET_REQUEST);
this.renderResponse =
(RenderResponse)servletRequest.getAttribute(Constants.PORTLET_RESPONSE);
}
/**
* @see org.displaytag.util.RequestHelper#getHref()
*/
public Href getHref() {
return new PortletHref(this.portletRequest, this.renderResponse);
}
/**
* @see org.displaytag.util.RequestHelper#getParameter(java.lang.String)
*/
public String getParameter(String key) {
return this.portletRequest.getParameter(key);
}
/**
* @see org.displaytag.util.RequestHelper#getIntParameter(java.lang.String)
*/
public Integer getIntParameter(String key) {
try {
return new Integer(this.getParameter(key));
}
catch (NumberFormatException nfe) {
return null;
}
}
/**
* @see org.displaytag.util.RequestHelper#getParameterMap()
*/
public Map getParameterMap() {
return this.portletRequest.getParameterMap();
}
}
------------------------------------------------------------------------
/* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
* See license distributed with this file and
* available online at http://www.uportal.org/license.html
*/
package org.jasig.portal.portlets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSecurityException;
import javax.portlet.PortletURL;
import javax.portlet.RenderResponse;
import javax.portlet.WindowState;
import javax.portlet.WindowStateException;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.InstanceofPredicate;
import org.apache.commons.collections.map.PredicatedMap;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.displaytag.util.Href;
/**
* @author Eric Dalquist <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>
* @version $Revision$
*/
public class PortletHref extends Href {
private static final Predicate PRED_TYPE_OF_STRING = new
InstanceofPredicate(String.class);
private static final Predicate PRED_TYPE_OF_STRING_ARRY = new
InstanceofPredicate(String[].class);
private static final String PARAM_PREFIX = "portlet:";
private static final String PARAM_MODE = PARAM_PREFIX + "mode";
private static final String PARAM_STATE = PARAM_PREFIX + "state";
private static final String PARAM_SECURE = PARAM_PREFIX + "secure";
private static final String PARAM_TYPE = PARAM_PREFIX + "type";
private static final String TYPE_RENDER = "render";
private static final String TYPE_ACTION = "action";
private final PortletRequest portletRequest;
private final RenderResponse renderResponse;
private final Map parameters = PredicatedMap.decorate(new HashMap(), PRED_TYPE_OF_STRING, PRED_TYPE_OF_STRING_ARRY);
private boolean isAction = false;
private PortletMode requestedMode = null;
private WindowState requestedState = null;
private boolean requestedSecure = false;
private String anchor = null;
public PortletHref(PortletRequest portletRequest, RenderResponse renderResponse) {
super("");
if (portletRequest == null) {
throw new IllegalArgumentException("portletRequest may not be null");
}
if (renderResponse == null) {
throw new IllegalArgumentException("renderResponse may not be null");
}
this.portletRequest = portletRequest;
this.renderResponse = renderResponse;
}
/**
* @see org.displaytag.util.Href#addParameter(java.lang.String, int)
*/
public Href addParameter(String name, int value) {
return this.addParameter(name, Integer.toString(value));
}
/**
* @see org.displaytag.util.Href#addParameter(java.lang.String,
java.lang.Object)
*/
public Href addParameter(String name, Object value) {
if (name != null && name.startsWith(PARAM_PREFIX)) {
final String valueString = (String)value;
if (PARAM_TYPE.equals(name)) {
if (TYPE_RENDER.equals(value)) {
this.isAction = false;
}
else if (TYPE_ACTION.equals(value)) {
this.isAction = true;
}
else {
throw new IllegalArgumentException("Value of parameter '" + name + "' must be equal to '"
+ TYPE_RENDER + "' or '" + TYPE_ACTION + "'. '" + value + "' is not allowed.");
}
}
else if (PARAM_SECURE.equals(name)) {
if (new Boolean(valueString).booleanValue()) {
this.requestedSecure = true;
}
else {
this.requestedSecure = false;
}
}
else if (PARAM_MODE.equals(name)) {
final PortletMode mode = new PortletMode(valueString);
if (!this.portletRequest.isPortletModeAllowed(mode)) {
throw new IllegalArgumentException("PortletMode '" + mode + "' is
not allowed for this request.");
}
this.requestedMode = mode;
}
else if (PARAM_STATE.equals(name)) {
final WindowState state = new WindowState(valueString);
if (!this.portletRequest.isWindowStateAllowed(state)) {
throw new IllegalArgumentException("WindowState '" + state + "'
is not allowed for this request.");
}
this.requestedState = state;
}
else {
throw new IllegalArgumentException("'" + name + "' is not a valid '" +
PARAM_PREFIX + "' prefixed parameter.");
}
}
final String[] realValue;
if (value instanceof String[]) {
realValue = (String[])value;
}
else {
realValue = new String[] { value.toString() };
}
this.parameters.put(name, realValue);
return this;
}
/**
* @see org.displaytag.util.Href#addParameterMap(java.util.Map)
*/
public void addParameterMap(Map parametersMap) {
for (final Iterator paramItr = parametersMap.entrySet().iterator();
paramItr.hasNext();) {
final Map.Entry entry = (Map.Entry)paramItr.next();
final String name = (String)entry.getKey();
final Object value = entry.getValue();
this.addParameter(name, value);
}
}
/**
* @see org.displaytag.util.Href#setParameterMap(java.util.Map)
*/
public void setParameterMap(Map parametersMap) {
this.parameters.clear();
this.addParameterMap(parametersMap);
}
/**
* @see org.displaytag.util.Href#getParameterMap()
*/
public Map getParameterMap() {
return this.parameters;
}
/**
* @see org.displaytag.util.Href#removeParameter(java.lang.String)
*/
public void removeParameter(String name) {
this.parameters.remove(name);
}
/**
* @see org.displaytag.util.Href#setAnchor(java.lang.String)
*/
public void setAnchor(String name) {
this.anchor = name;
}
/**
* @see org.displaytag.util.Href#getAnchor()
*/
public String getAnchor() {
return this.anchor;
}
/**
* @see org.displaytag.util.Href#getBaseUrl()
*/
public String getBaseUrl() {
return "";
}
/**
* @see org.displaytag.util.Href#clone()
*/
public Object clone() {
final PortletHref href = (PortletHref)super.clone();
href.isAction = this.isAction;
href.parameters.clear();
href.parameters.putAll(this.parameters);
href.requestedMode = this.requestedMode;
href.requestedState = this.requestedState;
href.requestedSecure = this.requestedSecure;
href.anchor = this.anchor;
return href;
}
/**
* @see org.displaytag.util.Href#equals(java.lang.Object)
*/
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof PortletHref)) {
return false;
}
PortletHref rhs = (PortletHref)object;
return new EqualsBuilder()
.append(this.isAction, rhs.isAction)
.append(this.parameters, rhs.parameters)
.append(this.requestedMode, rhs.requestedMode)
.append(this.requestedState, rhs.requestedState)
.append(this.requestedSecure, rhs.requestedSecure)
.append(this.anchor, rhs.anchor)
.isEquals();
}
/**
* @see org.displaytag.util.Href#hashCode()
*/
public int hashCode() {
return new HashCodeBuilder(1313733113, -431360889)
.append(this.isAction)
.append(this.parameters)
.append(this.requestedMode)
.append(this.requestedState)
.append(this.requestedSecure)
.append(this.anchor)
.toHashCode();
}
/**
* @see org.displaytag.util.Href#toString()
*/
public String toString() {
final PortletURL url;
if (this.isAction) {
url = this.renderResponse.createActionURL();
}
else {
url = this.renderResponse.createRenderURL();
}
if (this.requestedSecure) {
try {
url.setSecure(true);
}
catch (PortletSecurityException e) {
// TODO Auto-generated catch block
}
}
if (this.requestedMode != null) {
try {
url.setPortletMode(this.requestedMode);
}
catch (PortletModeException e) {
// TODO Auto-generated catch block
}
}
if (this.requestedState != null) {
try {
url.setWindowState(this.requestedState);
}
catch (WindowStateException e) {
// TODO Auto-generated catch block
}
}
url.setParameters(this.parameters);
if (this.anchor == null) {
return url.toString();
}
else {
return url.toString() + "#" + this.anchor;
}
}
}