Package org.jasig.portal.url

Source Code of org.jasig.portal.url.PortalUrlProviderImpl

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig 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.jasig.portal.url;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.portlet.PortletMode;
import javax.portlet.WindowState;
import javax.servlet.http.HttpServletRequest;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.IChannelRegistryStore;
import org.jasig.portal.IUserPreferencesManager;
import org.jasig.portal.channel.IChannelDefinition;
import org.jasig.portal.channels.portlet.IPortletAdaptor;
import org.jasig.portal.dao.usertype.FunctionalNameType;
import org.jasig.portal.layout.IUserLayout;
import org.jasig.portal.layout.IUserLayoutManager;
import org.jasig.portal.layout.TransientUserLayoutManagerWrapper;
import org.jasig.portal.layout.node.IUserLayoutChannelDescription;
import org.jasig.portal.layout.node.IUserLayoutNodeDescription;
import org.jasig.portal.portlet.om.IPortletDefinition;
import org.jasig.portal.portlet.om.IPortletEntity;
import org.jasig.portal.portlet.om.IPortletWindow;
import org.jasig.portal.portlet.om.IPortletWindowId;
import org.jasig.portal.portlet.registry.IPortletDefinitionRegistry;
import org.jasig.portal.portlet.registry.IPortletEntityRegistry;
import org.jasig.portal.portlet.registry.ITransientPortletWindowRegistry;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.user.IUserInstance;
import org.jasig.portal.user.IUserInstanceManager;
import org.springframework.web.util.UrlPathHelper;

/**
*
*
* @author Eric Dalquist
* @version $Revision: 21632 $
*/
public class PortalUrlProviderImpl implements IPortalUrlProvider, IUrlGenerator {
   
    public static final String SEPERATOR = "_";
    public static final String PORTAL_PARAM_PREFIX = "uP" + SEPERATOR;
    public static final String PORTLET_CONTROL_PREFIX = "pltc" + SEPERATOR;
    public static final String PORTLET_PARAM_PREFIX = "pltp" + SEPERATOR;

    public static final String PARAM_REQUEST_TARGET = PORTLET_CONTROL_PREFIX + "target";
    public static final String PARAM_WINDOW_STATE = PORTLET_CONTROL_PREFIX + "state";
    public static final String PARAM_PORTLET_MODE = PORTLET_CONTROL_PREFIX + "mode";
   
    public static final String NO_STATE_REGEX = ".*(normal|max|detached|exclusive|legacy).*";
    private static final Pattern NO_STATE_PATTERN = Pattern.compile(NO_STATE_REGEX);
    public static final String PORTAL_REQUEST_REGEX = "^(?:([^/]*)/)*(normal|max|detached|exclusive|legacy)/(?:([^/]*)/)?(render\\.uP|action\\.uP|)$";
    private static final Pattern PORTAL_REQUEST_PATTERN = Pattern.compile(PORTAL_REQUEST_REGEX);
   
    private static final String PORTAL_REQUEST_INFO_ATTR = PortalUrlProviderImpl.class.getName() + ".PORTAL_REQUEST_INFO";
   
    protected final Log logger = LogFactory.getLog(this.getClass());
   
    private String defaultEncoding = "UTF-8";
    private IUserInstanceManager userInstanceManager;
    private IPortletDefinitionRegistry portletDefinitionRegistry;
    private IPortletEntityRegistry portletEntityRegistry;
    private ITransientPortletWindowRegistry portletWindowRegistry;
    private IChannelRegistryStore channelRegistryStore;

    /**
     * @param defaultEncoding the defaultEncoding to set
     */
    public void setDefaultEncoding(String defaultEncoding) {
        this.defaultEncoding = defaultEncoding;
    }

    /**
     * @param userInstanceManager the userInstanceManager to set
     */
    public void setUserInstanceManager(IUserInstanceManager userInstanceManager) {
        this.userInstanceManager = userInstanceManager;
    }

    /**
     * @param portletDefinitionRegistry the portletDefinitionRegistry to set
     */
    public void setPortletDefinitionRegistry(IPortletDefinitionRegistry portletDefinitionRegistry) {
        this.portletDefinitionRegistry = portletDefinitionRegistry;
    }

    /**
     * @param portletEntityRegistry the portletEntityRegistry to set
     */
    public void setPortletEntityRegistry(IPortletEntityRegistry portletEntityRegistry) {
        this.portletEntityRegistry = portletEntityRegistry;
    }

    /**
     * @param portletWindowRegistry the portletWindowRegistry to set
     */
    public void setPortletWindowRegistry(ITransientPortletWindowRegistry portletWindowRegistry) {
        this.portletWindowRegistry = portletWindowRegistry;
    }
   
    /**
     * @param channelRegistryStore the channelRegistryStore to set
     */
    public void setChannelRegistryStore(IChannelRegistryStore channelRegistryStore) {
        this.channelRegistryStore = channelRegistryStore;
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.url.IPortalUrlProvider#getPortalRequestInfo(javax.servlet.http.HttpServletRequest)
     */
    public IPortalRequestInfo getPortalRequestInfo(HttpServletRequest request) throws InvalidPortalRequestException {       
        IPortalRequestInfo portalRequestInfo = (IPortalRequestInfo)request.getAttribute(PORTAL_REQUEST_INFO_ATTR);
        if (portalRequestInfo != null) {
            if(logger.isDebugEnabled()) {
                logger.debug("short-circuit: found portalRequestInfo within request attributes");
            }
            return portalRequestInfo;
        }
       
        final String requestPath = new UrlPathHelper().getPathWithinApplication(request);
        // first pass looks for absence of state
        Matcher firstPass = NO_STATE_PATTERN.matcher(requestPath);
        if(!firstPass.matches()) {
          // requestPath doesn't contain state
          // assume NORMAL state, not an action
          // and that requestPath solely contains folder information (no targeted channel)
          PortalRequestInfoImpl requestInfo = new PortalRequestInfoImpl();
          requestInfo.setUrlState(UrlState.NORMAL);
          requestInfo.setAction(false);
         
          String [] folderElements = requestPath.split("\\/");
            if(folderElements.length > 0) {
                requestInfo.setTargetedLayoutNodeId(folderElements[folderElements.length-1]);
            }
           
            if(logger.isDebugEnabled()) {
                logger.debug("finished building requestInfo: " + requestInfo);
            }
            return requestInfo;
        }
        // if we get here, the requestPath contains one of the states
        Matcher m = PORTAL_REQUEST_PATTERN.matcher(requestPath);
        if(m.matches()) {
            PortalRequestInfoImpl requestInfo = new PortalRequestInfoImpl();
            String folderInformation = m.group(1);
            String stateInformation = m.group(2);
            String channelInformation = m.group(3);
            String renderInformation = m.group(4);
           
            // upper case group(2) to get UrlState enum
            requestInfo.setUrlState(UrlState.valueOf(stateInformation.toUpperCase()));
            // true if group(4) matches "action", false otherwise
            requestInfo.setAction("action.uP".equals(renderInformation));
           
            // group(3) can be null - if so ignore setting targetedPortletWindowId and targetedChannelSubscribeId
            if(null != channelInformation) {
                // portletWindowId cannot contain a "."
                // if group(3) contains a ".", set subscribe Id to value after "."
                if(channelInformation.contains(".")) {
                    String [] channelElements = channelInformation.split("\\.");
                    IPortletWindowId portletWindowId = portletWindowRegistry.getPortletWindowId(channelElements[0]);
                    requestInfo.setTargetedPortletWindowId(portletWindowId);
                    requestInfo.setTargetedChannelSubscribeId(channelElements[1]);
                } else {
                    // no "." in group(3), just set as portletWindowId and leave targetedChannelSubscribeId null
                    IPortletWindowId portletWindowId = portletWindowRegistry.getPortletWindowId(channelInformation);
                    requestInfo.setTargetedPortletWindowId(portletWindowId);
                }
            }
           
            // group(1) may contain slashes to separate sub folders
            // set targetedLayoutNodeId to LAST folder
            if(!StringUtils.isBlank(folderInformation)) {
                String [] folderElements = folderInformation.split("\\/");
                if(folderElements.length > 0) {
                    requestInfo.setTargetedLayoutNodeId(folderElements[folderElements.length-1]);
                }
            }
           
            request.setAttribute(PORTAL_REQUEST_INFO_ATTR, requestInfo);
           
            if(logger.isDebugEnabled()) {
                logger.debug("finished building requestInfo: " + requestInfo);
            }
            return requestInfo;
        } else {
            throw new InvalidPortalRequestException("could not extract portal request from " + requestPath);
        }
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.url.IPortalUrlProvider#getDefaultUrl(javax.servlet.http.HttpServletRequest)
     */
    public IBasePortalUrl getDefaultUrl(HttpServletRequest request) {
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
        // TODO is this the user's default folder?
        final String rootFolderId = userLayoutManager.getRootFolderId();
       
        //TODO determine default active tab for user
        // xpath may look like: /layout/folder/folder[type='regular' and hidden='false'][0]/@ID
       
        // call out to getFolderUrlByNodeId, pass in default nodeId for user
        return getFolderUrlByNodeId(request, rootFolderId);
       
        //return new PortalLayoutUrlImpl(request, this, rootFolderId);
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.url.IPortalUrlProvider#getFolderUrlByNodeId(javax.servlet.http.HttpServletRequest, java.lang.String)
     */
    public IBasePortalUrl getFolderUrlByNodeId(HttpServletRequest request, String folderNodeId) {
        final String resolvedFolderId = this.verifyFolderId(request, folderNodeId);
        return new PortalLayoutUrlImpl(request, this, resolvedFolderId);

    }
   
    /* (non-Javadoc)
     * @see org.jasig.portal.url.IPortalUrlProvider#getPortletUrlByNodeId(javax.servlet.http.HttpServletRequest, org.jasig.portal.portlet.om.IPortletWindowId)
     */
    public IPortalPortletUrl getPortletUrl(HttpServletRequest request, IPortletWindowId portletWindowId) {
        return new PortalPortletUrlImpl(request, this, portletWindowId);
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.url.IPortalUrlProvider#getPortletUrlByFName(javax.servlet.http.HttpServletRequest, java.lang.String)
     */
    public IPortalPortletUrl getPortletUrlByFName(HttpServletRequest request, String portletFName) {
        //Get the user's layout manager
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
       
        //Determine the subscribe ID
        final String channelSubscribeId = userLayoutManager.getSubscribeId(portletFName);
        if (channelSubscribeId == null) {
            throw new IllegalArgumentException("No channel subscribe ID found for fname '" + portletFName + "'.");
        }
       
        return this.getPortletUrlByNodeId(request, channelSubscribeId);
    }

    /* (non-Javadoc)
     * @see org.jasig.portal.url.IPortalUrlProvider#getPortletUrlByNodeId(javax.servlet.http.HttpServletRequest, java.lang.String)
     */
    public IPortalPortletUrl getPortletUrlByNodeId(HttpServletRequest request, String portletNodeId) {
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
       
        //Find the channel and portlet definitions
        final IUserLayoutChannelDescription channelNode = (IUserLayoutChannelDescription)userLayoutManager.getNode(portletNodeId);
        final String channelPublishId = channelNode.getChannelPublishId();
        final IChannelDefinition channelDefinition = this.channelRegistryStore.getChannelDefinition(channelPublishId);
        if(null == channelDefinition) {
            throw new IllegalArgumentException("No channel definition found for publish id: " + channelPublishId);
        }
        final IPortletDefinition portletDefinition = this.portletDefinitionRegistry.getPortletDefinition(channelDefinition.getId());
        if (portletDefinition == null) {
            throw new IllegalArgumentException("No portlet defintion found for channel definition '" + channelDefinition.getId() + "'.");
        }
       
        //Determine the appropriate portlet window ID
        final IPerson person = userInstance.getPerson();
        final IPortletEntity portletEntity = this.portletEntityRegistry.getOrCreatePortletEntity(portletDefinition.getPortletDefinitionId(), portletNodeId, person.getID());
        final IPortletWindow defaultPortletWindow = this.portletWindowRegistry.createDefaultPortletWindow(request, portletEntity.getPortletEntityId());
        final IPortletWindowId portletWindowId = this.portletWindowRegistry.createTransientPortletWindowId(request, defaultPortletWindow.getPortletWindowId());
       
        return this.getPortletUrl(request, portletWindowId);
    }
   

    protected String verifyFolderId(HttpServletRequest request, String folderNodeId) {
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
        final IUserLayoutNodeDescription node = userLayoutManager.getNode(folderNodeId);
       
        if (node == null) {
            throw new IllegalArgumentException("No layout node exists for id: " + folderNodeId);
        }
        if (node.getType() != IUserLayoutNodeDescription.FOLDER) {
            throw new IllegalArgumentException("Layout node is not a folder for id: " + folderNodeId);
        }
       
        final String resolvedFolderId = node.getId();
        return resolvedFolderId;
    }
   
    /**
     * Tries to determine the encoded from the request, if not available falls back to configured default.
     *
     * @param request The current request.
     * @return The encoding to use.
     */
    protected String getEncoding(HttpServletRequest request) {
        final String encoding = request.getCharacterEncoding();
        if (encoding != null) {
            return encoding;
        }
       
        return this.defaultEncoding;
    }
   
   
    protected void encodeAndAppend(StringBuilder url, String encoding, String name, String... values) {
        this.encodeAndAppend(url, encoding, name, Arrays.asList(values));
    }
   
    /**
     * Encodes parameter name and value(s) on to the url using the specified encoding. The option to pass more than one
     * value is provided to avoid encoding the same name multiple times. 
     *
     * @param url The URL StringBuilder to append the parameters to
     * @param encoding The encoding to use.
     * @param name The name of the parameter
     * @param values The values for the parameter, a & will be appended between each name/value pair added when multiple values are passed.
     */
    protected void encodeAndAppend(StringBuilder url, String encoding, String name, List<String> values) {
        try {
            name = URLEncoder.encode(name, encoding);
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Failed to encode portlet URL parameter name '" + name + "' for encoding '" + encoding + "'");
        }
       
        if (values.size() == 0) {
            url.append(name).append("=");
        }
        else {
            for (final Iterator<String> valueItr = values.iterator(); valueItr.hasNext(); ) {
                String value = valueItr.next();
                if (value == null) {
                    value = "";
                }
               
                try {
                    value = URLEncoder.encode(value, encoding);
                }
                catch (UnsupportedEncodingException e) {
                    throw new RuntimeException("Failed to encode portlet URL parameter value '" + value + "' for encoding '" + encoding + "'");
                }
               
                url.append(name).append("=").append(value);
               
                if (valueItr.hasNext()) {
                    url.append("&");
                }
            }
        }
    }

    /**
     * @param request The current requet
     * @return The base URL, will be absolute (start with / or protocol://) and will end with a /
     */
    protected StringBuilder getUrlBase(HttpServletRequest request) {
        final StringBuilder url = new StringBuilder(request.getContextPath());
       
        //Make sure the URL starts with a /
        if (url.charAt(0) != '/') {
            url.insert(0, '/');
        }
       
        //Make sure the URL ends with a /
        if (url.charAt(url.length() - 1) != '/') {
            url.append('/');
        }

        return url;
    }
   
   
    /* (non-Javadoc)
     * @see org.jasig.portal.url.IUrlGenerator#generatePortalUrl(javax.servlet.http.HttpServletRequest, org.jasig.portal.url.IBasePortalUrl, java.lang.String)
     */
    public String generatePortalUrl(HttpServletRequest request, IBasePortalUrl basePortalUrl, String targetFolderId) {
        final StringBuilder url = this.getUrlBase(request);

        //Add targeted folder id
        final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
        final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
        final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
        final IUserLayout userLayout = userLayoutManager.getUserLayout();
       
        final XPathExpression findChannelTabExpression = this.getFindChannelTabIdExpression(targetFolderId);
        final String tabId = userLayout.findNodeId(findChannelTabExpression);
       
        //Add folder ID of parent tab if it exists
        if (tabId != null) {
            final String folderId = this.verifyFolderId(request, tabId);
            url.append("/").append(folderId);
        }
       
       
        final String folderId = this.verifyFolderId(request, targetFolderId);
        url.append("/").append(folderId);

        //TODO need to allow portal URLs to set the UrlState
        //TODO need to determine current URL state if specific UrlState is not already set?
        //Add state information - call out to getPortalRequestInfo to get UrlState, and action?
        // basePortalUrl may not have the ability to set state, also may never be action
        url.append("/").append(UrlState.NORMAL);
        //TODO are portal URLs always render URLs?
        url.append("/render.uP");

        //Add all portal parameters
        final Map<String, List<String>> portalParameters = basePortalUrl.getPortalParameters();
        if (portalParameters.size() > 0) {
            final String encoding = this.getEncoding(request);
           
            String seperator = "?";
            for (final Map.Entry<String, List<String>> paramEntry : portalParameters.entrySet()) {
                final String name = paramEntry.getKey();
                final List<String> values = paramEntry.getValue();
                this.encodeAndAppend(url.append(seperator), encoding, PORTAL_PARAM_PREFIX + name, values);
                seperator = "&";
            }
        }
       
        return url.toString();
    }
   
    /* (non-Javadoc)
     * @see org.jasig.portal.url.IUrlGenerator#generatePortletUrl(javax.servlet.http.HttpServletRequest, org.jasig.portal.url.IPortalPortletUrl, org.jasig.portal.portlet.om.IPortletWindowId)
     */
    public String generatePortletUrl(HttpServletRequest request, IPortalPortletUrl portalPortletUrl, IPortletWindowId portletWindowId) {
        Validate.notNull(request, "HttpServletRequest was null");
        Validate.notNull(portalPortletUrl, "IPortalPortletUrl was null");
        Validate.notNull(portletWindowId, "IPortletWindowId was null");
      
        final StringBuilder url = this.getUrlBase(request);
       
        final IPortletWindow portletWindow = this.portletWindowRegistry.getPortletWindow(request, portletWindowId);
        final IPortletEntity portletEntity = this.portletEntityRegistry.getPortletEntity(portletWindow.getPortletEntityId());
       
        //Add folder information if available: /tabId
        final String channelSubscribeId = portletEntity.getChannelSubscribeId();
        // if not a transient node, we need to lookup user layout information
        if (!channelSubscribeId.startsWith(TransientUserLayoutManagerWrapper.SUBSCRIBE_PREFIX)) {
            final IUserInstance userInstance = this.userInstanceManager.getUserInstance(request);
            final IUserPreferencesManager preferencesManager = userInstance.getPreferencesManager();
            final IUserLayoutManager userLayoutManager = preferencesManager.getUserLayoutManager();
            final IUserLayout userLayout = userLayoutManager.getUserLayout();
           
            final XPathExpression findChannelTabExpression = this.getFindChannelTabIdExpression(channelSubscribeId);
            final String tabId = userLayout.findNodeId(findChannelTabExpression);
           
            //Add folder ID of parent tab if it exists
            if (tabId != null) {
                final String folderId = this.verifyFolderId(request, tabId);
                url.append(folderId);
                url.append("/");
            }
        }
       
        //Add state information
        final WindowState requestedWindowState = portalPortletUrl.getWindowState();
        final WindowState currentWindowState = portletWindow.getWindowState();
        final WindowState urlWindowState = requestedWindowState != null ? requestedWindowState : currentWindowState;
     
        String windowStateString = UrlState.NORMAL.toString().toLowerCase();
        if (WindowState.MAXIMIZED.equals(urlWindowState)) {
            windowStateString = UrlState.MAX.toString().toLowerCase();
        }
        else if (IPortletAdaptor.DETACHED.equals(urlWindowState)) {
            windowStateString = UrlState.DETACHED.toString().toLowerCase();
        }
        else if (IPortletAdaptor.EXCLUSIVE.equals(urlWindowState)) {
            windowStateString = UrlState.EXCLUSIVE.toString().toLowerCase();
        }
        else {
            this.logger.warn("Unknown WindowState '" + urlWindowState + "' specified for portlet window " + portletWindow + ", defaulting to NORMAL");
        }
        url.append(windowStateString);
       
        //Add channel information: /fname.chanid
        final IPortletDefinition portletDefinition = this.portletDefinitionRegistry.getPortletDefinition(portletEntity.getPortletDefinitionId());
        final IChannelDefinition channelDefinition = portletDefinition.getChannelDefinition();
        final String fname = channelDefinition.getFName();
        final String validFname = FunctionalNameType.INVALID_CHARS_PATTERN.matcher(fname).replaceAll("_");
        url.append("/").append(validFname).append(".").append(channelSubscribeId);
       
        //File part
        if (portalPortletUrl.isAction()) {
            url.append("/action.uP");
        }
        else {
            url.append("/render.uP");
        }
        final String encoding = this.getEncoding(request);
       
        //Query String 
        //Target portlet window info
        this.encodeAndAppend(url.append("?"), encoding, PARAM_REQUEST_TARGET, portletWindowId.getStringId());
         
        //Portlet mode info
        final PortletMode portletMode = portalPortletUrl.getPortletMode();
        if (portletMode != null && !portletMode.equals(portletWindow.getPortletMode())) {
            this.encodeAndAppend(url.append("&"), encoding, PARAM_PORTLET_MODE, portletMode.toString());
        }
       
        //Add window state param for switching between normal and maximized
        if (requestedWindowState != null && !requestedWindowState.equals(currentWindowState)
                && (WindowState.MINIMIZED.equals(urlWindowState) || WindowState.NORMAL.equals(urlWindowState))) {
            this.encodeAndAppend(url.append("&"), encoding, PARAM_WINDOW_STATE, requestedWindowState.toString());
        }
       
        //Add all portal parameters
        final Map<String, List<String>> portalParameters = portalPortletUrl.getPortalParameters();
        for (final Map.Entry<String, List<String>> paramEntry : portalParameters.entrySet()) {
            final String name = paramEntry.getKey();
            final List<String> values = paramEntry.getValue();
            this.encodeAndAppend(url.append("&"), encoding, PORTAL_PARAM_PREFIX + name, values);
        }

        //Add all portlet parameters
        final Map<String, List<String>> portletParameters = portalPortletUrl.getPortletParameters();
        for (final Map.Entry<String, List<String>> paramEntry : portletParameters.entrySet()) {
            final String name = paramEntry.getKey();
            final List<String> values = paramEntry.getValue();
            this.encodeAndAppend(url.append("&"), encoding, PORTLET_PARAM_PREFIX + name, values);
        }
       
        if(logger.isDebugEnabled()) {
            logger.debug("finished portlet url: " + url.toString());
        }
        return url.toString();
    }
   
   
    protected XPathExpression getFindChannelTabIdExpression(String channelNodeId) {
        final String expression = "/layout/folder/folder[descendant::channel[@ID='" + channelNodeId + "']]/@ID";
       
        final XPathFactory xPathFactory = XPathFactory.newInstance();
        final XPath xPath = xPathFactory.newXPath();
        try {
            //TODO compile the expression once and cache it!
            return xPath.compile(expression);
        }
        catch (XPathExpressionException e) {
            throw new IllegalArgumentException("Invalid XPath expression: " + expression, e);
        }
    }
   
   
    protected XPathExpression getFindTabIdExpression(String tabNodeId) {
        final String expression = "/layout/folder/folder[@ID='" + tabNodeId + "']/@ID";
       
        final XPathFactory xPathFactory = XPathFactory.newInstance();
        final XPath xPath = xPathFactory.newXPath();
        try {
            //TODO compile the expression once and cache it!
            return xPath.compile(expression);
        }
        catch (XPathExpressionException e) {
            throw new IllegalArgumentException("Invalid XPath expression: " + expression, e);
        }
    }
}
TOP

Related Classes of org.jasig.portal.url.PortalUrlProviderImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.