blob: 65f8c632c4a2df5eaa2a7d39a189daf2801bc04a [file] [log] [blame]
/*
* Copyright 2003,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.pluto.internal.impl;
import java.util.Enumeration;
import java.util.Vector;
import javax.portlet.PortletContext;
import javax.portlet.PortletSession;
import javax.portlet.PortletSessionUtil;
import javax.servlet.http.HttpSessionContext;
import javax.servlet.http.HttpSession;
import javax.servlet.ServletContext;
import org.apache.pluto.internal.InternalPortletWindow;
import org.apache.pluto.util.ArgumentUtility;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Implementation of the <code>javax.portlet.PortletSession</code> interface.
*
* @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
* @author <a href="mailto:zheng@apache.org">ZHENG Zhong</a>
*/
public class PortletSessionImpl implements PortletSession, HttpSession {
/** Logger. */
private static final Log LOG = LogFactory.getLog(PortletSessionImpl.class);
/** The default scope (<code>PORTLET_SCOPE</code>) for storing objects. */
private static final int DEFAULT_SCOPE = PortletSession.PORTLET_SCOPE;
/** The portlet scope namespace as defined in PLT. 15.3. */
private static final String PORTLET_SCOPE_NAMESPACE = "javax.portlet.p.";
/** The portlet window ID / attribute name separator as defined in PLT. 15.3. */
private static final char ID_NAME_SEPARATOR = '?';
// Private Member Variables ------------------------------------------------
/** The wrapped HttpSession object. */
private HttpSession httpSession = null;
/** The portlet context. */
private PortletContext portletContext = null;
/** The internal portlet window. */
private InternalPortletWindow internalPortletWindow = null;
// Constructor -------------------------------------------------------------
/**
* Constructs an instance.
*/
public PortletSessionImpl(PortletContext portletContext,
InternalPortletWindow internalPortletWindow,
HttpSession httpSession) {
this.portletContext = portletContext;
this.internalPortletWindow = internalPortletWindow;
this.httpSession = httpSession;
}
// PortletSession Impl: Attributes -----------------------------------------
public Object getAttribute(String name) {
return getAttribute(name, DEFAULT_SCOPE);
}
/**
* Returns the attribute of the specified name under the given scope.
*
* @param name the attribute name.
* @param scope the scope under which the attribute object is stored.
* @return the attribute object.
*/
public Object getAttribute(String name, int scope) {
ArgumentUtility.validateNotNull("attributeName", name);
String key = (scope == PortletSession.APPLICATION_SCOPE)
? name : createPortletScopedId(name);
return httpSession.getAttribute(key);
}
public Enumeration getAttributeNames() {
return getAttributeNames(DEFAULT_SCOPE);
}
public Enumeration getAttributeNames(int scope) {
// Return all attribute names in the nested HttpSession object.
if (scope == PortletSession.APPLICATION_SCOPE) {
return httpSession.getAttributeNames();
}
// Return attribute names with the portlet-scoped prefix.
else {
Vector portletScopedNames = new Vector();
for (Enumeration en = httpSession.getAttributeNames();
en.hasMoreElements(); ) {
String name = (String) en.nextElement();
if (isInCurrentPortletScope(name)) {
portletScopedNames.add(
PortletSessionUtil.decodeAttributeName(name));
}
}
return portletScopedNames.elements();
}
}
public void removeAttribute(String name) {
removeAttribute(name, DEFAULT_SCOPE);
}
public void removeAttribute(String name, int scope) {
ArgumentUtility.validateNotNull("attributeName", name);
if (scope == PortletSession.APPLICATION_SCOPE) {
httpSession.removeAttribute(name);
} else {
httpSession.removeAttribute(createPortletScopedId(name));
}
}
public void setAttribute(String name, Object value) {
setAttribute(name, value, DEFAULT_SCOPE);
}
public void setAttribute(String name, Object value, int scope) {
ArgumentUtility.validateNotNull("attributeName", name);
if (scope == PortletSession.APPLICATION_SCOPE) {
httpSession.setAttribute(name, value);
} else {
httpSession.setAttribute(createPortletScopedId(name), value);
}
}
// PortletSession Impl: Other Methods --------------------------------------
public PortletContext getPortletContext() {
return portletContext;
}
public long getCreationTime() {
return httpSession.getCreationTime();
}
public String getId() {
return httpSession.getId();
}
public long getLastAccessedTime() {
return httpSession.getLastAccessedTime();
}
public int getMaxInactiveInterval() {
return httpSession.getMaxInactiveInterval();
}
public void invalidate() throws IllegalStateException {
httpSession.invalidate();
}
public boolean isNew() throws IllegalStateException {
return httpSession.isNew();
}
/**
* Specifies the time, in seconds, between client requests, before the
* portlet container invalidates this session. A negative time indicates
* the session should never timeout.
* <p>
* [Portlet Spec. PLT. 15.4.] If the PortletSession object is invalidated
* by a portlet, the portlet container must invalidate the associated
* HttpSession object.
* </p>
* @param interval an integer specifying the number of seconds.
*/
public void setMaxInactiveInterval(int interval) {
httpSession.setMaxInactiveInterval(interval);
if (LOG.isDebugEnabled()) {
LOG.debug("Session timeout set to: " + interval);
}
}
// Private Methods ---------------------------------------------------------
/**
* Creates portlet-scoped ID for the specified attribute name.
* Portlet-scoped ID for a given attribute name has the following form:
* <code>javax.portlet.p.&lt;ID&gt;?&lt;name&gt;</code>
* where <code>ID</code> is a unique identification for the portlet window
* (assigned by the portal/portlet-container) that must not contain a '?'
* character. <code>name</code> is the attribute name.
* <p>
* Refer to Portlet Specification PLT. 15.3 for more details.
* </p>
* @param name the attribute name.
* @return portlet-scoped ID for the attribute name.
*/
private String createPortletScopedId(String name) {
StringBuffer buffer = new StringBuffer();
buffer.append(PORTLET_SCOPE_NAMESPACE);
buffer.append(internalPortletWindow.getId().getStringId());
buffer.append(ID_NAME_SEPARATOR);
buffer.append(name);
return buffer.toString();
}
/**
* Checks if the attribute name in APPLICATION_SCOPE is in the current
* portlet scope.
* @param name the attribute name to check.
* @return true if the attribute name is in the current portlet scope.
* @see #createPortletScopedId(String)
*/
private boolean isInCurrentPortletScope(String name) {
// Portlet-scoped attribute names MUST start with "javax.portlet.p.",
// and contain the ID-name separator '?'.
if (name.startsWith(PORTLET_SCOPE_NAMESPACE)
&& name.indexOf(ID_NAME_SEPARATOR) > -1) {
String id = name.substring(PORTLET_SCOPE_NAMESPACE.length(),
name.indexOf(ID_NAME_SEPARATOR));
return (id.equals(internalPortletWindow.getId().getStringId()));
}
// Application-scoped attribute names are not in portlet scope.
else {
return false;
}
}
// HttpSession Impl --------------------------------------------------------
public ServletContext getServletContext() {
return httpSession.getServletContext();
}
/**
* DEPRECATED: implemented for backwards compatability with HttpSession.
* @deprecated
*/
public HttpSessionContext getSessionContext() {
return httpSession.getSessionContext();
}
public Object getValue(String name) {
return this.getAttribute(name, DEFAULT_SCOPE);
}
/**
* DEPRECATED: Implemented for backwards compatibility with HttpSession.
* @deprecated
*/
public String[] getValueNames() {
return httpSession.getValueNames();
}
public void putValue(String name, Object value) {
this.setAttribute(name, value, DEFAULT_SCOPE);
}
public void removeValue(String name) {
this.removeAttribute(name, DEFAULT_SCOPE);
}
}