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

Reply via email to