001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064: package com.jcorporate.expresso.core.controller.session;
065:
066: import com.jcorporate.expresso.core.jsdkapi.GenericSession;
067: import com.jcorporate.expresso.core.misc.CookieUtil;
068: import com.jcorporate.expresso.core.misc.SerializableString;
069: import com.jcorporate.expresso.core.misc.StringUtil;
070: import com.jcorporate.expresso.kernel.exception.ChainedException;
071: import org.apache.log4j.Logger;
072:
073: import javax.servlet.ServletException;
074: import javax.servlet.http.Cookie;
075: import javax.servlet.http.HttpServletRequest;
076: import javax.servlet.http.HttpServletResponse;
077: import java.io.Serializable;
078: import java.util.Enumeration;
079:
080: /**
081: * A <code>HTTPPersistentSession</code> is simply a place to stash some values
082: * between states of a controller object. Different environments may employ
083: * different ways of doing this - the simplest being this one, where a
084: * hashtable does all the required work.
085: * </p>
086: * <p/>
087: * A servlet environment must use <code>HTTPPersistentSession</code>, which
088: * stores it's values in the HTTPSession for storage from one invokation to
089: * the next.</p>
090: * <p>If you are inside a controller environment, then call ControllerRequest.getSession()
091: * to get a <code>PersistentSession</code> object, and do not install this class
092: * directly. See the PersistentSession javadoc documentation for an example
093: * usage of this class</p>
094: *
095: * @author Michael Nash
096: * @see com.jcorporate.expresso.core.controller.session.PersistentSession
097: * @since Expresso 4.0
098: */
099: public class HTTPPersistentSession implements PersistentSession {
100: /**
101: * The log object
102: */
103: private static final transient Logger log = Logger
104: .getLogger(HTTPPersistentSession.class);
105:
106: /**
107: * The servlet request
108: */
109: private transient HttpServletRequest request = null;
110:
111: /**
112: * The servlet response object.
113: */
114: private transient HttpServletResponse response = null;
115:
116: /**
117: * Creates new HTTPPersistentSession
118: */
119: public HTTPPersistentSession() {
120: }
121:
122: /**
123: * Creates new HTTPPersistentSession and set the request object in one step
124: *
125: * @param req a <code>HttpServletRequest</code> object
126: * @param res a <code>HttpServletResponse</code> object
127: */
128: public HTTPPersistentSession(HttpServletRequest req,
129: HttpServletResponse res) {
130: this ();
131: setRequest(req);
132: setResponse(res);
133: }
134:
135: /**
136: * Sets an attribute on the Servlet request
137: *
138: * @param attribName The name of the object you wish to set.
139: * @param attribValue the object you want to set.
140: * @throws IllegalArgumentException if the current object's Request object
141: * has not be set yet.
142: */
143: public void setAttribute(String attribName, Object attribValue) {
144: if (request == null) {
145: throw new IllegalArgumentException(
146: "HTTPPersistentSession not initialized correctly");
147: }
148:
149: request.setAttribute(attribName, attribValue);
150: }
151:
152: /**
153: * Retrieves the object from the request context.
154: *
155: * @param attribName the name of the object to retrieve
156: * @return the object or null if it doesn't exist.
157: */
158: public Object getAttribute(String attribName) {
159: if (request == null) {
160: return null;
161: }
162:
163: return request.getAttribute(attribName);
164: }
165:
166: /**
167: * Retrieves all attribute names in the request context.
168: *
169: * @return java.util.Enumeration
170: */
171: public Enumeration getAttributeNames() {
172: return request.getAttributeNames();
173: }
174:
175: /**
176: * Sets a cookie in the client's system. Note that this cookie is
177: * encrypted with the password you set up in your
178: * <code>expresso-config.xml</code> file.
179: *
180: * @param attribName the name of the attribute to
181: * @param attribValue the value of the attribute to set.
182: * @throws IllegalArgumentException If the cookie encryption fails for
183: * some reason. The actual chained exception is logged.
184: */
185: public void setClientAttribute(String attribName, String attribValue) {
186: Cookie c1;
187:
188: try {
189: if ((attribValue != null) && (attribValue.length() > 0)) {
190: c1 = new Cookie(attribName, CookieUtil
191: .cookieEncode(attribValue));
192: c1.setMaxAge(2592000); /* 30 days */
193: } else {
194: c1 = new Cookie(attribName, "");
195: c1.setMaxAge(0);
196: }
197:
198: c1.setPath("/");
199: response.addCookie(c1);
200: } catch (ChainedException ce) {
201: log.error(ce);
202: throw new IllegalArgumentException(ce.getMessage());
203: }
204: }
205:
206: /* setClientAttrib(String, String) */
207:
208: /**
209: * Retrieves a value of a cookie set on the client's system. It also
210: * decrypts the value with the password you set up in your
211: * <code>expresso-config.xml</code> file.
212: *
213: * @param attribName the name of the cookie to retrieve
214: * @return java.lang.String the value of the cookie or null if the cookie
215: * doesn't exist.
216: * @throws IllegalArgumentException If there's a problem decrypting the
217: * cookie. The full error is logged. [Especially important for chained
218: * exceptions]
219: */
220: public String getClientAttribute(String attribName) {
221: Cookie[] cookies = request.getCookies();
222:
223: try {
224: if (cookies != null) {
225: for (int i = 0; i < cookies.length; i++) {
226: String name = StringUtil.notNull(cookies[i]
227: .getName());
228: String value = StringUtil.notNull(cookies[i]
229: .getValue());
230:
231: if (name.equalsIgnoreCase(attribName)) {
232: return CookieUtil.cookieDecode(value);
233: }
234: }
235: /* for each cookie */
236: }
237: /* if there are any cookies */
238: } catch (Exception ce) {
239: log.error(ce);
240: throw new IllegalArgumentException(ce.getMessage());
241: }
242:
243: return null;
244: }
245:
246: /**
247: * Retrieves all attribute names from the session context.
248: *
249: * @return java.util.Enumeration
250: */
251: public Enumeration getPeristentAttributeNames() {
252: try {
253: return GenericSession.getAttributeNames(request);
254: } catch (ServletException se) {
255: log.error(se);
256: }
257:
258: return null;
259: }
260:
261: /**
262: * Saves an attribute to the actual session, rather than simply the
263: * response. Use this for storing objects between requests, but only use
264: * it with care since the extra memory used may bog down systems under
265: * high load.
266: *
267: * @param attribName the name of the attribute to set
268: * @param attribValue a <code>Serializable</code> java object.
269: * @throws IllegalArgumentException If there is an error storing the cookie
270: * to the session.
271: * @see java.io.Serializable
272: */
273: public void setPersistentAttribute(String attribName,
274: Object attribValue) {
275: if (attribValue == null) {
276: throw new IllegalArgumentException("Value must not be null");
277: }
278:
279: if (attribValue instanceof String) {
280: attribValue = new SerializableString((String) attribValue);
281: }
282:
283: if (attribValue instanceof Serializable) {
284: try {
285: GenericSession.setAttribute(request, attribName,
286: (Serializable) attribValue);
287: } catch (ServletException se) {
288: log.error(se);
289: throw new IllegalArgumentException(
290: "Unable to store value in session:"
291: + se.getMessage());
292: }
293: } else {
294: throw new IllegalArgumentException(
295: "Attribute value object must be serializable. '"
296: + attribValue.getClass().getName()
297: + "' is not serializable.");
298: }
299: }
300:
301: /**
302: * Retrieves the object from the session context.
303: *
304: * @param attribName the name of the object to retrieve
305: * @return the object or null if it doesn't exist.
306: */
307: public Object getPersistentAttribute(String attribName) {
308: try {
309: return GenericSession.getAttribute(request, attribName);
310: } catch (ServletException se) {
311: log.error(se);
312:
313: return null;
314: }
315: }
316:
317: /**
318: * Set the request object so we can get to the session.
319: *
320: * @param req An HttpServletRequest object.
321: */
322: public void setRequest(HttpServletRequest req) {
323: request = req;
324: }
325:
326: /**
327: * Set the response object so we can get to all the http objects we need.
328: *
329: * @param res A HttpServletResponse object
330: */
331: public void setResponse(HttpServletResponse res) {
332: response = res;
333: }
334:
335: /**
336: * Clear out the session. Invalidates the entire session.
337: */
338: public void invalidate() {
339: try {
340: GenericSession.invalidate(request);
341: } catch (ServletException ce) {
342: log.error(ce);
343: }
344:
345: request = null;
346: }
347:
348: /**
349: * Clears an attribute from the request context
350: *
351: * @param attribName the name of the attribute to remove.
352: */
353: public void removeAttribute(String attribName) {
354: request.removeAttribute(attribName);
355: }
356:
357: /**
358: * Clears an attribute from the session context
359: *
360: * @param attribName the name of the attribute to remove.
361: */
362: public void removePersistentAttribute(String attribName) {
363: try {
364: GenericSession.removeAttribute(request, attribName);
365: } catch (ServletException se) {
366: log.error(se);
367: }
368: }
369: }
|