001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.pluto.internal.impl;
018:
019: import java.util.Enumeration;
020: import java.util.Vector;
021:
022: import javax.portlet.PortletContext;
023: import javax.portlet.PortletSession;
024: import javax.portlet.PortletSessionUtil;
025: import javax.servlet.http.HttpSessionContext;
026: import javax.servlet.http.HttpSession;
027: import javax.servlet.ServletContext;
028:
029: import org.apache.pluto.internal.InternalPortletWindow;
030: import org.apache.pluto.util.ArgumentUtility;
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033:
034: /**
035: * Implementation of the <code>javax.portlet.PortletSession</code> interface.
036: *
037: */
038: public class PortletSessionImpl implements PortletSession, HttpSession {
039:
040: /** Logger. */
041: private static final Log LOG = LogFactory
042: .getLog(PortletSessionImpl.class);
043:
044: /** The default scope (<code>PORTLET_SCOPE</code>) for storing objects. */
045: private static final int DEFAULT_SCOPE = PortletSession.PORTLET_SCOPE;
046:
047: /** The portlet scope namespace as defined in PLT. 15.3. */
048: private static final String PORTLET_SCOPE_NAMESPACE = "javax.portlet.p.";
049:
050: /** The portlet window ID / attribute name separator as defined in PLT. 15.3. */
051: private static final char ID_NAME_SEPARATOR = '?';
052:
053: // Private Member Variables ------------------------------------------------
054:
055: /** The wrapped HttpSession object. */
056: private final HttpSession httpSession;
057:
058: /** The portlet context. */
059: private final PortletContext portletContext;
060:
061: /** The internal portlet window. */
062: private final InternalPortletWindow internalPortletWindow;
063:
064: // Constructor -------------------------------------------------------------
065:
066: /**
067: * Constructs an instance.
068: */
069: public PortletSessionImpl(PortletContext portletContext,
070: InternalPortletWindow internalPortletWindow,
071: HttpSession httpSession) {
072: this .portletContext = portletContext;
073: this .internalPortletWindow = internalPortletWindow;
074: this .httpSession = httpSession;
075: }
076:
077: // PortletSession Impl: Attributes -----------------------------------------
078:
079: public Object getAttribute(String name) {
080: return getAttribute(name, DEFAULT_SCOPE);
081: }
082:
083: /**
084: * Returns the attribute of the specified name under the given scope.
085: *
086: * @param name the attribute name.
087: * @param scope the scope under which the attribute object is stored.
088: * @return the attribute object.
089: */
090: public Object getAttribute(String name, int scope) {
091: ArgumentUtility.validateNotNull("attributeName", name);
092: String key = (scope == PortletSession.APPLICATION_SCOPE) ? name
093: : createPortletScopedId(name);
094: return httpSession.getAttribute(key);
095: }
096:
097: public Enumeration getAttributeNames() {
098: return getAttributeNames(DEFAULT_SCOPE);
099: }
100:
101: public Enumeration getAttributeNames(int scope) {
102: // Return all attribute names in the nested HttpSession object.
103: if (scope == PortletSession.APPLICATION_SCOPE) {
104: return httpSession.getAttributeNames();
105: }
106: // Return attribute names with the portlet-scoped prefix.
107: else {
108: Vector portletScopedNames = new Vector();
109: for (Enumeration en = httpSession.getAttributeNames(); en
110: .hasMoreElements();) {
111: String name = (String) en.nextElement();
112: if (isInCurrentPortletScope(name)) {
113: portletScopedNames.add(PortletSessionUtil
114: .decodeAttributeName(name));
115: }
116: }
117: return portletScopedNames.elements();
118: }
119: }
120:
121: public void removeAttribute(String name) {
122: removeAttribute(name, DEFAULT_SCOPE);
123: }
124:
125: public void removeAttribute(String name, int scope) {
126: ArgumentUtility.validateNotNull("attributeName", name);
127: if (scope == PortletSession.APPLICATION_SCOPE) {
128: httpSession.removeAttribute(name);
129: } else {
130: httpSession.removeAttribute(createPortletScopedId(name));
131: }
132: }
133:
134: public void setAttribute(String name, Object value) {
135: setAttribute(name, value, DEFAULT_SCOPE);
136: }
137:
138: public void setAttribute(String name, Object value, int scope) {
139: ArgumentUtility.validateNotNull("attributeName", name);
140: if (scope == PortletSession.APPLICATION_SCOPE) {
141: httpSession.setAttribute(name, value);
142: } else {
143: httpSession
144: .setAttribute(createPortletScopedId(name), value);
145: }
146: }
147:
148: // PortletSession Impl: Other Methods --------------------------------------
149:
150: public PortletContext getPortletContext() {
151: return portletContext;
152: }
153:
154: public long getCreationTime() {
155: return httpSession.getCreationTime();
156: }
157:
158: public String getId() {
159: return httpSession.getId();
160: }
161:
162: public long getLastAccessedTime() {
163: return httpSession.getLastAccessedTime();
164: }
165:
166: public int getMaxInactiveInterval() {
167: return httpSession.getMaxInactiveInterval();
168: }
169:
170: public void invalidate() throws IllegalStateException {
171: httpSession.invalidate();
172: }
173:
174: public boolean isNew() throws IllegalStateException {
175: return httpSession.isNew();
176: }
177:
178: /**
179: * Specifies the time, in seconds, between client requests, before the
180: * portlet container invalidates this session. A negative time indicates
181: * the session should never timeout.
182: * <p>
183: * [Portlet Spec. PLT. 15.4.] If the PortletSession object is invalidated
184: * by a portlet, the portlet container must invalidate the associated
185: * HttpSession object.
186: * </p>
187: * @param interval an integer specifying the number of seconds.
188: */
189: public void setMaxInactiveInterval(int interval) {
190: httpSession.setMaxInactiveInterval(interval);
191: if (LOG.isDebugEnabled()) {
192: LOG.debug("Session timeout set to: " + interval);
193: }
194: }
195:
196: // Private Methods ---------------------------------------------------------
197:
198: /**
199: * Creates portlet-scoped ID for the specified attribute name.
200: * Portlet-scoped ID for a given attribute name has the following form:
201: * <code>javax.portlet.p.<ID>?<name></code>
202: * where <code>ID</code> is a unique identification for the portlet window
203: * (assigned by the portal/portlet-container) that must not contain a '?'
204: * character. <code>name</code> is the attribute name.
205: * <p>
206: * Refer to Portlet Specification PLT. 15.3 for more details.
207: * </p>
208: * @param name the attribute name.
209: * @return portlet-scoped ID for the attribute name.
210: */
211: private String createPortletScopedId(String name) {
212: StringBuffer buffer = new StringBuffer();
213: buffer.append(PORTLET_SCOPE_NAMESPACE);
214: buffer.append(internalPortletWindow.getId().getStringId());
215: buffer.append(ID_NAME_SEPARATOR);
216: buffer.append(name);
217: return buffer.toString();
218: }
219:
220: /**
221: * Checks if the attribute name in APPLICATION_SCOPE is in the current
222: * portlet scope.
223: * @param name the attribute name to check.
224: * @return true if the attribute name is in the current portlet scope.
225: * @see #createPortletScopedId(String)
226: */
227: private boolean isInCurrentPortletScope(String name) {
228: // Portlet-scoped attribute names MUST start with "javax.portlet.p.",
229: // and contain the ID-name separator '?'.
230: if (name.startsWith(PORTLET_SCOPE_NAMESPACE)
231: && name.indexOf(ID_NAME_SEPARATOR) > -1) {
232: String id = name.substring(
233: PORTLET_SCOPE_NAMESPACE.length(), name
234: .indexOf(ID_NAME_SEPARATOR));
235: return (id.equals(internalPortletWindow.getId()
236: .getStringId()));
237: }
238: // Application-scoped attribute names are not in portlet scope.
239: else {
240: return false;
241: }
242: }
243:
244: // HttpSession Impl --------------------------------------------------------
245:
246: public ServletContext getServletContext() {
247: return httpSession.getServletContext();
248: }
249:
250: /**
251: * DEPRECATED: implemented for backwards compatability with HttpSession.
252: * @deprecated
253: */
254: public HttpSessionContext getSessionContext() {
255: return httpSession.getSessionContext();
256: }
257:
258: public Object getValue(String name) {
259: return this .getAttribute(name, DEFAULT_SCOPE);
260: }
261:
262: /**
263: * DEPRECATED: Implemented for backwards compatibility with HttpSession.
264: * @deprecated
265: */
266: public String[] getValueNames() {
267: return httpSession.getValueNames();
268: }
269:
270: public void putValue(String name, Object value) {
271: this .setAttribute(name, value, DEFAULT_SCOPE);
272: }
273:
274: public void removeValue(String name) {
275: this.removeAttribute(name, DEFAULT_SCOPE);
276: }
277:
278: }
|