001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixxml;
021:
022: import java.util.Timer;
023: import java.util.TimerTask;
024:
025: import javax.servlet.http.HttpSession;
026:
027: import org.apache.log4j.Logger;
028:
029: import de.schlund.pfixxml.util.CacheValueLRU;
030:
031: /**
032: * The <code>SessionCleaner</code> class is used to remove stored SPDocuments from the session
033: * after a timout. This helps in reducing the memory usage as those documents
034: * are only stored for possible reuse by following subrequests (for frames). After the timeout one should
035: * be reasonable sure that no subrequests will follow (During development, the AbstractXMLServlet
036: * should make sure to call storeSPDocument() with the <code>timeoutsec</code> parameter set to
037: * <b>a very high value</b>, to be able to get the stored SPDocument for debugging purposes).
038: *
039: * Created: Thu Mar 20 16:45:31 2003
040: *
041: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
042: * @version $Id: SessionCleaner.java 3388 2008-02-29 01:31:09Z jenstl $
043: */
044: public class SessionCleaner {
045: private static SessionCleaner instance = new SessionCleaner();
046: private Timer timer = new Timer(true);
047: private final static Logger LOG = Logger
048: .getLogger(SessionCleaner.class);
049:
050: private SessionCleaner() {
051: }
052:
053: /**
054: * @return The <code>SessionCleaner</code> singleton.
055: */
056: public static SessionCleaner getInstance() {
057: return instance;
058: }
059:
060: /**
061: * Called from the AbstractXMLServlet to store a SPDocument into the supplied SPCache structure
062: * (which in turn is stored in the HTTPSession). This will also start a TimerTask that removes
063: * the stored SPDocument after the given timeout.
064: *
065: * @param spdoc a <code>SPDocument</code> value
066: * @param storeddoms a <code>Map</code> value
067: * @param timeoutsecs a <code>int</code> value. The timeout when the document should be removed.
068: */
069: public void storeSPDocument(SPDocument spdoc,
070: CacheValueLRU<String, SPDocument> storeddoms,
071: int timeoutsecs) {
072: storeSPDocument(spdoc, null, storeddoms, timeoutsecs);
073: }
074:
075: /**
076: * Called from the AbstractXMLServlet to store a SPDocument into the supplied SPCache structure
077: * (which in turn is stored in the HTTPSession). This will also start a TimerTask that removes
078: * the stored SPDocument after the given timeout.
079: *
080: * @param spdoc a <code>SPDocument</code> value
081: * @param storeddoms a <code>Map</code> value
082: * @param timeoutsecs a <code>int</code> value. The timeout when the document should be removed.
083: */
084: public void storeSPDocument(SPDocument spdoc, String frameName,
085: CacheValueLRU<String, SPDocument> storeddoms,
086: int timeoutsecs) {
087: String key = spdoc.getTimestamp() + "";
088: if (frameName != null) {
089: key = key + "." + frameName;
090: }
091:
092: // Save the needed info
093: if (LOG.isDebugEnabled()) {
094: LOG.debug("Store SPDocument " + spdoc.getTimestamp()
095: + " under key " + key);
096: }
097: storeddoms.put(key, spdoc);
098: LOG.info("*** Create new TimerTask with timeout: "
099: + timeoutsecs);
100: TimerTask task = new SessionCleanerTask(storeddoms, key);
101: timer.schedule(task, timeoutsecs * 1000);
102:
103: }
104:
105: private class SessionCleanerTask extends TimerTask {
106: String key;
107: CacheValueLRU<String, SPDocument> storeddoms;
108:
109: public SessionCleanerTask(
110: CacheValueLRU<String, SPDocument> storeddomcache,
111: String key) {
112: this .storeddoms = storeddomcache;
113: this .key = key;
114: }
115:
116: public void run() {
117: try {
118: if (storeddoms.containsKey(key)) {
119: storeddoms.remove(key);
120: LOG
121: .info("*** CALLING TIMERTASK: Removing SPDoc Reference for '"
122: + key
123: + "' in session from cache (Curr. Size (= All keys counted!): "
124: + storeddoms.size() + ")");
125: } else {
126: LOG.info("*** CALLING TIMERTASK: nothing to do.");
127: }
128:
129: } catch (IllegalStateException e) {
130: LOG.warn("*** Couldn't remove from cache... "
131: + e.getMessage() + " ***");
132: }
133: key = null;
134: storeddoms = null;
135: }
136: }
137:
138: private class SessionInvalidateTask extends TimerTask {
139: HttpSession session;
140:
141: private SessionInvalidateTask(HttpSession session) {
142: this .session = session;
143: }
144:
145: public void run() {
146: try {
147: this .session.invalidate();
148: } catch (IllegalStateException e) {
149: // Ignore IllegalStateException
150: }
151: }
152: }
153:
154: public void invalidateSession(HttpSession session, int timeoutsecs) {
155: timer.schedule(new SessionInvalidateTask(session),
156: timeoutsecs * 1000);
157: }
158:
159: } // SessionCleaner
|