Project

General

Profile

1 4080 daigle
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements session utility methods
4
 *  Copyright: 2008 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 *
8
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26
27
package edu.ucsb.nceas.metacat.service;
28
29 5041 daigle
import java.io.PrintWriter;
30
import java.util.Calendar;
31 5311 daigle
import java.util.Enumeration;
32 4080 daigle
import java.util.Hashtable;
33
34 5041 daigle
import javax.servlet.http.HttpServletResponse;
35
36 4080 daigle
import org.apache.log4j.Logger;
37
38 5041 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
39 5015 daigle
import edu.ucsb.nceas.metacat.shared.BaseService;
40
import edu.ucsb.nceas.metacat.shared.ServiceException;
41 4080 daigle
import edu.ucsb.nceas.metacat.util.SessionData;
42 5041 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
43 4080 daigle
44 4442 daigle
public class SessionService extends BaseService {
45 4080 daigle
46
	private static SessionService sessionService = null;
47 5041 daigle
	private static int sessionTimeoutMinutes;
48 4080 daigle
49
	private static Logger logMetacat = Logger.getLogger(SessionService.class);
50
	private static Hashtable<String, SessionData> sessionHash = null;
51
52 4297 daigle
	private static final String PUBLIC_SESSION_ID = "0";
53 5311 daigle
54
	private static Object lockObj = new Object();
55 4080 daigle
56
	/**
57
	 * private constructor since this is a singleton
58
	 */
59 5015 daigle
	private SessionService() throws ServiceException {
60
		_serviceName = "SessionService";
61
62 5041 daigle
		String sessionTimeoutStr = null;
63
		try {
64
			sessionHash = new Hashtable<String, SessionData>();
65
			sessionTimeoutStr = PropertyService.getProperty("session.timeoutMinutes");
66
			sessionTimeoutMinutes = Integer.parseInt(sessionTimeoutStr);
67
68
			logMetacat.debug("SessionService() - Registering public session id: " +
69
					PUBLIC_SESSION_ID);
70 5070 daigle
			registerSession(PUBLIC_SESSION_ID, "public", null, null, "Public User");
71 5041 daigle
		} catch (PropertyNotFoundException pnfe) {
72
			throw new ServiceException("SessionService() - Error getting property: " +
73
					pnfe.getMessage());
74
		} catch (NumberFormatException nfe) {
75
			throw new ServiceException("SessionService() - Error parsing session timeout minutes: " +
76
					sessionTimeoutStr);
77
		}
78 4080 daigle
	}
79
80
	/**
81 4429 daigle
	 * Get the single instance of SessionService.
82 4080 daigle
	 *
83 4429 daigle
	 * @return the single instance of SessionService
84 4080 daigle
	 */
85 4780 daigle
	public static SessionService getInstance() throws ServiceException {
86 4080 daigle
		if (sessionService == null) {
87
			sessionService = new SessionService();
88
		}
89
		return sessionService;
90
	}
91 4297 daigle
92 4442 daigle
	public boolean refreshable() {
93
		return false;
94
	}
95
96 4981 daigle
	public void doRefresh() throws ServiceException {
97 4442 daigle
		return;
98
	}
99
100 4981 daigle
	public void stop() throws ServiceException {
101
		return;
102
	}
103
104 4297 daigle
	/**
105
	 * Register a session in the session hash table.  This uses
106
	 * the parameters passed in to create a SessionData object.
107
	 *
108
	 * @param sessionId
109
	 *            the ID of the session to register
110
	 * @param userName
111
	 *            the user name of the session
112
	 * @param groupNames
113
	 *            the group names for the session
114
	 * @param password
115
	 *            the password for the session
116
	 */
117 4080 daigle
	public static void registerSession(String sessionId, String userName,
118 5070 daigle
			String[] groupNames, String password, String name) throws ServiceException {
119 5311 daigle
		synchronized(lockObj) {
120
			if (sessionId == null) {
121
				throw new ServiceException("SessionService.registerSession - " +
122
						"Cannot register a null session id");
123
			}
124
			logMetacat.debug("SessionService.registerSession - Registering session id: " + sessionId);
125
			SessionData sessionData = new SessionData(sessionId, userName, groupNames,
126
					password, name);
127
			sessionHash.put(sessionId, sessionData);
128 4780 daigle
		}
129 4080 daigle
	}
130
131 4297 daigle
	/**
132
	 * Register a session in the session hash table.
133
	 *
134
	 * @param sessionData
135
	 *            the session data object to add to the session hash
136
	 */
137 4780 daigle
	public static void registerSession(SessionData sessionData) throws ServiceException {
138 5311 daigle
		synchronized(lockObj) {
139
			if (sessionData == null) {
140
				throw new ServiceException("SessionService.registerSession - " +
141
						"Cannot register null session data");
142
			}
143
			logMetacat.debug("SessionService.registerSession - Registering session " +
144
					"data with id: " + sessionData.getId());
145
			sessionHash.put(sessionData.getId(), sessionData);
146 4780 daigle
		}
147 4080 daigle
	}
148
149 4297 daigle
	/**
150
	 * Unregister a session from the session hash table.
151
	 *
152
	 * @param sessionId
153
	 *            the id of the session to remove.
154
	 */
155 4080 daigle
	public static void unRegisterSession(String sessionId) {
156 5311 daigle
		synchronized(lockObj) {
157
			if (sessionId == null) {
158
				logMetacat.error("SessionService.unRegisterSession - trying to " +
159 5041 daigle
					"unregister a session with null id");
160 5311 daigle
			}
161
162
			logMetacat.info("SessionService.unRegisterSession - unRegistering session: " + sessionId);
163
			sessionHash.remove(sessionId);
164 4780 daigle
		}
165 4080 daigle
	}
166
167 4297 daigle
	/**
168 5311 daigle
	 * Unregister all sessions from the session hash table except the public session.
169
	 *
170
	 * @param sessionId
171
	 *            the id of the session to remove.
172
	 */
173
	public static void unRegisterAllSessions() {
174
		synchronized(lockObj) {
175
			Enumeration<String> keyEnum = sessionHash.keys();
176
			while (keyEnum.hasMoreElements()) {
177
				String sessionId = keyEnum.nextElement();
178
				if (!sessionId.equals(PUBLIC_SESSION_ID)) {
179
					logMetacat.info("SessionService.unRegisterAllSessions - unRegistering session: " + sessionId);
180
					sessionHash.remove(sessionId);
181
				}
182
			}
183
		}
184
	}
185
186
	/**
187 4297 daigle
	 * Check if a session is registered in the session hash table.
188
	 *
189
	 * @param sessionId
190
	 *            the id of the session to look for.
191
	 */
192 5041 daigle
	public static boolean isSessionRegistered(String sessionId) {
193 4780 daigle
		if (sessionId == null) {
194 5041 daigle
			logMetacat.error("SessionService.isSessionRegistered - trying to check if a " +
195
					"session with null id is registered");
196 4780 daigle
			return false;
197
		}
198 5041 daigle
199
		checkTimeout(sessionId);
200
201 4080 daigle
		return sessionHash.containsKey(sessionId);
202
	}
203
204 4297 daigle
	/**
205 5041 daigle
	 * Check if a session is registered in the session hash table. Write results
206
	 * in XML format to output.
207
	 *
208
	 * @param out
209
	 *            the output stream to write to.
210
	 * @param sessionId
211
	 *            the id of the session to look for.
212
	 */
213
	public static void validateSession(PrintWriter out, HttpServletResponse response,
214
			String sessionId) {
215
216
		response.setContentType("text/xml");
217
		out.println("<?xml version=\"1.0\"?>");
218
		out.write("<validateSession><status>");
219 5070 daigle
		if (validateSession(sessionId)) {
220 5041 daigle
			out.write("valid");
221
		} else {
222
			out.write("invalid");
223
		}
224
		out.write("</status>");
225
		out.write("<sessionId>" + sessionId + "</sessionId></validateSession>");
226
	}
227
228
	/**
229 5070 daigle
	 * Check if a session is registered in the session hash table. Return
230
	 * true if the session is valid and false otherwise.
231
	 *
232
	 * @param sessionId
233
	 *            the id of the session to look for.
234
	 */
235
	public static boolean validateSession(String sessionId) {
236
		if (sessionId != null && !sessionId.equals(PUBLIC_SESSION_ID) && isSessionRegistered(sessionId)) {
237
			return true;
238
		} else {
239
			return false;
240
		}
241
	}
242
243
	/**
244 4297 daigle
	 * Get a registered session from the session hash table.
245
	 * TODO MCD need to time sessions out
246
	 *
247
	 * @param sessionId
248
	 *            the id of the session to retrieve.
249
	 */
250 4080 daigle
	public static SessionData getRegisteredSession(String sessionId) {
251 4780 daigle
		if (sessionId == null) {
252 5041 daigle
			logMetacat.error("SessionService.getRegisteredSession - trying to get a session with null id");
253 4780 daigle
			return null;
254
		}
255 5041 daigle
		checkTimeout(sessionId);
256
257 4080 daigle
		return sessionHash.get(sessionId);
258
	}
259
260 4297 daigle
	/**
261
	 * Get the public session from the session hash table.
262
	 */
263
	public static SessionData getPublicSession() {
264
		return sessionHash.get(PUBLIC_SESSION_ID);
265 4080 daigle
	}
266
267 4297 daigle
	/**
268
	 * Keep a session active by updating its last accessed time.
269
	 *
270
	 * @param sessionId
271
	 *            the id of the session to update.
272
	 */
273 4080 daigle
	public static synchronized void touchSession(String sessionId) {
274 4780 daigle
		if (sessionId == null) {
275 5041 daigle
			logMetacat.error("SessionService.touchSession - trying to touch a session with null id");
276 4780 daigle
		} else if (isSessionRegistered(sessionId)) {
277 5311 daigle
			synchronized(lockObj) {
278
				SessionData sessionData = getRegisteredSession(sessionId);
279
				sessionData.setLastAccessedTime();
280
			}
281 4080 daigle
		}
282
	}
283 5041 daigle
284
	private static void checkTimeout (String sessionId) {
285
		SessionData sessionData = null;
286
		if ((sessionData = sessionHash.get(sessionId)) != null) {
287
			Calendar expireTime = Calendar.getInstance();
288
			Calendar lastAccessedTime = sessionData.getLastAccessedTime();
289
			expireTime.add(Calendar.MINUTE, 0 - sessionTimeoutMinutes);
290
			if(lastAccessedTime.compareTo(expireTime) < 0 ) {
291
				unRegisterSession(sessionId);
292
			}
293 5311 daigle
		}
294 5041 daigle
	}
295 4080 daigle
296
}