/* =============================================================================== * * Part of the InfoGlue Content Management Platform (www.infoglue.org) * * =============================================================================== * * Copyright (C) * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2, as published by the * Free Software Foundation. See the file LICENSE.html for more information. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple * Place, Suite 330 / Boston, MA 02111-1307 / USA. * * =============================================================================== */ package org.infoglue.deliver.portal; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.portlet.PortletMode; import javax.portlet.WindowState; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.pluto.om.window.PortletWindow; /** * Represents an portal URL including control parameters. * * @author jand * @author robert */ public class PortalControlURL { private static final Log log = LogFactory.getLog(PortalControlURL.class); public static final String IG = "_ig_"; public static final String RENDER = "_rp_"; public static final String ACTION = "_ac"; public static final String PID = "_pid"; public static final String MULTI_VALUE = "__"; private String contextPath; private String realPath; private String webWorkAction; private Map queryParams; // ?<str> private Map pathParams; private String local; // #<str> /** * Constructor * * @param req current request */ public PortalControlURL(HttpServletRequest req) { // TODO ok to unwrap request? It seems it must be done while (req instanceof HttpServletRequestWrapper) { req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest(); } this.contextPath = req.getContextPath(); String path = req.getRequestURI(); if (contextPath != null && path.length() > 0) { path = path.substring(contextPath.length(), path.length()); } if (path.endsWith(".action")) { int last = path.lastIndexOf("/"); this.webWorkAction = path.substring(last + 1); path = path.substring(0, last); } this.realPath = PathParser.getRealPath(path); this.queryParams = PathParser.copyParameters(req.getParameterMap()); this.pathParams = PathParser.parsePathParameters("_", path, true); log.debug("realPath: " + realPath); log.debug("wwAction: " + webWorkAction); } /** * Copy-constructor * * @param url copy this portal control URL */ public PortalControlURL(PortalControlURL url) { this.contextPath = url.contextPath; this.realPath = url.realPath; this.webWorkAction = url.webWorkAction; this.queryParams = new HashMap(url.queryParams.size()); this.queryParams.putAll(url.queryParams); this.pathParams = new HashMap(url.pathParams.size()); this.pathParams.putAll(url.pathParams); } public PortletMode getPortletMode(PortletWindow window) { // TODO fixme return PortletMode.VIEW; } public PortletMode getPreviousPortletMode(PortletWindow portletWindow) { // TODO fixme return PortletMode.VIEW; } public WindowState getWindowState(PortletWindow portletWindow) { // TODO fixme return WindowState.NORMAL; } public WindowState getPreviousWindowState(PortletWindow portletWindow) { // TODO fixme return WindowState.NORMAL; } public void setPortletMode(PortletWindow window, PortletMode mode) { // TODO implement } public void setPortletWindowState(PortletWindow window, WindowState state) { // TODO implement } public void setPortletId(PortletWindow window) { setPathParameter(PID, new String[] { window.getId().toString()}); } // general param public void setPathParameter(String nsName, String[] values) { if (values == null || values.length == 0) { pathParams.remove(nsName); } else { pathParams.put(nsName, values); } } // --- ACTION param /** * Get the window-id of current request. * * @return window-id or null if no action. */ public String getActionWindowID() { String[] values = (String[]) pathParams.get(ACTION); if (values != null && values.length > 0) { return values[0]; } return null; } public void setActionParameter(PortletWindow window) { setPathParameter(ACTION, new String[] { window.getId().toString()}); } public void clearActionParameter() { pathParams.remove(ACTION); pathParams.remove(PID); } // --- RENDER params /** * Get all render parameters of a window. * Note: the resulting Map will not contain namespaced parameters. * * @param window Window */ public Map getRenderParameterMap(PortletWindow window) { Map result = new HashMap(); int nsSize = RENDER.length() + window.getId().toString().length() + 1; for (Iterator iter = pathParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); if (name.startsWith(RENDER + window.getId())) { String paramName = name.substring(nsSize); result.put(paramName, pathParams.get(name)); } } return result; } /** * Set render parameter of window. * * @param window Window * @param name Parameter-name (not namespaced) * @param values Parameter-values */ public void setRenderParameter(PortletWindow window, String name, String[] values) { String nsName = RENDER + window.getId() + "_" + name; setPathParameter(nsName, values); } /** * Clear render parameters of window. * * @param window Window */ public void clearRenderParameters(PortletWindow window) { for (Iterator iter = pathParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); if (name.startsWith(RENDER + window.getId())) { //pathParams.remove(name); iter.remove(); } } } // QUERY params /** * Get all query (action) parameters of a window. * Note: the resulting Map will _not_ contain namespaced parameters. * * @param window Window */ public Map getQueryParameterMap(PortletWindow window) { return queryParams; } /** * Get all query (action) parameters of a window. * Note: the resulting Map will contain namespaced parameters. * * @param window Window */ public Map getQueryParameterMap() { return queryParams; } /** * Set query (action) parameter of window. * Note: current implementation does not namespace parameters * * @param window Window * @param name Parameter-name (not namespaced) * @param values Parameter-values */ public void setQueryParameter(PortletWindow window, String name, String[] values) { String nsName = name; // Prepared for namespaced params if (values == null || values.length == 0) { queryParams.remove(nsName); } else { queryParams.put(nsName, values); } } public void clearQueryParameters() { queryParams.clear(); } /** * Generates an portal URL. * Format: 'context/realPath/control-params/infoglueServletPath?query-params#local' * where 'control-params': _type_pid_name/[value | __value1/__value2]/... * separated by '/'. */ public String toString() { StringBuffer buf = new StringBuffer(); // Append context-path buf.append(contextPath); // Append real path (path besides control params, think "niceuri") if (realPath != null) { buf.append(realPath); } // Append "control-parameters" if (!pathParams.isEmpty()) { buf.append("/"); for (Iterator iter = pathParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) pathParams.get(name); buf.append(name); buf.append("/"); buf.append(PathParser.encodeValues(values)); if (iter.hasNext()) { buf.append("/"); } } } // Append servlet-path (infoglue-action) if (webWorkAction != null) { buf.append("/"); buf.append(webWorkAction); } // Append query-parameters if (!queryParams.isEmpty()) { buf.append("?"); for (Iterator iter = queryParams.keySet().iterator(); iter.hasNext();) { // Iterating over names String name = (String) iter.next(); String[] values = (String[]) queryParams.get(name); for (int i = 0; i < values.length; i++) { // Iterating over values buf.append(name); buf.append("="); buf.append(values[i]); if (i < values.length - 1) { buf.append("&"); } } if (iter.hasNext()) { buf.append("&"); } } } // Append local navigation (reference) if (local != null && local.length() > 0) { buf.append("#"); buf.append(local); } if (log.isDebugEnabled()) { log.debug("Generated URL: " + buf.toString()); } return buf.toString(); } /** * @return Returns the targeted. */ public boolean isTargeted() { return pathParams.containsKey(ACTION) || pathParams.containsKey(PID); //return targeted; } }