001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portlet.mail.util;
022:
023: import com.liferay.portal.util.WebKeys;
024: import com.liferay.portlet.mail.util.multiaccount.MailCache;
025: import com.liferay.util.CollectionFactory;
026:
027: import java.util.Map;
028:
029: import javax.mail.Folder;
030: import javax.mail.MessagingException;
031:
032: import javax.servlet.http.HttpServletRequest;
033: import javax.servlet.http.HttpSession;
034:
035: import org.apache.commons.logging.Log;
036: import org.apache.commons.logging.LogFactory;
037:
038: /**
039: * <a href="MailSessionLock.java.html"><b><i>View Source</i></b></a>
040: *
041: * @author Alexander Chow
042: *
043: */
044: public class MailSessionLock {
045:
046: public static void cleanUp(HttpSession ses) {
047: _instance._cleanUp(ses);
048: }
049:
050: public static void lock(HttpServletRequest req) {
051: _instance._lock(req.getSession().getId());
052: }
053:
054: public static void unlock(HttpServletRequest req) {
055: _instance._unlock(req.getSession().getId());
056: }
057:
058: private MailSessionLock() {
059: }
060:
061: private void _cleanUp(HttpSession ses) {
062: try {
063:
064: // This method duplicates the same method in MailUtil because of
065: // LEP-4829.
066:
067: Folder folder = (Folder) ses
068: .getAttribute(WebKeys.MAIL_FOLDER);
069:
070: if ((folder != null) && folder.isOpen()) {
071: try {
072: folder.close(false);
073: } catch (MessagingException me) {
074: if (_log.isWarnEnabled()) {
075: _log.warn(me);
076: }
077: }
078:
079: ses.removeAttribute(WebKeys.MAIL_FOLDER);
080: }
081:
082: MailCache.clearCache(ses);
083:
084: ses.removeAttribute(WebKeys.MAIL_MESSAGE_ID);
085: } catch (Exception e) {
086: }
087:
088: synchronized (_sessionMap) {
089: _sessionMap.remove(ses.getId());
090: }
091: }
092:
093: private void _lock(String sessionId) {
094: ThreadLocal threadLocal = null;
095:
096: for (;;) {
097: synchronized (_sessionMap) {
098: threadLocal = (ThreadLocal) _sessionMap.get(sessionId);
099:
100: if (threadLocal == null) {
101:
102: // Initialize reentrant counter.
103:
104: threadLocal = new ThreadLocal();
105:
106: threadLocal.set(new Long(0));
107:
108: _sessionMap.put(sessionId, threadLocal);
109:
110: break;
111: } else if (threadLocal.get() != null) {
112:
113: // This thread instantiated the thread local. Increment the
114: // reentrant counter.
115:
116: Long count = (Long) threadLocal.get();
117:
118: threadLocal.set(new Long(count.longValue() + 1L));
119:
120: break;
121: }
122: }
123:
124: // Another thread instantiated the thread local. Wait until that
125: // thread is done.
126:
127: try {
128: wait(100);
129: } catch (Exception ex) {
130: }
131: }
132: }
133:
134: private void _unlock(String sessionId) {
135: ThreadLocal threadLocal = null;
136:
137: synchronized (_sessionMap) {
138: threadLocal = (ThreadLocal) _sessionMap.get(sessionId);
139:
140: // The variable can be null at this time if a method called unlock()
141: // twice or cleanUp() was called.
142:
143: if (threadLocal != null) {
144: Long count = (Long) threadLocal.get();
145:
146: if (count.longValue() == 0L) {
147:
148: // All reentrant calls have completed
149:
150: _sessionMap.remove(sessionId);
151: } else {
152:
153: // Finished one of the reentrant calls
154:
155: count = new Long(count.longValue() - 1L);
156:
157: threadLocal.set(count);
158: }
159: }
160: }
161: }
162:
163: private static Log _log = LogFactory.getLog(MailSessionLock.class);
164:
165: private static MailSessionLock _instance = new MailSessionLock();
166:
167: private Map _sessionMap = CollectionFactory.getHashMap();
168:
169: }
|