/*
* Created on 10-Mar-2003
*/
package net.sf.jportlet.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.jportlet.portlet.Client;
import net.sf.jportlet.portlet.Portlet;
import net.sf.jportlet.portlet.PortletData;
import net.sf.jportlet.portlet.PortletException;
import net.sf.jportlet.portlet.PortletRequest;
import net.sf.jportlet.portlet.PortletSession;
import net.sf.jportlet.portlet.PortletSettings;
import net.sf.jportlet.portlet.PortletURI;
import net.sf.jportlet.portlet.PortletWindow;
import net.sf.jportlet.portlet.User;
import net.sf.jportlet.portlet.application.PortletProxy;
import net.sf.jportlet.portlet.descriptor.AuthConstraintDescriptor;
import net.sf.jportlet.service.PortletServiceFactory;
import net.sf.jportlet.service.user.UserService;
import net.sf.jportlet.util.LocaleHelper;
/**
* Implementation of {@link net.sf.jportlet.portlet.PortletRequest}
*
* @author <a href="mailto:tchbansi@sourceforge.net">Herve Tchepannou</a>
*/
public class PortletRequestImpl
extends HttpServletRequestWrapper
implements PortletRequest
{
//~ Static fields/initializers ---------------------------------------------
private static final Log __log = LogFactory.getLog( PortletRequest.class );
/**
* Key for accessing the <code>Locale</code> from <code>HttpSession</code>
*/
public static final String LOCALE_KEY = "net.sf.jportal.Locale";
/**
* Key for accessing the previous <code>PortletRequest</code>
*/
public static final String PORTLET_REQUEST_KEY = "net.sf.jportlet.portlet.PortletRequest";
/**
* Key for accessing the {@link PortletURI} from <code>HttpServletRequest</code>
*/
public static final String PORTLET_URI_KEY = "net.sf.jportlet.portlet.PortletRequest.PortletURI";
/**
* Prefix of the key of each {@link PortletSession} stored in the <code>HttpSession</code>
*/
public static final String SESSION_KEY_PREFIX = "net.sf.jportlet.portlet.PortletRequest.PortletSession";
/**
* Key for accessing the current user's id from <code>HttpSession</code>
*/
public static final String USER_ID_KEY = "net.sf.jportlet.portlet.PortletRequest.User.id";
/**
* Key for accessing the {@link User} from <code>HttpServletRequest</code>
*/
public static final String USER_KEY = "net.sf.jportlet.portlet.PortletRequest.User";
/**
* Key for accessing the {@link User}'s roles from <code>HttpServletRequest</code>
*/
public static final String ROLES_KEY = "net.sf.jportlet.portlet.PortletRequest.Roles";
//~ Instance fields --------------------------------------------------------
private Map _attributes;
private String _contextPath;
private PortletDataImpl _data;
private Collection _errors;
private HttpServletRequest _httpRequest;
private Locale _locale;
private PortletPageContext _pageContext;
private PortletURI _portletURI;
private PortletProxy _proxy;
private PortletServiceFactory _serviceFactory;
private String _sessionKey;
private PortletSettingsImpl _settings;
private PortletWindow _window;
//~ Constructors -----------------------------------------------------------
public PortletRequestImpl( PortletProxy proxy,
HttpServletRequest httpRequest,
PortletServiceFactory serviceFactory )
{
super( httpRequest );
boolean debug = __log.isDebugEnabled( );
_proxy = proxy;
_httpRequest = httpRequest;
_serviceFactory = serviceFactory;
_sessionKey = SESSION_KEY_PREFIX + "#" + proxy.getDescriptor( ).getName( );
/* Initialize the state of the current request */
PortletRequestImpl request = ( PortletRequestImpl ) httpRequest.getAttribute( PORTLET_REQUEST_KEY );
if ( ( request != null ) && ( request.getProxy( ).getPortletConfig( ).getPortletName( ) == proxy.getPortletConfig( ).getPortletName( ) ) )
{
if ( debug )
{
__log.debug( "Inheriting: attributes=" + request.getAttributes( ) + ", errors=" + request.getErrors( ) );
}
setAttributes( request.getAttributes( ) );
if ( request.hasErrors( ) )
{
addErrors( request.getErrors( ) );
}
}
}
//~ Methods ----------------------------------------------------------------
public void addError( Object error )
{
if ( __log.isDebugEnabled( ) )
{
__log.debug( "adding error: " + error );
}
if ( _errors == null )
{
_errors = new ArrayList( );
}
_errors.add( error );
}
public void addErrors( Collection errors )
{
if ( __log.isDebugEnabled( ) )
{
__log.debug( "adding errors: " + errors );
}
if ( _errors == null )
{
_errors = new ArrayList( );
}
_errors.addAll( errors );
}
/**
* @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
*/
public Object getAttribute( String name )
{
return ( _attributes != null )
? _attributes.get( name )
: null;
}
/**
* @see javax.servlet.ServletRequest#getAttributeNames()
*/
public Enumeration getAttributeNames( )
{
return ( _attributes != null )
? Collections.enumeration( _attributes.keySet( ) )
: Collections.enumeration( Collections.EMPTY_LIST );
}
public Map getAttributes( )
{
return ( _attributes != null )
? _attributes
: Collections.EMPTY_MAP;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getClient()
*/
public Client getClient( )
{
return ClientImpl.getClient( getHttpRequest() );
}
/**
* @see javax.servlet.http.HttpServletRequest#getContextPath()
*/
public String getContextPath( )
{
if ( _contextPath == null )
{
_contextPath = _httpRequest.getContextPath( ) + _proxy.getDescriptor( ).getContextPath( );
}
return _contextPath;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getData()
*/
public PortletData getData( )
{
if ( _data == null )
{
_data = new PortletDataImpl( _proxy, _serviceFactory, getUser( ) );
}
return _data;
}
public Collection getErrors( )
{
return _errors;
}
public HttpServletRequest getHttpRequest( )
{
return _httpRequest;
}
/**
* @see javax.servlet.ServletRequest#getLocale()
*/
public Locale getLocale( )
{
if ( _locale == null )
{
HttpSession session = _httpRequest.getSession( false );
if ( session == null )
{
_locale = super.getLocale( );
}
else
{
String locale = ( String ) session.getAttribute( LOCALE_KEY );
_locale = LocaleHelper.getLocale( locale, super.getLocale( ) );
}
}
return _locale;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getMode()
*/
public Portlet.Mode getMode( )
{
PortletURIImpl uri = ( PortletURIImpl ) getPortletURI( );
if ( uri != null )
{
Portlet.Mode mode = uri.getMode( );
if ( mode != null )
{
return mode;
}
}
return Portlet.Mode.VIEW;
}
/**
* @return PortletPageContext
*/
public PortletPageContext getPageContext( )
{
return _pageContext;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getPortletSession()
*/
public PortletSession getPortletSession( )
{
return getPortletSession( true );
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getPortletSession(boolean)
*/
public PortletSession getPortletSession( boolean create )
{
/* Get the session */
HttpSession session = _httpRequest.getSession( create );
if ( session == null )
{
return null;
}
/* Get all the portlet' sessions */
HashMap map = ( HashMap ) session.getAttribute( SESSION_KEY_PREFIX );
if ( map == null )
{
if ( create )
{
map = new HashMap( );
session.setAttribute( SESSION_KEY_PREFIX, map );
}
else
{
return null;
}
}
/* Get the portlet session */
PortletSession psession = ( PortletSession ) map.get( _sessionKey );
if ( ( psession == null ) && create )
{
psession = new PortletSessionImpl( );
map.put( _sessionKey, psession );
}
return psession;
}
public PortletURI getPortletURI( )
{
if ( _portletURI == null )
{
PortletURIImpl uri = ( PortletURIImpl ) _httpRequest.getAttribute( PORTLET_URI_KEY );
if ( ( uri != null ) && uri.getPortletName( ).equals( _proxy.getDescriptor( ).getName( ) ) )
{
_portletURI = uri;
}
}
return _portletURI;
}
/**
* @return PortletProxy
*/
public PortletProxy getProxy( )
{
return _proxy;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getSettings()
*/
public PortletSettings getSettings( )
{
if ( _settings == null )
{
_settings = new PortletSettingsImpl( _proxy, _serviceFactory );
}
return _settings;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getUser()
*/
public User getUser( )
{
/* Load the user chached in the HttpServletRequest */
User usr = ( User ) _httpRequest.getAttribute( USER_KEY );
if ( usr != null )
{
return usr;
}
/* Load the user */
String userId = getUserId( );
if ( userId != null )
{
try
{
UserService srv = ( UserService ) _serviceFactory.getPortletService( UserService.NAME );
usr = srv.getUser( userId );
/* Cache the user into the HttpServletRequest */
if ( usr != null )
{
_httpRequest.setAttribute( USER_KEY, usr );
}
}
catch ( Exception e )
{
__log.error( "Error while retrieving User. userId=" + userId, e );
}
}
return usr;
}
public String getUserId( )
{
HttpSession session = _httpRequest.getSession( false );
return ( session != null )
? ( String ) session.getAttribute( USER_ID_KEY )
: null;
}
/**
* Return a list of all the roles of the current user, or <code>null</code> if the
* current user has no role or no user is logged in
*
* @return Collection
*/
public Collection getUserRoles( )
{
/* Load the roles cached in the HttpServletRequest */
Collection roles = ( Collection ) _httpRequest.getAttribute( ROLES_KEY );
if ( roles != null )
{
return roles;
}
/* Load the roles */
String userId = getUserId( );
if ( userId != null )
{
try
{
UserService srv = ( UserService ) _serviceFactory.getPortletService( UserService.NAME );
roles = srv.getRoles( userId );
}
catch ( Exception e )
{
__log.error( "Error while retrieving roles. userId=" + userId, e );
}
}
/* Cache the user into the HttpServletRequest */
if ( roles != null )
{
_httpRequest.setAttribute( ROLES_KEY, roles );
}
return roles;
}
/**
* @see net.sf.jportlet.portlet.PortletRequest#getWindow()
*/
public PortletWindow getWindow( )
{
if ( _window == null )
{
_window = new PortletWindowImpl( this );
}
return _window;
}
public boolean hasErrors( )
{
return ( _errors != null ) && ( _errors.size( ) > 0 );
}
/**
* @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
*/
public void removeAttribute( String name )
{
if ( _attributes != null )
{
_attributes.remove( name );
}
}
/**
* @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object)
*/
public void setAttribute( String name,
Object value )
{
if ( _attributes == null )
{
_attributes = new HashMap( );
}
_attributes.put( name, value );
}
public void setAttributes( Map attributes )
{
if ( _attributes == null )
{
_attributes = new HashMap( );
}
_attributes.putAll( attributes );
}
/**
* Sets the pageContext.
* @param pageContext The pageContext to set
*/
public void setPageContext( PortletPageContext pageContext )
{
_pageContext = pageContext;
}
/**
* Start a new session for a user.
* This function is called by the container when a user logs in.
*
* @param user User who starts the current session
*/
public void startSession( User user )
throws PortletException
{
if ( __log.isDebugEnabled( ) )
{
__log.debug( "starting session for user=" + user );
}
HttpSession session = _httpRequest.getSession( true );
Locale locale = user.getLocale( );
_httpRequest.setAttribute( USER_KEY, user );
_httpRequest.removeAttribute( ROLES_KEY );
session.setAttribute( USER_ID_KEY, user.getId( ) );
if ( locale != null )
{
session.setAttribute( LOCALE_KEY, locale.toString( ) );
}
}
/**
* Stop the current session.
* This function is called by the container when the current user logs out
*/
public void stopSession( )
{
if ( __log.isDebugEnabled( ) )
{
__log.debug( "Stopping current session" );
}
HttpSession session = _httpRequest.getSession( false );
if ( session != null )
{
session.removeAttribute( LOCALE_KEY );
session.removeAttribute( USER_ID_KEY );
}
_httpRequest.removeAttribute( USER_KEY );
_httpRequest.removeAttribute( ROLES_KEY );
}
/**
* @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
*/
public boolean isUserInRole( String role )
{
return getUserRoles( ).contains( role );
}
/**
* Return <code>true</code> if the current user can access the portlet in a given mode
* @param mode
* @return boolean
*/
public boolean canAccess( Portlet.Mode mode )
{
boolean debug = __log.isDebugEnabled( );
boolean access;
if ( debug )
{
__log.debug( "canAccess(" + mode + ")" );
}
AuthConstraintDescriptor descr = _proxy.getDescriptor( ).getAuthConstraintDescriptor( mode );
if ( descr == null )
{
if ( debug )
{
__log.debug( "...No security-contraint" );
}
access = true;
}
else
{
String userId = getUserId( );
if ( userId == null )
{
if ( debug )
{
__log.debug( "...Allowing anonymous access" );
}
access = descr.isAllowAnonymous( );
}
else
{
return descr.containsRoles( getUserRoles( ) );
}
}
if ( debug )
{
__log.debug( "...access=" + access );
}
return access;
}
public void userChanged( User user )
{
Locale locale = user.getLocale( );
User old = ( User ) _httpRequest.getAttribute( USER_KEY );
if ( ( old != null ) && ( old.getId( ).equals( user.getId( ) ) ) )
{
_httpRequest.setAttribute( USER_KEY, user );
if ( locale != null )
{
_httpRequest.getSession( ).setAttribute( LOCALE_KEY, locale.toString( ) );
}
else
{
_httpRequest.getSession( ).removeAttribute( LOCALE_KEY );
}
}
}
}