You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by ms...@apache.org on 2014/11/25 13:50:07 UTC

[02/19] portals-pluto git commit: First steps towards implementing Ajax Action on server

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/c86384d8/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/PortalURLParserImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/PortalURLParserImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/PortalURLParserImpl.java
index 6062081..342f34d 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/PortalURLParserImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/PortalURLParserImpl.java
@@ -1,555 +1,567 @@
-/*
- * 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.pluto.driver.url.impl;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.portlet.PortletMode;
-import javax.portlet.WindowState;
-import javax.servlet.http.HttpServletRequest;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.pluto.driver.url.PortalURL;
-import org.apache.pluto.driver.url.PortalURLParameter;
-import org.apache.pluto.driver.url.PortalURLParser;
-
-/**
- * @version 1.0
- * @since Sep 30, 2004
- */
-public class PortalURLParserImpl implements PortalURLParser {
-
-	/** Logger. */
-    private static final Logger LOG = LoggerFactory.getLogger(PortalURLParserImpl.class);
-
-    /** The singleton parser instance. */
-    private static final PortalURLParser PARSER = new PortalURLParserImpl();
-
-
-    // Constants used for Encoding/Decoding ------------------------------------
-
-    private static final String PREFIX = "__";
-    private static final String DELIM = "_";
-    private static final String PORTLET_ID = "pd";
-    private static final String ACTION = "ac";
-    private static final String RESOURCE = "rs";
-    private static final String RESOURCE_ID = "ri";
-    private static final String CACHE_LEVEL = "cl";
-    private static final String RENDER_PARAM = "rp";
-    private static final String PRIVATE_RENDER_PARAM = "pr";
-    private static final String PUBLIC_RENDER_PARAM = "sp";
-    private static final String WINDOW_STATE = "ws";
-    private static final String PORTLET_MODE = "pm";
-    private static final String VALUE_DELIM = "0x0";
-
-    //This is a list of characters that need to be encoded  to be protected
-    //The ? is necessary to protect URI's with a query portion that is being passed as a parameter
-    private static final String[][] ENCODINGS = new String[][] {
-    		new String[] { "_",  "0x1" },
-            new String[] { ".",  "0x2" },
-            new String[] { "/",  "0x3" },
-            new String[] { "\r", "0x4" },
-            new String[] { "\n", "0x5" },
-            new String[] { "<",  "0x6" },
-            new String[] { ">",  "0x7" },
-            new String[] { " ",  "0x8" },
-            new String[] { "#",  "0x9" },
-            new String[] { "?",  "0xa" },
-            new String[] { "\\", "0xb" },
-            new String[] { "%",  "0xc" },
-    };
-
-    // Constructor -------------------------------------------------------------
-
-    /**
-     * Private constructor that prevents external instantiation.
-     */
-    private PortalURLParserImpl() {
-    	// Do nothing.
-    }
-
-    /**
-     * Returns the singleton parser instance.
-     * @return the singleton parser instance.
-     */
-    public static PortalURLParser getParser() {
-    	return PARSER;
-    }
-
-
-    // Public Methods ----------------------------------------------------------
-
-    /**
-     * Parse a servlet request to a portal URL.
-     * @param request  the servlet request to parse.
-     * @return the portal URL.
-     */
-    public PortalURL parse(HttpServletRequest request) {
-
-    	if (LOG.isDebugEnabled()) {
-            LOG.debug("Parsing URL: " + request.getRequestURI());
-        }
-
-        String contextPath = request.getContextPath();
-        String servletName = request.getServletPath();
-
-        String urlBase = request.getScheme()+"://" + request.getServerName() + ":" + request.getServerPort();
-        // Construct portal URL using info retrieved from servlet request.
-        PortalURL portalURL =  new RelativePortalURLImpl(urlBase, contextPath, servletName, this);
-
-        // Support added for filter.  Should we seperate into a different impl?
-        String pathInfo = request.getPathInfo();
-        if (pathInfo == null) {
-            if(servletName.contains(".jsp") && !servletName.endsWith(".jsp")) {
-                int idx = servletName.indexOf(".jsp")+".jsp".length();
-                pathInfo = servletName.substring(idx);
-                servletName = servletName.substring(0, idx);
-                portalURL = new RelativePortalURLImpl(urlBase, contextPath, servletName, this);
-            } else {
-                return portalURL;
-            }
-        }
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Parsing request pathInfo: " + pathInfo);
-        }
-
-        StringBuffer renderPath = new StringBuffer();
-        StringTokenizer st = new StringTokenizer(pathInfo, "/", false);
-        while (st.hasMoreTokens()) {
-
-        	String token = st.nextToken();
-
-        	// Part of the render path: append to renderPath.
-        	if (!token.startsWith(PREFIX)) {
-//        		renderPath.append(token);
-        		//Fix for PLUTO-243
-        		renderPath.append('/').append(token);
-        	}
-//        	 Resource window definition: portalURL.setResourceWindow().
-           else if (token.startsWith(PREFIX + RESOURCE)) {
-               portalURL.setResourceWindow(decodeControlParameter(token)[0]);
-           }
-        	// Action window definition: portalURL.setActionWindow().
-        	else if (token.startsWith(PREFIX + ACTION)) {
-        		portalURL.setActionWindow(decodeControlParameter(token)[0]);
-        	}
-            // Cacheability definition: portalURL.setCacheability().
-            else if (token.startsWith(PREFIX + CACHE_LEVEL)) {
-                portalURL.setCacheability(decodeControlParameter(token)[0]);
-            }
-            // ResourceID definition: portalURL.setResourceID().
-            else if (token.startsWith(PREFIX + RESOURCE_ID)) {
-                portalURL.setResourceID(decodeControlParameter(token)[0]);
-            }
-        	// Window state definition: portalURL.setWindowState().
-        	else if (token.startsWith(PREFIX + WINDOW_STATE)) {
-        		String[] decoded = decodeControlParameter(token);
-        		portalURL.setWindowState(decoded[0], new WindowState(decoded[1]));
-        	}
-        	// Portlet mode definition: portalURL.setPortletMode().
-        	else if (token.startsWith(PREFIX + PORTLET_MODE)) {
-        		String[] decoded = decodeControlParameter(token);
-        		portalURL.setPortletMode(decoded[0], new PortletMode(decoded[1]));
-        	}
-        	// Portal URL parameter: portalURL.addParameter().
-        	else if(token.startsWith(PREFIX + RENDER_PARAM)) {
-        		String value = null;
-        		if (st.hasMoreTokens()) {
-        			value = st.nextToken();
-        		}
-        		//set the
-        		PortalURLParameter param = decodeParameter(token, value);
-        		portalURL.addParameter(param);
-
-
-        	}
-            else if (token.startsWith(PREFIX + PRIVATE_RENDER_PARAM)){
-                String value = null;
-                if (st.hasMoreTokens()) {
-                    value = st.nextToken();
-                }
-                PortalURLParameter param = decodePublicParameter(token, value);
-                if( param != null )
-                {
-                    //set private (Resource) parameter in portalURL
-                    portalURL.getPrivateRenderParameters().put(param.getName(), param.getValues());
-                }
-            }
-        	else if (token.startsWith(PREFIX + PUBLIC_RENDER_PARAM)){
-        		String value = null;
-        		if (st.hasMoreTokens()) {
-        			value = st.nextToken();
-        		}
-        		PortalURLParameter param = decodePublicParameter(token, value);
-        		if( param != null )
-        		{
-        			//set public parameter in portalURL
-    	    		portalURL.addPublicParameterCurrent(param.getName(), param.getValues());
-        		}
-        	}
-        }
-        if (renderPath.length() > 0) {
-            portalURL.setRenderPath(renderPath.toString());
-        }
-
-        // Return the portal URL.
-        return portalURL;
-    }
-
-
-    /**
-     * Converts a portal URL to a URL string.
-     * @param portalURL  the portal URL to convert.
-     * @return a URL string representing the portal URL.
-     */
-    public String toString(PortalURL portalURL) {
-
-    	StringBuffer buffer = new StringBuffer();
-
-        // Append the server URI and the servlet path.
-    	buffer.append(portalURL.getServletPath().startsWith("/")?"":"/")
-            .append(portalURL.getServletPath());
-
-        // Start the pathInfo with the path to the render URL (page).
-        if (portalURL.getRenderPath() != null) {
-        	buffer.append(portalURL.getRenderPath());
-        }
-        //Append the resource window definition, if it exists.
-        if (portalURL.getResourceWindow() != null){
-               buffer.append("/");
-               buffer.append(PREFIX).append(RESOURCE)
-                               .append(encodeCharacters(portalURL.getResourceWindow()));
-        }
-        // Append the action window definition, if it exists.
-        if (portalURL.getActionWindow() != null) {
-        	buffer.append("/");
-        	buffer.append(PREFIX).append(ACTION)
-        			.append(encodeCharacters(portalURL.getActionWindow()));
-        }
-        
-        if (portalURL.getResourceWindow() != null)
-        {
-            if (portalURL.getCacheability() != null)
-            {
-                buffer.append("/");
-                buffer.append(PREFIX).append(CACHE_LEVEL).append(encodeCharacters(portalURL.getCacheability()));
-            }
-            if (portalURL.getResourceID() != null)
-            {
-                buffer.append("/");
-                buffer.append(PREFIX).append(RESOURCE_ID).append(encodeCharacters(portalURL.getResourceID()));
-            }
-        }
-
-        // Append portlet mode definitions.
-        for (Iterator it = portalURL.getPortletModes().entrySet().iterator();
-        		it.hasNext(); ) {
-            Map.Entry entry = (Map.Entry) it.next();
-            buffer.append("/").append(
-            		encodeControlParameter(PORTLET_MODE, entry.getKey().toString(),
-                       entry.getValue().toString()));
-        }
-
-        // Append window state definitions.
-        for (Iterator it = portalURL.getWindowStates().entrySet().iterator();
-        		it.hasNext(); ) {
-            Map.Entry entry = (Map.Entry) it.next();
-            buffer.append("/").append(
-            		encodeControlParameter(WINDOW_STATE, entry.getKey().toString(),
-                       entry.getValue().toString()));
-        }
-
-        // Append action and render parameters.
-        StringBuffer query = new StringBuffer("?");
-        boolean firstParam = true;
-        for (Iterator it = portalURL.getParameters().iterator();
-        		it.hasNext(); ) {
-
-        	PortalURLParameter param = (PortalURLParameter) it.next();
-
-            // Encode action params in the query appended at the end of the URL.
-            if (portalURL.getActionWindow() != null
-            		&& portalURL.getActionWindow().equals(param.getWindowId())
-            		|| (portalURL.getResourceWindow() != null
-            				&& portalURL.getResourceWindow().equals(param.getWindowId()))) {
-            	for (int i = 0; i < param.getValues().length; i++) {
-                    // FIX for PLUTO-247
-                    if ( firstParam ) {
-                        firstParam = false;
-                    } else {
-                        query.append("&");
-                    }
-                    query.append(encodeQueryParam(param.getName())).append("=")
-                    		.append(encodeQueryParam(param.getValues()[i]));
-                }
-            }
-
-            // Encode render params as a part of the URL.
-            else if (param.getValues() != null
-            		&& param.getValues().length > 0) {
-                String valueString = encodeMultiValues(param.getValues());
-                if (valueString.length() > 0) {
-                	buffer.append("/").append(
-                			encodeControlParameter(RENDER_PARAM, param.getWindowId(),
-                               param.getName()));
-                	buffer.append("/").append(valueString);
-                }
-            }
-        }
-
-        encode(buffer);
-
-        if (portalURL.getResourceWindow() != null)
-        {
-            Map<String, String[]> privateParamList = portalURL.getPrivateRenderParameters();
-            if (privateParamList!=null){
-                for (Iterator iter = privateParamList.keySet().iterator();iter.hasNext();){
-                    String paramname = (String)iter.next();
-                    String[] tmp = privateParamList.get(paramname);
-                    String valueString = encodeMultiValues(tmp);
-                    if (valueString.length()>0){
-                        buffer.append("/").append(encodePublicParamname(PRIVATE_RENDER_PARAM, paramname));
-                        buffer.append("/").append(valueString);
-                    }
-                }
-            }
-        }
-        
-        Map<String, String[]> publicParamList = portalURL.getPublicParameters();
-        if (publicParamList!=null){
-	        for (Iterator iter = publicParamList.keySet().iterator();iter.hasNext();){
-	        	String paramname = (String)iter.next();
-	        	String[] tmp = publicParamList.get(paramname);
-	        	String valueString = encodeMultiValues(tmp);
-	        	if (valueString.length()>0){
-	        		buffer.append("/").append(encodePublicParamname(PUBLIC_RENDER_PARAM, paramname));
-	        		buffer.append("/").append(valueString);
-	        	}
-	        }
-        }
-
-        // Construct the string representing the portal URL.
-        // Fix for PLUTO-247 - check if query string contains parameters
-        if ( query.length() > 1 ) {
-            return buffer.append(query).toString();
-        }
-
-        // Construct the string representing the portal URL.
-        return buffer.toString();
-    }
-
-    public static void encode(StringBuffer url){
-        replaceChar(url,"|","%7C");
-        replaceChar(url,"\"","%22");
-    }
-    private static void replaceChar(StringBuffer url, String character, String change){
-        boolean contains = url.toString().contains(character);
-        while (contains){
-            int index = url.indexOf(character);
-            url.deleteCharAt(index);
-            url.insert(index, change, 0, 3);
-            contains = url.toString().contains(character);
-        }
-    }
-
-    private String encodeQueryParam(String param) {
-        try {
-            return URLEncoder.encode(param, "UTF-8");
-        }
-        catch (UnsupportedEncodingException e) {
-            // If this happens, we've got bigger problems.
-            throw new RuntimeException(e);
-        }
-    }
-
-    // Private Encoding/Decoding Methods ---------------------------------------
-
-    /**
-     * Encode a control parameter.
-     * @param type  the type of the control parameter, which may be:
-     *              portlet mode, window state, or render parameter.
-     * @param windowId  the portlet window ID.
-     * @param name  the name to encode.
-     */
-    private String encodeControlParameter(String type,
-                                          String windowId,
-                                          String name) {
-    	StringBuffer buffer = new StringBuffer();
-    	buffer.append(PREFIX).append(type)
-    			.append(encodeCharacters(windowId))
-    			.append(DELIM).append(name);
-    	return buffer.toString();
-    }
-
-    private String encodePublicParamname(String type, String name){
-    	StringBuffer buffer = new StringBuffer();
-    	buffer.append(PREFIX).append(type)
-    	.append(DELIM).append(name);
-    	return buffer.toString();
-    }
-
-    /**
-     * Encode a string array containing multiple values into a single string.
-     * This method is used to encode multiple render parameter values.
-     * @param values  the string array to encode.
-     * @return a single string containing all the values.
-     */
-    private String encodeMultiValues(String[] values) {
-    	StringBuffer buffer = new StringBuffer();
-        for (int i = 0; i < values.length; i++) {
-        	// Do not operate on the array reference
-        	String currentValue = values[i];
-        	try {
-        		if (currentValue != null)
-        			currentValue = URLEncoder.encode(values[i], "UTF-8");
-			} catch (UnsupportedEncodingException e) {
-				LOG.warn(e.getMessage(),e);
-			}
-        	buffer.append(currentValue != null ? currentValue : "");
-            if (i + 1 < values.length) {
-            	buffer.append(VALUE_DELIM);
-            }
-        }
-        return encodeCharacters(buffer.toString());
-    }
-
-    /**
-     * Encode special characters contained in the string value.
-     * @param string  the string value to encode.
-     * @return the encoded string.
-     */
-    private String encodeCharacters(String string) {
-        for (int i = 0; i < ENCODINGS.length; i++) {
-            string = string.replace(ENCODINGS[i][0], ENCODINGS[i][1]);
-        }
-        return string;
-    }
-
-
-    /**
-     * Decode a control parameter.
-     * @param control  the control parameter to decode.
-     * @return values  a pair of decoded values.
-     */
-    private String[] decodeControlParameter(String control) {
-        String[] valuePair = new String[2];
-        control = control.substring((PREFIX + PORTLET_ID).length());
-        int index = control.indexOf(DELIM);
-        if (index >= 0) {
-        	valuePair[0] = control.substring(0, index);
-        	valuePair[0] = decodeCharacters(valuePair[0]);
-        	if (index + 1 <= control.length()) {
-        		valuePair[1] = control.substring(index + 1);
-        		valuePair[1] = decodeCharacters(valuePair[1]);
-        	} else {
-        		valuePair[1] = "";
-        	}
-        } else {
-        	valuePair[0] = decodeCharacters(control);
-        }
-        return valuePair;
-    }
-
-    /**
-     * Decode a name-value pair into a portal URL parameter.
-     * @param name  the parameter name.
-     * @param value  the parameter value.
-     * @return the decoded portal URL parameter.
-     */
-    private PortalURLParameter decodeParameter(String name, String value) {
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Decoding parameter: name=" + name
-            		+ ", value=" + value);
-        }
-
-    	// Decode the name into window ID and parameter name.
-        String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
-        String windowId = noPrefix.substring(0, noPrefix.indexOf(DELIM));
-        String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
-
-        // Decode special characters in window ID and parameter value.
-        windowId = decodeCharacters(windowId);
-        if (value != null) {
-        	value = decodeCharacters(value);
-        }
-
-        // Split multiple values into a value array.
-        String[] paramValues = value.split(VALUE_DELIM);
-        for (int i = 0; i < paramValues.length;i++){
-        	try {
-        		paramValues[i] = URLDecoder.decode(paramValues[i], "UTF-8");
-			} catch (UnsupportedEncodingException e) {
-				LOG.warn(e.getMessage(),e);
-			}
-        }
-        // Construct portal URL parameter and return.
-        return new PortalURLParameter(windowId, paramName, paramValues);
-    }
-
-    private PortalURLParameter decodePublicParameter(String name, String value) {
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Decoding parameter: name=" + name
-            		+ ", value=" + value);
-        }
-
-//    	// Decode the name into window ID and parameter name.
-        String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
-        String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
-
-        // Decode special characters in parameter value.
-
-        if (value != null) {
-        	value = decodeCharacters(value);
-        }
-
-        // Split multiple values into a value array.
-        String[] paramValues = value.split(VALUE_DELIM);
-        for (int i = 0; i < paramValues.length;i++){
-        	try {
-        		paramValues[i] = URLDecoder.decode(paramValues[i], "UTF-8");
-			} catch (UnsupportedEncodingException e) {
-				LOG.warn(e.getMessage(),e);
-			}
-        }
-
-        // Construct portal URL parameter and return.
-        return new PortalURLParameter(null, paramName, paramValues);
-    }
-
-    /**
-     * Decode special characters contained in the string value.
-     * @param string  the string value to decode.
-     * @return the decoded string.
-     */
-    private String decodeCharacters(String string) {
-        for (int i = 0; i < ENCODINGS.length; i++) {
-        	string = string.replace(ENCODINGS[i][1], ENCODINGS[i][0]);
-        }
-		return string;
-    }
-
-}
-
+/*
+ * 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.pluto.driver.url.impl;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.pluto.driver.url.PortalURL;
+import org.apache.pluto.driver.url.PortalURLParameter;
+import org.apache.pluto.driver.url.PortalURLParser;
+
+/**
+ * @version 1.0
+ * @since Sep 30, 2004
+ */
+public class PortalURLParserImpl implements PortalURLParser {
+
+	/** Logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(PortalURLParserImpl.class);
+
+    /** The singleton parser instance. */
+    private static final PortalURLParser PARSER = new PortalURLParserImpl();
+
+
+    // Constants used for Encoding/Decoding ------------------------------------
+
+    private static final String PREFIX = "__";
+    private static final String DELIM = "_";
+    private static final String PORTLET_ID = "pd";
+    private static final String ACTION = "ac";
+    private static final String RESOURCE = "rs";
+    private static final String RESOURCE_ID = "ri";
+    private static final String CACHE_LEVEL = "cl";
+    private static final String RENDER_PARAM = "rp";
+    private static final String PRIVATE_RENDER_PARAM = "pr";
+    private static final String PUBLIC_RENDER_PARAM = "sp";
+    private static final String WINDOW_STATE = "ws";
+    private static final String PORTLET_MODE = "pm";
+    private static final String VALUE_DELIM = "0x0";
+    
+    private static final String AJAX_ACTION = "aa";      // new for portlet spec 3
+    private static final String PARTIAL_ACTION = "pa";   // new for portlet spec 3
+
+
+    //This is a list of characters that need to be encoded  to be protected
+    //The ? is necessary to protect URI's with a query portion that is being passed as a parameter
+    private static final String[][] ENCODINGS = new String[][] {
+    		new String[] { "_",  "0x1" },
+            new String[] { ".",  "0x2" },
+            new String[] { "/",  "0x3" },
+            new String[] { "\r", "0x4" },
+            new String[] { "\n", "0x5" },
+            new String[] { "<",  "0x6" },
+            new String[] { ">",  "0x7" },
+            new String[] { " ",  "0x8" },
+            new String[] { "#",  "0x9" },
+            new String[] { "?",  "0xa" },
+            new String[] { "\\", "0xb" },
+            new String[] { "%",  "0xc" },
+    };
+
+    // Constructor -------------------------------------------------------------
+
+    /**
+     * Private constructor that prevents external instantiation.
+     */
+    private PortalURLParserImpl() {
+    	// Do nothing.
+    }
+
+    /**
+     * Returns the singleton parser instance.
+     * @return the singleton parser instance.
+     */
+    public static PortalURLParser getParser() {
+    	return PARSER;
+    }
+
+
+    // Public Methods ----------------------------------------------------------
+
+    /**
+     * Parse a servlet request to a portal URL.
+     * @param request  the servlet request to parse.
+     * @return the portal URL.
+     */
+    public PortalURL parse(HttpServletRequest request) {
+
+    	if (LOG.isDebugEnabled()) {
+            LOG.debug("Parsing URL: " + request.getRequestURI());
+        }
+
+        String contextPath = request.getContextPath();
+        String servletName = request.getServletPath();
+
+        String urlBase = request.getScheme()+"://" + request.getServerName() + ":" + request.getServerPort();
+        // Construct portal URL using info retrieved from servlet request.
+        PortalURL portalURL =  new RelativePortalURLImpl(urlBase, contextPath, servletName, this);
+
+        // Support added for filter.  Should we seperate into a different impl?
+        String pathInfo = request.getPathInfo();
+        if (pathInfo == null) {
+            if(servletName.contains(".jsp") && !servletName.endsWith(".jsp")) {
+                int idx = servletName.indexOf(".jsp")+".jsp".length();
+                pathInfo = servletName.substring(idx);
+                servletName = servletName.substring(0, idx);
+                portalURL = new RelativePortalURLImpl(urlBase, contextPath, servletName, this);
+            } else {
+                return portalURL;
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Parsing request pathInfo: " + pathInfo);
+        }
+
+        StringBuffer renderPath = new StringBuffer();
+        StringTokenizer st = new StringTokenizer(pathInfo, "/", false);
+        while (st.hasMoreTokens()) {
+
+           String token = st.nextToken();
+
+           // Part of the render path: append to renderPath.
+           if (!token.startsWith(PREFIX)) {
+              //        		renderPath.append(token);
+              //Fix for PLUTO-243
+              renderPath.append('/').append(token);
+           }
+           //        	 Resource window definition: portalURL.setResourceWindow().
+           else if (token.startsWith(PREFIX + RESOURCE)) {
+              portalURL.setResourceWindow(decodeControlParameter(token)[0]);
+           }
+           // Action window definition: portalURL.setActionWindow().
+           else if (token.startsWith(PREFIX + ACTION)) {
+              portalURL.setActionWindow(decodeControlParameter(token)[0]);
+           }
+           // Action window definition: portalURL.setActionWindow().
+           else if (token.startsWith(PREFIX + AJAX_ACTION)) {
+              portalURL.setAjaxActionWindow(decodeControlParameter(token)[0]);
+           }
+           // Action window definition: portalURL.setActionWindow().
+           else if (token.startsWith(PREFIX + PARTIAL_ACTION)) {
+              portalURL.setPartialActionWindow(decodeControlParameter(token)[0]);
+           }
+           // Cacheability definition: portalURL.setCacheability().
+           else if (token.startsWith(PREFIX + CACHE_LEVEL)) {
+              portalURL.setCacheability(decodeControlParameter(token)[0]);
+           }
+           // ResourceID definition: portalURL.setResourceID().
+           else if (token.startsWith(PREFIX + RESOURCE_ID)) {
+              portalURL.setResourceID(decodeControlParameter(token)[0]);
+           }
+           // Window state definition: portalURL.setWindowState().
+           else if (token.startsWith(PREFIX + WINDOW_STATE)) {
+              String[] decoded = decodeControlParameter(token);
+              portalURL.setWindowState(decoded[0], new WindowState(decoded[1]));
+           }
+           // Portlet mode definition: portalURL.setPortletMode().
+           else if (token.startsWith(PREFIX + PORTLET_MODE)) {
+              String[] decoded = decodeControlParameter(token);
+              portalURL.setPortletMode(decoded[0], new PortletMode(decoded[1]));
+           }
+           // Portal URL parameter: portalURL.addParameter().
+           else if(token.startsWith(PREFIX + RENDER_PARAM)) {
+              String value = null;
+              if (st.hasMoreTokens()) {
+                 value = st.nextToken();
+              }
+              //set the
+              PortalURLParameter param = decodeParameter(token, value);
+              portalURL.addParameter(param);
+
+
+           }
+           else if (token.startsWith(PREFIX + PRIVATE_RENDER_PARAM)){
+              String value = null;
+              if (st.hasMoreTokens()) {
+                 value = st.nextToken();
+              }
+              PortalURLParameter param = decodePublicParameter(token, value);
+              if( param != null )
+              {
+                 //set private (Resource) parameter in portalURL
+                 portalURL.getPrivateRenderParameters().put(param.getName(), param.getValues());
+              }
+           }
+           else if (token.startsWith(PREFIX + PUBLIC_RENDER_PARAM)){
+              String value = null;
+              if (st.hasMoreTokens()) {
+                 value = st.nextToken();
+              }
+              PortalURLParameter param = decodePublicParameter(token, value);
+              if( param != null )
+              {
+                 //set public parameter in portalURL
+                 portalURL.addPublicParameterCurrent(param.getName(), param.getValues());
+              }
+           }
+        }
+        if (renderPath.length() > 0) {
+           portalURL.setRenderPath(renderPath.toString());
+        }
+
+        // Return the portal URL.
+        return portalURL;
+    }
+
+
+    /**
+     * Converts a portal URL to a URL string.
+     * @param portalURL  the portal URL to convert.
+     * @return a URL string representing the portal URL.
+     */
+    public String toString(PortalURL portalURL) {
+
+    	StringBuffer buffer = new StringBuffer();
+
+        // Append the server URI and the servlet path.
+    	buffer.append(portalURL.getServletPath().startsWith("/")?"":"/")
+            .append(portalURL.getServletPath());
+
+        // Start the pathInfo with the path to the render URL (page).
+        if (portalURL.getRenderPath() != null) {
+        	buffer.append(portalURL.getRenderPath());
+        }
+        //Append the resource window definition, if it exists.
+        if (portalURL.getResourceWindow() != null){
+               buffer.append("/");
+               buffer.append(PREFIX).append(RESOURCE)
+                               .append(encodeCharacters(portalURL.getResourceWindow()));
+        }
+        // Append the action window definition, if it exists.
+        if (portalURL.getActionWindow() != null) {
+        	buffer.append("/");
+        	buffer.append(PREFIX).append(ACTION)
+        			.append(encodeCharacters(portalURL.getActionWindow()));
+        }
+        
+        if (portalURL.getResourceWindow() != null)
+        {
+            if (portalURL.getCacheability() != null)
+            {
+                buffer.append("/");
+                buffer.append(PREFIX).append(CACHE_LEVEL).append(encodeCharacters(portalURL.getCacheability()));
+            }
+            if (portalURL.getResourceID() != null)
+            {
+                buffer.append("/");
+                buffer.append(PREFIX).append(RESOURCE_ID).append(encodeCharacters(portalURL.getResourceID()));
+            }
+        }
+
+        // Append portlet mode definitions.
+        for (Iterator it = portalURL.getPortletModes().entrySet().iterator();
+        		it.hasNext(); ) {
+            Map.Entry entry = (Map.Entry) it.next();
+            buffer.append("/").append(
+            		encodeControlParameter(PORTLET_MODE, entry.getKey().toString(),
+                       entry.getValue().toString()));
+        }
+
+        // Append window state definitions.
+        for (Iterator it = portalURL.getWindowStates().entrySet().iterator();
+        		it.hasNext(); ) {
+            Map.Entry entry = (Map.Entry) it.next();
+            buffer.append("/").append(
+            		encodeControlParameter(WINDOW_STATE, entry.getKey().toString(),
+                       entry.getValue().toString()));
+        }
+
+        // Append action and render parameters.
+        StringBuffer query = new StringBuffer("?");
+        boolean firstParam = true;
+        for (Iterator it = portalURL.getParameters().iterator();
+        		it.hasNext(); ) {
+
+        	PortalURLParameter param = (PortalURLParameter) it.next();
+
+            // Encode action params in the query appended at the end of the URL.
+            if (portalURL.getActionWindow() != null
+            		&& portalURL.getActionWindow().equals(param.getWindowId())
+            		|| (portalURL.getResourceWindow() != null
+            				&& portalURL.getResourceWindow().equals(param.getWindowId()))) {
+            	for (int i = 0; i < param.getValues().length; i++) {
+                    // FIX for PLUTO-247
+                    if ( firstParam ) {
+                        firstParam = false;
+                    } else {
+                        query.append("&");
+                    }
+                    query.append(encodeQueryParam(param.getName())).append("=")
+                    		.append(encodeQueryParam(param.getValues()[i]));
+                }
+            }
+
+            // Encode render params as a part of the URL.
+            else if (param.getValues() != null
+            		&& param.getValues().length > 0) {
+                String valueString = encodeMultiValues(param.getValues());
+                if (valueString.length() > 0) {
+                	buffer.append("/").append(
+                			encodeControlParameter(RENDER_PARAM, param.getWindowId(),
+                               param.getName()));
+                	buffer.append("/").append(valueString);
+                }
+            }
+        }
+
+        encode(buffer);
+
+        if (portalURL.getResourceWindow() != null)
+        {
+            Map<String, String[]> privateParamList = portalURL.getPrivateRenderParameters();
+            if (privateParamList!=null){
+                for (Iterator iter = privateParamList.keySet().iterator();iter.hasNext();){
+                    String paramname = (String)iter.next();
+                    String[] tmp = privateParamList.get(paramname);
+                    String valueString = encodeMultiValues(tmp);
+                    if (valueString.length()>0){
+                        buffer.append("/").append(encodePublicParamname(PRIVATE_RENDER_PARAM, paramname));
+                        buffer.append("/").append(valueString);
+                    }
+                }
+            }
+        }
+        
+        Map<String, String[]> publicParamList = portalURL.getPublicParameters();
+        if (publicParamList!=null){
+	        for (Iterator iter = publicParamList.keySet().iterator();iter.hasNext();){
+	        	String paramname = (String)iter.next();
+	        	String[] tmp = publicParamList.get(paramname);
+	        	String valueString = encodeMultiValues(tmp);
+	        	if (valueString.length()>0){
+	        		buffer.append("/").append(encodePublicParamname(PUBLIC_RENDER_PARAM, paramname));
+	        		buffer.append("/").append(valueString);
+	        	}
+	        }
+        }
+
+        // Construct the string representing the portal URL.
+        // Fix for PLUTO-247 - check if query string contains parameters
+        if ( query.length() > 1 ) {
+            return buffer.append(query).toString();
+        }
+
+        // Construct the string representing the portal URL.
+        return buffer.toString();
+    }
+
+    public static void encode(StringBuffer url){
+        replaceChar(url,"|","%7C");
+        replaceChar(url,"\"","%22");
+    }
+    private static void replaceChar(StringBuffer url, String character, String change){
+        boolean contains = url.toString().contains(character);
+        while (contains){
+            int index = url.indexOf(character);
+            url.deleteCharAt(index);
+            url.insert(index, change, 0, 3);
+            contains = url.toString().contains(character);
+        }
+    }
+
+    private String encodeQueryParam(String param) {
+        try {
+            return URLEncoder.encode(param, "UTF-8");
+        }
+        catch (UnsupportedEncodingException e) {
+            // If this happens, we've got bigger problems.
+            throw new RuntimeException(e);
+        }
+    }
+
+    // Private Encoding/Decoding Methods ---------------------------------------
+
+    /**
+     * Encode a control parameter.
+     * @param type  the type of the control parameter, which may be:
+     *              portlet mode, window state, or render parameter.
+     * @param windowId  the portlet window ID.
+     * @param name  the name to encode.
+     */
+    private String encodeControlParameter(String type,
+                                          String windowId,
+                                          String name) {
+    	StringBuffer buffer = new StringBuffer();
+    	buffer.append(PREFIX).append(type)
+    			.append(encodeCharacters(windowId))
+    			.append(DELIM).append(name);
+    	return buffer.toString();
+    }
+
+    private String encodePublicParamname(String type, String name){
+    	StringBuffer buffer = new StringBuffer();
+    	buffer.append(PREFIX).append(type)
+    	.append(DELIM).append(name);
+    	return buffer.toString();
+    }
+
+    /**
+     * Encode a string array containing multiple values into a single string.
+     * This method is used to encode multiple render parameter values.
+     * @param values  the string array to encode.
+     * @return a single string containing all the values.
+     */
+    private String encodeMultiValues(String[] values) {
+    	StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < values.length; i++) {
+        	// Do not operate on the array reference
+        	String currentValue = values[i];
+        	try {
+        		if (currentValue != null)
+        			currentValue = URLEncoder.encode(values[i], "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				LOG.warn(e.getMessage(),e);
+			}
+        	buffer.append(currentValue != null ? currentValue : "");
+            if (i + 1 < values.length) {
+            	buffer.append(VALUE_DELIM);
+            }
+        }
+        return encodeCharacters(buffer.toString());
+    }
+
+    /**
+     * Encode special characters contained in the string value.
+     * @param string  the string value to encode.
+     * @return the encoded string.
+     */
+    private String encodeCharacters(String string) {
+        for (int i = 0; i < ENCODINGS.length; i++) {
+            string = string.replace(ENCODINGS[i][0], ENCODINGS[i][1]);
+        }
+        return string;
+    }
+
+
+    /**
+     * Decode a control parameter.
+     * @param control  the control parameter to decode.
+     * @return values  a pair of decoded values.
+     */
+    private String[] decodeControlParameter(String control) {
+        String[] valuePair = new String[2];
+        control = control.substring((PREFIX + PORTLET_ID).length());
+        int index = control.indexOf(DELIM);
+        if (index >= 0) {
+        	valuePair[0] = control.substring(0, index);
+        	valuePair[0] = decodeCharacters(valuePair[0]);
+        	if (index + 1 <= control.length()) {
+        		valuePair[1] = control.substring(index + 1);
+        		valuePair[1] = decodeCharacters(valuePair[1]);
+        	} else {
+        		valuePair[1] = "";
+        	}
+        } else {
+        	valuePair[0] = decodeCharacters(control);
+        }
+        return valuePair;
+    }
+
+    /**
+     * Decode a name-value pair into a portal URL parameter.
+     * @param name  the parameter name.
+     * @param value  the parameter value.
+     * @return the decoded portal URL parameter.
+     */
+    private PortalURLParameter decodeParameter(String name, String value) {
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Decoding parameter: name=" + name
+            		+ ", value=" + value);
+        }
+
+    	// Decode the name into window ID and parameter name.
+        String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
+        String windowId = noPrefix.substring(0, noPrefix.indexOf(DELIM));
+        String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
+
+        // Decode special characters in window ID and parameter value.
+        windowId = decodeCharacters(windowId);
+        if (value != null) {
+        	value = decodeCharacters(value);
+        }
+
+        // Split multiple values into a value array.
+        String[] paramValues = value.split(VALUE_DELIM);
+        for (int i = 0; i < paramValues.length;i++){
+        	try {
+        		paramValues[i] = URLDecoder.decode(paramValues[i], "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				LOG.warn(e.getMessage(),e);
+			}
+        }
+        // Construct portal URL parameter and return.
+        return new PortalURLParameter(windowId, paramName, paramValues);
+    }
+
+    private PortalURLParameter decodePublicParameter(String name, String value) {
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Decoding parameter: name=" + name
+            		+ ", value=" + value);
+        }
+
+//    	// Decode the name into window ID and parameter name.
+        String noPrefix = name.substring((PREFIX + PORTLET_ID).length());
+        String paramName = noPrefix.substring(noPrefix.indexOf(DELIM) + 1);
+
+        // Decode special characters in parameter value.
+
+        if (value != null) {
+        	value = decodeCharacters(value);
+        }
+
+        // Split multiple values into a value array.
+        String[] paramValues = value.split(VALUE_DELIM);
+        for (int i = 0; i < paramValues.length;i++){
+        	try {
+        		paramValues[i] = URLDecoder.decode(paramValues[i], "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				LOG.warn(e.getMessage(),e);
+			}
+        }
+
+        // Construct portal URL parameter and return.
+        return new PortalURLParameter(null, paramName, paramValues);
+    }
+
+    /**
+     * Decode special characters contained in the string value.
+     * @param string  the string value to decode.
+     * @return the decoded string.
+     */
+    private String decodeCharacters(String string) {
+        for (int i = 0; i < ENCODINGS.length; i++) {
+        	string = string.replace(ENCODINGS[i][1], ENCODINGS[i][0]);
+        }
+		return string;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/c86384d8/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/RelativePortalURLImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/RelativePortalURLImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/RelativePortalURLImpl.java
index c13f594..aa6a879 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/RelativePortalURLImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/url/impl/RelativePortalURLImpl.java
@@ -1,376 +1,394 @@
-/*
- * 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.pluto.driver.url.impl;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.portlet.PortletMode;
-import javax.portlet.WindowState;
-import javax.servlet.ServletContext;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.pluto.driver.AttributeKeys;
-import org.apache.pluto.driver.config.DriverConfiguration;
-import org.apache.pluto.driver.services.portal.PageConfig;
-import org.apache.pluto.driver.url.PortalURL;
-import org.apache.pluto.driver.url.PortalURLParameter;
-import org.apache.pluto.driver.url.PortalURLParser;
-
-/**
- * The portal URL.
- * @since 1.0
- */
-public class RelativePortalURLImpl implements PortalURL {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RelativePortalURLImpl.class);
-
-    private String urlBase;
-    private String servletPath;
-    private String renderPath;
-    private String actionWindow;
-    private String resourceWindow;
-    private String cacheLevel;
-    private String resourceID;
-
-    private Map<String, String[]> publicParameterCurrent = new HashMap<String, String[]>();
-
-    private Map<String, String[]> publicParameterNew = new HashMap<String, String[]>();
-    private Map<String, String[]> privateRenderParameters = new HashMap<String, String[]>();
-    
-    /**
-     * PortalURLParser used to construct the string
-     * representation of this portal url.
-     */
-    private PortalURLParser urlParser;
-
-    /** The window states: key is the window ID, value is WindowState. */
-    private Map<String, WindowState> windowStates = new HashMap<String, WindowState>();
-
-    private Map<String, PortletMode> portletModes = new HashMap<String, PortletMode>();
-
-    /** Parameters of the portlet windows. */
-    private Map<String, PortalURLParameter> parameters = new HashMap<String, PortalURLParameter>();
-
-    /**
-     * Constructs a PortalURLImpl instance using customized port.
-     * @param urlBase      the absolute (protocol://domain:port) request url base
-     * @param contextPath  the servlet context path.
-     * @param servletName  the servlet name.
-     * @param urlParser    the {@link PortalURLParser} used to construct a string representation of the url.
-     */
-    public RelativePortalURLImpl(String urlBase, String contextPath, String servletName, PortalURLParser urlParser) {
-        this.urlBase = urlBase;
-    	StringBuffer buffer = new StringBuffer();
-    	buffer.append(contextPath);
-    	buffer.append(servletName);
-        servletPath = buffer.toString();
-        this.urlParser = urlParser;
-    }
-
-    /**
-     * Internal private constructor used by method <code>clone()</code>.
-     * @see #clone()
-     */
-    private RelativePortalURLImpl() {
-    	// Do nothing.
-    }
-
-    // Public Methods ----------------------------------------------------------
-
-    public void setRenderPath(String renderPath) {
-        this.renderPath = renderPath;
-    }
-
-    public String getRenderPath() {
-        return renderPath;
-    }
-
-    public void addParameter(PortalURLParameter param) {
-        parameters.put(param.getWindowId() + param.getName(), param);
-    }
-
-    public Collection<PortalURLParameter> getParameters() {
-        return parameters.values();
-    }
-
-    public void setActionWindow(String actionWindow) {
-        this.actionWindow = actionWindow;
-    }
-
-    public String getActionWindow() {
-        return actionWindow;
-    }
-
-    public Map<String, PortletMode> getPortletModes() {
-        return Collections.unmodifiableMap(portletModes);
-    }
-
-    public PortletMode getPortletMode(String windowId) {
-        PortletMode mode = portletModes.get(windowId);
-        if (mode == null) {
-            mode = PortletMode.VIEW;
-        }
-        return mode;
-    }
-
-    public void setPortletMode(String windowId, PortletMode portletMode) {
-        portletModes.put(windowId, portletMode);
-    }
-
-    public Map<String, WindowState> getWindowStates() {
-        return Collections.unmodifiableMap(windowStates);
-    }
-
-    /**
-     * Returns the window state of the specified window.
-     * @param windowId  the window ID.
-     * @return the window state. Default to NORMAL.
-     */
-    public WindowState getWindowState(String windowId) {
-        WindowState state = windowStates.get(windowId);
-        if (state == null) {
-            state = WindowState.NORMAL;
-        }
-        return state;
-    }
-
-    /**
-     * Sets the window state of the specified window.
-     * @param windowId  the window ID.
-     * @param windowState  the window state.
-     */
-    public void setWindowState(String windowId, WindowState windowState) {
-        this.windowStates.put(windowId, windowState);
-    }
-
-    /**
-     * Clear parameters of the specified window.
-     * @param windowId  the window ID.
-     */
-    public void clearParameters(String windowId) {
-    	for (Iterator<Map.Entry<String, PortalURLParameter>> it = parameters.entrySet().iterator(); it.hasNext(); ) {
-            Map.Entry<String, PortalURLParameter> entry = it.next();
-            PortalURLParameter param = entry.getValue();
-            if (param.getWindowId()!=null){
-            	if (param.getWindowId().equals(windowId)) {
-                	it.remove();
-                }
-            }
-        }
-    }
-    
-    public void setCacheability(String cacheLevel)
-    {
-        this.cacheLevel = cacheLevel;
-    }
-    
-    public String getCacheability()
-    {
-        return cacheLevel;
-    }
-    
-    public void setResourceID(String resourceID)
-    {
-        this.resourceID = resourceID;
-    }
-    
-    public String getResourceID()
-    {
-        return resourceID;
-    }
-
-    /**
-     * Converts to a string representing the portal URL.
-     * @deprecated use toURL(boolean absolute) instead
-     * @return a string representing the portal URL.
-     * @see PortalURLParserImpl#toString(org.apache.pluto.driver.url.PortalURL)
-     */
-    public String toString() {
-        return toURL(false);
-    }
-    
-    /**
-     * Converts to a string representing the portal URL.
-     * @return a string representing the portal URL.
-     * @see PortalURLParserImpl#toString(org.apache.pluto.driver.url.PortalURL)
-     */
-    public String toURL(boolean absolute)
-    {
-        String result = urlParser.toString(this);
-        if (absolute)
-        {
-            return urlBase + result;
-        }
-        return result;
-    }
-
-    /**
-     * Returns the server URI (protocol, name, port).
-     * @return the server URI portion of the portal URL.
-     * @deprecated
-     */
-    @Deprecated
-    public String getServerURI() {
-        return null;
-    }
-
-    /**
-     * Returns the servlet path (context path + servlet name).
-     * @return the servlet path.
-     */
-    public String getServletPath() {
-        return servletPath;
-    }
-
-    /**
-     * Clone a copy of itself.
-     * @return a copy of itself.
-     */
-    public synchronized PortalURL clone() {
-    	RelativePortalURLImpl portalURL = new RelativePortalURLImpl();
-    	portalURL.servletPath = this.servletPath;
-    	portalURL.parameters = new HashMap<String, PortalURLParameter>(parameters);
-    	portalURL.privateRenderParameters = new HashMap<String, String[]>(privateRenderParameters);
-    	portalURL.portletModes = new HashMap<String, PortletMode>(portletModes);
-    	portalURL.windowStates = new HashMap<String, WindowState>(windowStates);
-    	portalURL.cacheLevel = cacheLevel;
-    	portalURL.resourceID = resourceID;
-    	portalURL.renderPath = renderPath;
-    	portalURL.actionWindow = actionWindow;
-        portalURL.urlParser = urlParser;
-    	portalURL.resourceWindow = resourceWindow;
-    	portalURL.publicParameterCurrent = publicParameterCurrent;
-        return portalURL;
-    }
-//JSR-286 methods
-
-    public void addPublicRenderParametersNew(Map<String, String[]> parameters){
-    	for (Iterator<String> iter=parameters.keySet().iterator(); iter.hasNext();) {
-			String key = iter.next();
-			if (publicParameterNew.containsKey(key)){
-				publicParameterNew.remove(key);
-			}
-			String[] values = parameters.get(key);
-            publicParameterNew.put(key, values);
-		}
-    }
-
-
-    public void addPublicParameterCurrent(String name, String[] values){
-    	publicParameterCurrent.put(name, values);
-    }
-
-    public void addPublicParameterActionResourceParameter(String parameterName, String value) {
-    	//add at the first position
-		if (publicParameterCurrent.containsKey(parameterName)){
-			String[] tmp = publicParameterCurrent.get(parameterName);
-
-			String[] values = new String[tmp.length + 1];
-			values[0] = value;
-			for (int i = 0; i < tmp.length; i++) {
-				values[i+1] = tmp[i];
-			}
-			publicParameterCurrent.remove(parameterName);
-			publicParameterCurrent.put(parameterName, values.clone());
-		}
-		else
-			publicParameterCurrent.put(parameterName, new String[]{value});
-	}
-
-    public Map<String, String[]> getPublicParameters() {
-    	Map<String,String[]> tmp = new HashMap<String, String[]>();
-
-		for (Iterator<String> iter = publicParameterCurrent.keySet().iterator(); iter.hasNext();) {
-           String paramname = iter.next();
-           if (!publicParameterNew.containsKey(paramname)){
-               String[] paramvalue = publicParameterCurrent.get(paramname);
-               tmp.put(paramname, paramvalue);
-           }
-        }
-		for (Iterator<String> iter = publicParameterNew.keySet().iterator();iter.hasNext();){
-			String paramname = iter.next();
-			String[] paramvalue = publicParameterNew.get(paramname);
-			if (paramvalue[0]!=null){
-				tmp.put(paramname, paramvalue);
-			}
-		}
-		return tmp;
-    }
-    
-    public Map<String, String[]> getNewPublicParameters()
-    {
-        return publicParameterNew;
-    }
-    
-    public Map<String, String[]> getPrivateRenderParameters()
-    {
-        return privateRenderParameters;
-    }
-
-
-	public PageConfig getPageConfig(ServletContext servletContext) {
-		String requestedPageId = getRenderPath();
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Requested Page: " + requestedPageId);
-        }
-        return ((DriverConfiguration) servletContext.getAttribute(
-        		AttributeKeys.DRIVER_CONFIG)).getPageConfig(requestedPageId);
-	}
-
-    public String getResourceWindow() {
-		return resourceWindow;
-	}
-
-	public void setResourceWindow(String resourceWindow) {
-		this.resourceWindow = resourceWindow;
-	}
-
-	public synchronized void merge(PortalURL url, String windowId)
-	{
-        actionWindow = url.getActionWindow();
-        resourceWindow = url.getResourceWindow();
-        setPortletMode(windowId, url.getPortletMode(windowId));
-        setWindowState(windowId, url.getWindowState(windowId));
-        setCacheability(url.getCacheability());
-        setResourceID(url.getResourceID());
-        clearParameters(windowId);
-        for (PortalURLParameter param : url.getParameters())
-        {
-            if (windowId.equals(param.getWindowId()))
-            {
-                addParameter(new PortalURLParameter(param.getWindowId(), param.getName(), param.getValues()));
-            }
-        }
-        Map<String, String[]> newPublicParameters = url.getNewPublicParameters();
-        for (Map.Entry<String, String[]> entry : newPublicParameters.entrySet())
-        {
-            if (entry.getValue()[0] == null)
-            {
-                publicParameterCurrent.remove(entry.getKey());
-            }
-            else
-            {
-                publicParameterCurrent.put(entry.getKey(), entry.getValue());
-            }
-        }
-	}
-}
+/*
+ * 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.pluto.driver.url.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+import javax.servlet.ServletContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.pluto.driver.AttributeKeys;
+import org.apache.pluto.driver.config.DriverConfiguration;
+import org.apache.pluto.driver.services.portal.PageConfig;
+import org.apache.pluto.driver.url.PortalURL;
+import org.apache.pluto.driver.url.PortalURLParameter;
+import org.apache.pluto.driver.url.PortalURLParser;
+
+/**
+ * The portal URL.
+ * @since 1.0
+ */
+public class RelativePortalURLImpl implements PortalURL {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RelativePortalURLImpl.class);
+
+    private String urlBase;
+    private String servletPath;
+    private String renderPath;
+    private String actionWindow;
+    private String ajaxActionWindow;
+    private String partialActionWindow;
+    private String resourceWindow;
+    private String cacheLevel;
+    private String resourceID;
+
+    private Map<String, String[]> publicParameterCurrent = new HashMap<String, String[]>();
+
+    private Map<String, String[]> publicParameterNew = new HashMap<String, String[]>();
+    private Map<String, String[]> privateRenderParameters = new HashMap<String, String[]>();
+    
+    /**
+     * PortalURLParser used to construct the string
+     * representation of this portal url.
+     */
+    private PortalURLParser urlParser;
+
+    /** The window states: key is the window ID, value is WindowState. */
+    private Map<String, WindowState> windowStates = new HashMap<String, WindowState>();
+
+    private Map<String, PortletMode> portletModes = new HashMap<String, PortletMode>();
+
+    /** Parameters of the portlet windows. */
+    private Map<String, PortalURLParameter> parameters = new HashMap<String, PortalURLParameter>();
+
+    /**
+     * Constructs a PortalURLImpl instance using customized port.
+     * @param urlBase      the absolute (protocol://domain:port) request url base
+     * @param contextPath  the servlet context path.
+     * @param servletName  the servlet name.
+     * @param urlParser    the {@link PortalURLParser} used to construct a string representation of the url.
+     */
+    public RelativePortalURLImpl(String urlBase, String contextPath, String servletName, PortalURLParser urlParser) {
+        this.urlBase = urlBase;
+    	StringBuffer buffer = new StringBuffer();
+    	buffer.append(contextPath);
+    	buffer.append(servletName);
+        servletPath = buffer.toString();
+        this.urlParser = urlParser;
+    }
+
+    /**
+     * Internal private constructor used by method <code>clone()</code>.
+     * @see #clone()
+     */
+    private RelativePortalURLImpl() {
+    	// Do nothing.
+    }
+
+    // Public Methods ----------------------------------------------------------
+
+    public void setRenderPath(String renderPath) {
+        this.renderPath = renderPath;
+    }
+
+    public String getRenderPath() {
+        return renderPath;
+    }
+
+    public void addParameter(PortalURLParameter param) {
+        parameters.put(param.getWindowId() + param.getName(), param);
+    }
+
+    public Collection<PortalURLParameter> getParameters() {
+        return parameters.values();
+    }
+
+    public void setActionWindow(String actionWindow) {
+        this.actionWindow = actionWindow;
+    }
+
+    public String getActionWindow() {
+        return actionWindow;
+    }
+
+    public void setAjaxActionWindow(String window) {
+        this.ajaxActionWindow = window;
+    }
+
+    public String getAjaxActionWindow() {
+        return ajaxActionWindow;
+    }
+
+    public void setPartialActionWindow(String window) {
+        this.partialActionWindow = window;
+    }
+
+    public String getPartialActionWindow() {
+        return partialActionWindow;
+    }
+
+    public Map<String, PortletMode> getPortletModes() {
+        return Collections.unmodifiableMap(portletModes);
+    }
+
+    public PortletMode getPortletMode(String windowId) {
+        PortletMode mode = portletModes.get(windowId);
+        if (mode == null) {
+            mode = PortletMode.VIEW;
+        }
+        return mode;
+    }
+
+    public void setPortletMode(String windowId, PortletMode portletMode) {
+        portletModes.put(windowId, portletMode);
+    }
+
+    public Map<String, WindowState> getWindowStates() {
+        return Collections.unmodifiableMap(windowStates);
+    }
+
+    /**
+     * Returns the window state of the specified window.
+     * @param windowId  the window ID.
+     * @return the window state. Default to NORMAL.
+     */
+    public WindowState getWindowState(String windowId) {
+        WindowState state = windowStates.get(windowId);
+        if (state == null) {
+            state = WindowState.NORMAL;
+        }
+        return state;
+    }
+
+    /**
+     * Sets the window state of the specified window.
+     * @param windowId  the window ID.
+     * @param windowState  the window state.
+     */
+    public void setWindowState(String windowId, WindowState windowState) {
+        this.windowStates.put(windowId, windowState);
+    }
+
+    /**
+     * Clear parameters of the specified window.
+     * @param windowId  the window ID.
+     */
+    public void clearParameters(String windowId) {
+    	for (Iterator<Map.Entry<String, PortalURLParameter>> it = parameters.entrySet().iterator(); it.hasNext(); ) {
+            Map.Entry<String, PortalURLParameter> entry = it.next();
+            PortalURLParameter param = entry.getValue();
+            if (param.getWindowId()!=null){
+            	if (param.getWindowId().equals(windowId)) {
+                	it.remove();
+                }
+            }
+        }
+    }
+    
+    public void setCacheability(String cacheLevel)
+    {
+        this.cacheLevel = cacheLevel;
+    }
+    
+    public String getCacheability()
+    {
+        return cacheLevel;
+    }
+    
+    public void setResourceID(String resourceID)
+    {
+        this.resourceID = resourceID;
+    }
+    
+    public String getResourceID()
+    {
+        return resourceID;
+    }
+
+    /**
+     * Converts to a string representing the portal URL.
+     * @deprecated use toURL(boolean absolute) instead
+     * @return a string representing the portal URL.
+     * @see PortalURLParserImpl#toString(org.apache.pluto.driver.url.PortalURL)
+     */
+    public String toString() {
+        return toURL(false);
+    }
+    
+    /**
+     * Converts to a string representing the portal URL.
+     * @return a string representing the portal URL.
+     * @see PortalURLParserImpl#toString(org.apache.pluto.driver.url.PortalURL)
+     */
+    public String toURL(boolean absolute)
+    {
+        String result = urlParser.toString(this);
+        if (absolute)
+        {
+            return urlBase + result;
+        }
+        return result;
+    }
+
+    /**
+     * Returns the server URI (protocol, name, port).
+     * @return the server URI portion of the portal URL.
+     * @deprecated
+     */
+    @Deprecated
+    public String getServerURI() {
+        return null;
+    }
+
+    /**
+     * Returns the servlet path (context path + servlet name).
+     * @return the servlet path.
+     */
+    public String getServletPath() {
+        return servletPath;
+    }
+
+    /**
+     * Clone a copy of itself.
+     * @return a copy of itself.
+     */
+    public synchronized PortalURL clone() {
+    	RelativePortalURLImpl portalURL = new RelativePortalURLImpl();
+    	portalURL.servletPath = this.servletPath;
+    	portalURL.parameters = new HashMap<String, PortalURLParameter>(parameters);
+    	portalURL.privateRenderParameters = new HashMap<String, String[]>(privateRenderParameters);
+    	portalURL.portletModes = new HashMap<String, PortletMode>(portletModes);
+    	portalURL.windowStates = new HashMap<String, WindowState>(windowStates);
+    	portalURL.cacheLevel = cacheLevel;
+    	portalURL.resourceID = resourceID;
+    	portalURL.renderPath = renderPath;
+    	portalURL.actionWindow = actionWindow;
+        portalURL.urlParser = urlParser;
+    	portalURL.resourceWindow = resourceWindow;
+    	portalURL.publicParameterCurrent = publicParameterCurrent;
+        return portalURL;
+    }
+//JSR-286 methods
+
+    public void addPublicRenderParametersNew(Map<String, String[]> parameters){
+    	for (Iterator<String> iter=parameters.keySet().iterator(); iter.hasNext();) {
+			String key = iter.next();
+			if (publicParameterNew.containsKey(key)){
+				publicParameterNew.remove(key);
+			}
+			String[] values = parameters.get(key);
+            publicParameterNew.put(key, values);
+		}
+    }
+
+
+    public void addPublicParameterCurrent(String name, String[] values){
+    	publicParameterCurrent.put(name, values);
+    }
+
+    public void addPublicParameterActionResourceParameter(String parameterName, String value) {
+    	//add at the first position
+		if (publicParameterCurrent.containsKey(parameterName)){
+			String[] tmp = publicParameterCurrent.get(parameterName);
+
+			String[] values = new String[tmp.length + 1];
+			values[0] = value;
+			for (int i = 0; i < tmp.length; i++) {
+				values[i+1] = tmp[i];
+			}
+			publicParameterCurrent.remove(parameterName);
+			publicParameterCurrent.put(parameterName, values.clone());
+		}
+		else
+			publicParameterCurrent.put(parameterName, new String[]{value});
+	}
+
+    public Map<String, String[]> getPublicParameters() {
+    	Map<String,String[]> tmp = new HashMap<String, String[]>();
+
+		for (Iterator<String> iter = publicParameterCurrent.keySet().iterator(); iter.hasNext();) {
+           String paramname = iter.next();
+           if (!publicParameterNew.containsKey(paramname)){
+               String[] paramvalue = publicParameterCurrent.get(paramname);
+               tmp.put(paramname, paramvalue);
+           }
+        }
+		for (Iterator<String> iter = publicParameterNew.keySet().iterator();iter.hasNext();){
+			String paramname = iter.next();
+			String[] paramvalue = publicParameterNew.get(paramname);
+			if (paramvalue[0]!=null){
+				tmp.put(paramname, paramvalue);
+			}
+		}
+		return tmp;
+    }
+    
+    public Map<String, String[]> getNewPublicParameters()
+    {
+        return publicParameterNew;
+    }
+    
+    public Map<String, String[]> getPrivateRenderParameters()
+    {
+        return privateRenderParameters;
+    }
+
+
+	public PageConfig getPageConfig(ServletContext servletContext) {
+		String requestedPageId = getRenderPath();
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Requested Page: " + requestedPageId);
+        }
+        return ((DriverConfiguration) servletContext.getAttribute(
+        		AttributeKeys.DRIVER_CONFIG)).getPageConfig(requestedPageId);
+	}
+
+    public String getResourceWindow() {
+		return resourceWindow;
+	}
+
+	public void setResourceWindow(String resourceWindow) {
+		this.resourceWindow = resourceWindow;
+	}
+
+	public synchronized void merge(PortalURL url, String windowId)
+	{
+        actionWindow = url.getActionWindow();
+        resourceWindow = url.getResourceWindow();
+        setPortletMode(windowId, url.getPortletMode(windowId));
+        setWindowState(windowId, url.getWindowState(windowId));
+        setCacheability(url.getCacheability());
+        setResourceID(url.getResourceID());
+        clearParameters(windowId);
+        for (PortalURLParameter param : url.getParameters())
+        {
+            if (windowId.equals(param.getWindowId()))
+            {
+                addParameter(new PortalURLParameter(param.getWindowId(), param.getName(), param.getValues()));
+            }
+        }
+        Map<String, String[]> newPublicParameters = url.getNewPublicParameters();
+        for (Map.Entry<String, String[]> entry : newPublicParameters.entrySet())
+        {
+            if (entry.getValue()[0] == null)
+            {
+                publicParameterCurrent.remove(entry.getKey());
+            }
+            else
+            {
+                publicParameterCurrent.put(entry.getKey(), entry.getValue());
+            }
+        }
+	}
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/c86384d8/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverFilter.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverFilter.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverFilter.java
index 0b8e234..510246a 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverFilter.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverFilter.java
@@ -1,190 +1,190 @@
-/*
- * 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.pluto.driver;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.pluto.container.PortletContainer;
-import org.apache.pluto.container.PortletContainerException;
-import org.apache.pluto.driver.core.PortalRequestContext;
-import org.apache.pluto.driver.core.PortletWindowImpl;
-import org.apache.pluto.driver.services.portal.PortletWindowConfig;
-import org.apache.pluto.driver.url.PortalURL;
-
-import javax.portlet.PortletException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * The controller filter used to drive static portlet pages (see
- * <a href="http://portals.apache.org/pluto/faq.html#simple-embed">
- * http://portals.apache.org/pluto/faq.html#simple-embed</a> in Pluto FAQ).
- *
- * @version 1.0
- * @since March 28, 2006
- */
-public class PortalDriverFilter implements Filter {
-
-    /**
-     * Internal Logger.
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(PortalDriverFilter.class);
-
-    /**
-     * The Portal Driver sServlet Context
-     */
-    private ServletContext servletContext;
-
-    /**
-     * The portlet container to which we
-     * will forward all portlet requests.
-     */
-    protected PortletContainer container;
-
-
-    public ServletContext getServletContext() {
-        return servletContext;
-    }
-
-    /**
-     * Initialize the Portal Driver.
-     * This method retrieves the portlet container instance
-     * from the servlet context scope.
-     *
-     * @see org.apache.pluto.container.PortletContainer
-     */
-    public void init(FilterConfig filterConfig) throws ServletException {
-        servletContext = filterConfig.getServletContext();
-        container = (PortletContainer) servletContext.getAttribute(
-            AttributeKeys.PORTLET_CONTAINER);
-    }
-
-
-    /**
-     * Release the container and the context.
-     */
-    public void destroy() {
-        container = null;
-        servletContext = null;
-    }
-
-    /**
-     * Intercept requests in order to perform any actions.
-     *
-     * @param request  the incoming ServletRequest.
-     * @param response the incoming ServletResponse.
-     * @throws javax.servlet.ServletException if an internal error occurs.
-     * @throws java.io.IOException            if an error occurs writing to the response.
-     */
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
-        throws IOException, ServletException {
-        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
-            HttpServletRequest req = (HttpServletRequest) request;
-            // Since we must support a 2.3 environment, we can't use
-            //  filter dispatchers.  B/C of this, we make sure we haven't
-            //  allready processed this request. No infinite loops for us!!!!
-            if (PortalRequestContext.getContext(req) == null) {
-                boolean actionRequestProcessed = 
-                	doPortletPrepare(req, (HttpServletResponse) response);
-
-                if (actionRequestProcessed) {
-                    return;
-                }
-
-            }
-
-            String path = req.getServletPath();
-            int idx = path.indexOf(".jsp");
-            if (!path.endsWith(".jsp") && idx > 0) {
-                String realPath = path.substring(0, idx + ".jsp".length());
-                if (realPath.startsWith(req.getContextPath())) {
-                    realPath = realPath.substring(req.getContextPath().length());
-                }
-                LOG.info("Forwarding to realPath: " + realPath);
-                request.getRequestDispatcher(realPath).forward(request, response);
-                return;
-            }
-        }
-        filterChain.doFilter(request, response);
-    }
-
-    /**
-     * Perform Portlet Preparation
-     *
-     * @param request
-     * @param response
-     * @throws java.io.IOException            if an io exception occurs
-     * @throws javax.servlet.ServletException if a servlet exception occurs
-     * @return A boolean flag indicating whether or not an action request was
-     * processed. A value of true indicates than an action request was 
-     * processed while a value of false indicates that an action request was
-     * NOT processed.
-     */
-    public boolean doPortletPrepare(HttpServletRequest request, HttpServletResponse response)
-        throws IOException, ServletException {
-
-    	boolean actionRequestProcessed = false;
-    	
-        PortalRequestContext portalRequestContext =
-            new PortalRequestContext(getServletContext(), request, response);
-
-        PortalURL portalURL = portalRequestContext.getRequestedPortalURL();
-        String actionWindowId = portalURL.getActionWindow();
-
-        PortletWindowConfig actionWindowConfig =
-            actionWindowId == null
-                ? null
-                : PortletWindowConfig.fromId(actionWindowId);
-
-        // Action window config will only exist if there is an action request.
-        if (actionWindowConfig != null) {
-            PortletWindowImpl portletWindow = new PortletWindowImpl(container,
-                actionWindowConfig, portalURL);
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Processing action request for window: "
-                    + portletWindow.getId().getStringId());
-            }
-            try {
-                container.doAction(portletWindow, request, response);
-            } catch (PortletContainerException ex) {
-                throw new ServletException(ex);
-            } catch (PortletException ex) {
-                throw new ServletException(ex);
-            }
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Action request processed.\n\n");
-            }
-            
-            actionRequestProcessed = true;
-        }
-        
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Render Path: " + portalURL.getRenderPath());
-            LOG.debug("Servlet Path: " + portalURL.getServletPath());        	
-        }
-
-        return actionRequestProcessed;
-    }
-}
+/*
+ * 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.pluto.driver;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.pluto.container.PortletContainer;
+import org.apache.pluto.container.PortletContainerException;
+import org.apache.pluto.driver.core.PortalRequestContext;
+import org.apache.pluto.driver.core.PortletWindowImpl;
+import org.apache.pluto.driver.services.portal.PortletWindowConfig;
+import org.apache.pluto.driver.url.PortalURL;
+
+import javax.portlet.PortletException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * The controller filter used to drive static portlet pages (see
+ * <a href="http://portals.apache.org/pluto/faq.html#simple-embed">
+ * http://portals.apache.org/pluto/faq.html#simple-embed</a> in Pluto FAQ).
+ *
+ * @version 1.0
+ * @since March 28, 2006
+ */
+public class PortalDriverFilter implements Filter {
+
+    /**
+     * Internal Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(PortalDriverFilter.class);
+
+    /**
+     * The Portal Driver sServlet Context
+     */
+    private ServletContext servletContext;
+
+    /**
+     * The portlet container to which we
+     * will forward all portlet requests.
+     */
+    protected PortletContainer container;
+
+
+    public ServletContext getServletContext() {
+        return servletContext;
+    }
+
+    /**
+     * Initialize the Portal Driver.
+     * This method retrieves the portlet container instance
+     * from the servlet context scope.
+     *
+     * @see org.apache.pluto.container.PortletContainer
+     */
+    public void init(FilterConfig filterConfig) throws ServletException {
+        servletContext = filterConfig.getServletContext();
+        container = (PortletContainer) servletContext.getAttribute(
+            AttributeKeys.PORTLET_CONTAINER);
+    }
+
+
+    /**
+     * Release the container and the context.
+     */
+    public void destroy() {
+        container = null;
+        servletContext = null;
+    }
+
+    /**
+     * Intercept requests in order to perform any actions.
+     *
+     * @param request  the incoming ServletRequest.
+     * @param response the incoming ServletResponse.
+     * @throws javax.servlet.ServletException if an internal error occurs.
+     * @throws java.io.IOException            if an error occurs writing to the response.
+     */
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
+        throws IOException, ServletException {
+        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
+            HttpServletRequest req = (HttpServletRequest) request;
+            // Since we must support a 2.3 environment, we can't use
+            //  filter dispatchers.  B/C of this, we make sure we haven't
+            //  allready processed this request. No infinite loops for us!!!!
+            if (PortalRequestContext.getContext(req) == null) {
+                boolean actionRequestProcessed = 
+                	doPortletPrepare(req, (HttpServletResponse) response);
+
+                if (actionRequestProcessed) {
+                    return;
+                }
+
+            }
+
+            String path = req.getServletPath();
+            int idx = path.indexOf(".jsp");
+            if (!path.endsWith(".jsp") && idx > 0) {
+                String realPath = path.substring(0, idx + ".jsp".length());
+                if (realPath.startsWith(req.getContextPath())) {
+                    realPath = realPath.substring(req.getContextPath().length());
+                }
+                LOG.info("Forwarding to realPath: " + realPath);
+                request.getRequestDispatcher(realPath).forward(request, response);
+                return;
+            }
+        }
+        filterChain.doFilter(request, response);
+    }
+
+    /**
+     * Perform Portlet Preparation
+     *
+     * @param request
+     * @param response
+     * @throws java.io.IOException            if an io exception occurs
+     * @throws javax.servlet.ServletException if a servlet exception occurs
+     * @return A boolean flag indicating whether or not an action request was
+     * processed. A value of true indicates than an action request was 
+     * processed while a value of false indicates that an action request was
+     * NOT processed.
+     */
+    public boolean doPortletPrepare(HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException {
+
+    	boolean actionRequestProcessed = false;
+    	
+        PortalRequestContext portalRequestContext =
+            new PortalRequestContext(getServletContext(), request, response);
+
+        PortalURL portalURL = portalRequestContext.getRequestedPortalURL();
+        String actionWindowId = portalURL.getActionWindow();
+
+        PortletWindowConfig actionWindowConfig =
+            actionWindowId == null
+                ? null
+                : PortletWindowConfig.fromId(actionWindowId);
+
+        // Action window config will only exist if there is an action request.
+        if (actionWindowConfig != null) {
+            PortletWindowImpl portletWindow = new PortletWindowImpl(container,
+                actionWindowConfig, portalURL);
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Processing action request for window: "
+                    + portletWindow.getId().getStringId());
+            }
+            try {
+                container.doAction(portletWindow, request, response, true);
+            } catch (PortletContainerException ex) {
+                throw new ServletException(ex);
+            } catch (PortletException ex) {
+                throw new ServletException(ex);
+            }
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Action request processed.\n\n");
+            }
+            
+            actionRequestProcessed = true;
+        }
+        
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Render Path: " + portalURL.getRenderPath());
+            LOG.debug("Servlet Path: " + portalURL.getServletPath());        	
+        }
+
+        return actionRequestProcessed;
+    }
+}