/*
* Copyright 2000-2004 The Apache Software Foundation.
*
* Licensed 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.jetspeed.engine.servlet;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.portlet.PortletRequest;
import javax.servlet.ServletRequest;
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.jetspeed.PortalReservedParameters;
import org.apache.jetspeed.container.url.PortalURL;
import org.apache.jetspeed.request.JetspeedRequestContext;
import org.apache.jetspeed.request.RequestContext;
import org.apache.pluto.om.common.ObjectID;
import org.apache.pluto.om.entity.PortletApplicationEntity;
import org.apache.pluto.om.entity.PortletEntity;
import org.apache.pluto.om.portlet.PortletApplicationDefinition;
import org.apache.pluto.om.portlet.PortletDefinition;
import org.apache.pluto.om.window.PortletWindow;
import org.apache.pluto.util.Enumerator;
import org.apache.pluto.util.NamespaceMapper;
import org.apache.pluto.util.NamespaceMapperAccess;
/**
* This request wrappers the servlet request and is used within the container to
* communicate to the invoked servlet.
*
* @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
* @version $Id: ServletRequestImpl.java,v 1.37 2005/04/02 19:38:25 ate Exp $
*/
public class ServletRequestImpl extends HttpServletRequestWrapper
{
public static final String ACCEPT_LANGUAGE = "Accept-Language";
/** Logger */
private static final Log log = LogFactory.getLog(ServletRequestImpl.class);
PortletWindow portletWindow = null;
private NamespaceMapper nameSpaceMapper = null;
private ServletRequest currentRequest = null;
private Map portletParameters;
private ObjectID webAppId;
public ServletRequestImpl( HttpServletRequest servletRequest, PortletWindow window )
{
super(servletRequest);
nameSpaceMapper = NamespaceMapperAccess.getNamespaceMapper();
this.portletWindow = window;
PortletDefinition portletDef = portletWindow.getPortletEntity().getPortletDefinition();
if(portletDef != null)
{
webAppId = portletDef.getPortletApplicationDefinition().getWebApplicationDefinition().getId();
}
else
{
// This happens when an entity is referencing a non-existent portlet
webAppId = window.getId();
}
}
protected HttpServletRequest _getHttpServletRequest()
{
return (HttpServletRequest) super.getRequest();
}
// ServletRequestWrapper overlay
public String getParameter( String name )
{
Object value = this.getParameterMap().get(name);
if (value == null)
{
return (null);
}
else if (value instanceof String[])
{
return (((String[]) value)[0]);
}
else if (value instanceof String)
{
return ((String) value);
}
else
{
return (value.toString());
}
}
public Map getParameterMap()
{
if (currentRequest == null || currentRequest != getRequest() )
{
// Cache the parameters for as long as the wrapped request stays the same.
// According to Servlet 2.3 SRV.6.2.2 the passed on ServletRequest object
// to an dispatched Servlet must remain the same (this one).
// Tomcat solves this by injecting a new ServletRequest of its own above
// this one (the getRequest() object).
// So, when that one has changed since the last time the parameters have
// been accessed, flush the cache and rebuild the map.
currentRequest = getRequest();
portletParameters = new HashMap();
// get portlet params
JetspeedRequestContext context = (JetspeedRequestContext) getAttribute("org.apache.jetspeed.request.RequestContext");
if (context != null)
{
PortalURL url = context.getPortalURL();
Iterator iter = url.getNavigationalState().getParameterNames(portletWindow);
while (iter.hasNext())
{
String name = (String) iter.next();
String[] values = url.getNavigationalState().getParameterValues(portletWindow, name);
portletParameters.put(name, values);
}
}
//get servlet params
for (Enumeration parameters = getRequest().getParameterNames(); parameters.hasMoreElements();)
{
String paramName = (String) parameters.nextElement();
String[] paramValues = (String[]) getRequest().getParameterValues(paramName);
String[] values = (String[]) portletParameters.get(paramName);
if (getCharacterEncoding() != null)
{
for (int i = 0; i < paramValues.length; i++)
{
try
{
paramValues[i] = new String(paramValues[i].getBytes("ISO-8859-1"), getCharacterEncoding());
}
catch (UnsupportedEncodingException e)
{
;
}
}
}
if (values != null)
{
String[] temp = new String[paramValues.length + values.length];
System.arraycopy(paramValues, 0, temp, 0, paramValues.length);
System.arraycopy(values, 0, temp, paramValues.length, values.length);
paramValues = temp;
}
portletParameters.put(paramName, paramValues);
}
}
return Collections.unmodifiableMap(portletParameters);
}
public Enumeration getParameterNames()
{
return Collections.enumeration(this.getParameterMap().keySet());
}
public String[] getParameterValues( String name )
{
return (String[]) this.getParameterMap().get(name);
}
/**
* @see javax.servlet.http.HttpServletRequest#getAttribute(java.lang.String)
*/
public Object getAttribute( String name )
{
Object value = super.getAttribute(name);
if (name.equals(PortletRequest.USER_INFO))
{
JetspeedRequestContext context = (JetspeedRequestContext) getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
if (null != context)
{
String entityID = "--NULL--";
PortletEntity entity = portletWindow.getPortletEntity();
if (entity != null)
{
entityID = entity.getId().toString();
}
PortletApplicationEntity portletAppEntity = portletWindow.getPortletEntity()
.getPortletApplicationEntity();
PortletApplicationDefinition portletAppDef = entity.getPortletDefinition()
.getPortletApplicationDefinition();
if (null != portletAppDef)
{
value = context.getUserInfoMap(portletAppDef.getId());
if (log.isDebugEnabled() && (null != value))
log.debug(PortletRequest.USER_INFO + " map size: " + ((Map) value).size());
}
else
{
log.error("Entity is null:" + entityID);
}
}
}
else
{
if (null == value)
{
PortletRequest pr = (PortletRequest) super.getAttribute("javax.portlet.request");
if (pr != null)
{
value = super.getAttribute(NamespaceMapperAccess.getNamespaceMapper().encode(portletWindow.getId(),
name));
}
}
}
return value;
}
/**
* @see javax.servlet.ServletRequest#getLocale()
*/
public Locale getLocale()
{
//Locale preferedLocale = (Locale) getSession().getAttribute(RequestContext.PREFERED_LOCALE_SESSION_KEY);
RequestContext requestContext = (RequestContext) _getHttpServletRequest().getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
Locale preferedLocale = requestContext.getLocale();
if (preferedLocale != null)
{
return preferedLocale;
}
return super.getLocale();
}
/**
* @see javax.servlet.ServletRequest#getLocales()
*/
public Enumeration getLocales()
{
RequestContext requestContext = (RequestContext) _getHttpServletRequest().getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
Locale preferedLocale = requestContext.getLocale();
if (preferedLocale != null)
{
return getLocaleEnum(preferedLocale);
}
return super.getLocales();
}
/**
* <p>
* getLocaleEnum
* </p>
*
* @param preferedLocale
* @return
*/
protected Enumeration getLocaleEnum( Locale preferedLocale )
{
ArrayList locales = new ArrayList();
locales.add(preferedLocale);
Enumeration localeEnums = super.getLocales();
while (localeEnums.hasMoreElements())
{
locales.add(localeEnums.nextElement());
}
Iterator i = locales.iterator();
return new Enumerator(locales);
}
/**
* @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
*/
public String getHeader( String name )
{
if(name.equals(ACCEPT_LANGUAGE))
{
return getLocale().getLanguage();
}
else
{
return super.getHeader(name);
}
}
/**
* @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
*/
public Enumeration getHeaders( String name )
{
if(name.equals(ACCEPT_LANGUAGE))
{
return getLocaleEnum(getLocale());
}
else
{
return super.getHeaders(name);
}
}
/**
* <p>
* setAttribute
* </p>
*
* @see javax.servlet.ServletRequest#setAttribute(java.lang.String,
* java.lang.Object)
* @param arg0
* @param arg1
*/
public void setAttribute( String name, Object value )
{
if (name == null)
{
throw new IllegalArgumentException("Attribute name == null");
}
// This allows us to make jetpseed objects avaiable to portlets
// This makes the portlet non-portable but is a must admin portlets
if (name.startsWith("org.apache.jetspeed"))
{
if (value == null)
{
this.removeAttribute(name);
}
else
{
String encodedKey = nameSpaceMapper.encode(portletWindow.getId(), name);
this._getHttpServletRequest().setAttribute(
encodedKey, value);
}
}
super.setAttribute(name, value);
}
/**
* <p>
* getHeaderNames
* </p>
*
* @see javax.servlet.http.HttpServletRequest#getHeaderNames()
* @return
*/
public Enumeration getHeaderNames()
{
return super.getHeaderNames();
}
/*
* JST-168 PLT.16.3.3 cxxix
*/
public String getProtocol()
{
return null;
}
/*
* JST-168 PLT.16.3.3 cxxix
*/
public String getRemoteAddr()
{
return null;
}
/*
* JST-168 PLT.16.3.3 cxxix
*/
public String getRemoteHost()
{
return null;
}
/*
* JST-168 PLT.16.3.3 cxxix
*/
public String getRealPath()
{
return null;
}
/*
* JST-168 PLT.16.3.3 cxxix
*/
public StringBuffer getRequestURL()
{
return null;
}
/*
* JST-168 PLT.16.3.3 cxxx
*/
public String getPathInfo()
{
String attr = (String)super.getAttribute("javax.servlet.include.path_info");
return (attr != null) ? attr : super.getPathInfo();
}
/*
* JST-168 PLT.16.3.3 cxxx
*/
public String getPathTranslated()
{
// TODO: Don't know yet how to implement this.
// A null value is a valid value.
return null;
}
/*
* JST-168 PLT.16.3.3 cxxx
*/
public String getQueryString()
{
String attr = (String)super.getAttribute("javax.servlet.include.query_string");
return (attr != null) ? attr : super.getQueryString();
}
/*
* JST-168 PLT.16.3.3 cxxx
*/
public String getRequestURI()
{
String attr = (String)super.getAttribute("javax.servlet.include.request_uri");
return (attr != null) ? attr : super.getRequestURI();
}
/*
* JST-168 PLT.16.3.3 cxxx
*/
public String getServletPath()
{
String attr = (String)super.getAttribute("javax.servlet.include.servlet_path");
return (attr != null) ? attr : super.getServletPath();
}
/*
* JST-168 PLT.16.3.3 cxxxi
*/
public String getContextPath()
{
return portletWindow.getPortletEntity().getPortletDefinition()
.getPortletApplicationDefinition()
.getWebApplicationDefinition().getContextRoot();
}
}