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 4080 daigle
import java.util.Hashtable;
32
33 5041 daigle
import javax.servlet.http.HttpServletResponse;
34
35 4080 daigle
import org.apache.log4j.Logger;
36
37 5041 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
38 5015 daigle
import edu.ucsb.nceas.metacat.shared.BaseService;
39
import edu.ucsb.nceas.metacat.shared.ServiceException;
40 4080 daigle
import edu.ucsb.nceas.metacat.util.SessionData;
41 5041 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
42 4080 daigle
43 4442 daigle
public class SessionService extends BaseService {
44 4080 daigle
45
	private static SessionService sessionService = null;
46 5041 daigle
	private static int sessionTimeoutMinutes;
47 4080 daigle
48
	private static Logger logMetacat = Logger.getLogger(SessionService.class);
49
	private static Hashtable<String, SessionData> sessionHash = null;
50
51 4297 daigle
	private static final String PUBLIC_SESSION_ID = "0";
52 4080 daigle
53
	/**
54
	 * private constructor since this is a singleton
55
	 */
56 5015 daigle
	private SessionService() throws ServiceException {
57
		_serviceName = "SessionService";
58
59 5041 daigle
		String sessionTimeoutStr = null;
60
		try {
61
			sessionHash = new Hashtable<String, SessionData>();
62
			sessionTimeoutStr = PropertyService.getProperty("session.timeoutMinutes");
63
			sessionTimeoutMinutes = Integer.parseInt(sessionTimeoutStr);
64
65
			logMetacat.debug("SessionService() - Registering public session id: " +
66
					PUBLIC_SESSION_ID);
67 5070 daigle
			registerSession(PUBLIC_SESSION_ID, "public", null, null, "Public User");
68 5041 daigle
		} catch (PropertyNotFoundException pnfe) {
69
			throw new ServiceException("SessionService() - Error getting property: " +
70
					pnfe.getMessage());
71
		} catch (NumberFormatException nfe) {
72
			throw new ServiceException("SessionService() - Error parsing session timeout minutes: " +
73
					sessionTimeoutStr);
74
		}
75 4080 daigle
	}
76
77
	/**
78 4429 daigle
	 * Get the single instance of SessionService.
79 4080 daigle
	 *
80 4429 daigle
	 * @return the single instance of SessionService
81 4080 daigle
	 */
82 4780 daigle
	public static SessionService getInstance() throws ServiceException {
83 4080 daigle
		if (sessionService == null) {
84
			sessionService = new SessionService();
85
		}
86
		return sessionService;
87
	}
88 4297 daigle
89 4442 daigle
	public boolean refreshable() {
90
		return false;
91
	}
92
93 4981 daigle
	public void doRefresh() throws ServiceException {
94 4442 daigle
		return;
95
	}
96
97 4981 daigle
	public void stop() throws ServiceException {
98
		return;
99
	}
100
101 4297 daigle
	/**
102
	 * Register a session in the session hash table.  This uses
103
	 * the parameters passed in to create a SessionData object.
104
	 *
105
	 * @param sessionId
106
	 *            the ID of the session to register
107
	 * @param userName
108
	 *            the user name of the session
109
	 * @param groupNames
110
	 *            the group names for the session
111
	 * @param password
112
	 *            the password for the session
113
	 */
114 4080 daigle
	public static void registerSession(String sessionId, String userName,
115 5070 daigle
			String[] groupNames, String password, String name) throws ServiceException {
116 4780 daigle
		if (sessionId == null) {
117 5041 daigle
			throw new ServiceException("SessionService.registerSession - " +
118
					"Cannot register a null session id");
119 4780 daigle
		}
120 5041 daigle
		logMetacat.debug("SessionService.registerSession - Registering session id: " + sessionId);
121 4080 daigle
		SessionData sessionData = new SessionData(sessionId, userName, groupNames,
122 5070 daigle
				password, name);
123 4080 daigle
		sessionHash.put(sessionId, sessionData);
124
	}
125
126 4297 daigle
	/**
127
	 * Register a session in the session hash table.
128
	 *
129
	 * @param sessionData
130
	 *            the session data object to add to the session hash
131
	 */
132 4780 daigle
	public static void registerSession(SessionData sessionData) throws ServiceException {
133
		if (sessionData == null) {
134 5041 daigle
			throw new ServiceException("SessionService.registerSession - " +
135
					"Cannot register null session data");
136 4780 daigle
		}
137 5041 daigle
		logMetacat.debug("SessionService.registerSession - Registering session " +
138
				"data with id: " + sessionData.getId());
139 4080 daigle
		sessionHash.put(sessionData.getId(), sessionData);
140
	}
141
142 4297 daigle
	/**
143
	 * Unregister a session from the session hash table.
144
	 *
145
	 * @param sessionId
146
	 *            the id of the session to remove.
147
	 */
148 4080 daigle
	public static void unRegisterSession(String sessionId) {
149 5070 daigle
		if (sessionId == null) {
150 5041 daigle
			logMetacat.error("SessionService.unRegisterSession - trying to " +
151
					"unregister a session with null id");
152 4780 daigle
		}
153 5070 daigle
154
		logMetacat.error("SessionService.unRegisterSession - unRegistering session: " + sessionId);
155
		sessionHash.remove(sessionId);
156 4080 daigle
	}
157
158 4297 daigle
	/**
159
	 * Check if a session is registered in the session hash table.
160
	 *
161
	 * @param sessionId
162
	 *            the id of the session to look for.
163
	 */
164 5041 daigle
	public static boolean isSessionRegistered(String sessionId) {
165 4780 daigle
		if (sessionId == null) {
166 5041 daigle
			logMetacat.error("SessionService.isSessionRegistered - trying to check if a " +
167
					"session with null id is registered");
168 4780 daigle
			return false;
169
		}
170 5041 daigle
171
		checkTimeout(sessionId);
172
173 4080 daigle
		return sessionHash.containsKey(sessionId);
174
	}
175
176 4297 daigle
	/**
177 5041 daigle
	 * Check if a session is registered in the session hash table. Write results
178
	 * in XML format to output.
179
	 *
180
	 * @param out
181
	 *            the output stream to write to.
182
	 * @param sessionId
183
	 *            the id of the session to look for.
184
	 */
185
	public static void validateSession(PrintWriter out, HttpServletResponse response,
186
			String sessionId) {
187
188
		response.setContentType("text/xml");
189
		out.println("<?xml version=\"1.0\"?>");
190
		out.write("<validateSession><status>");
191 5070 daigle
		if (validateSession(sessionId)) {
192 5041 daigle
			out.write("valid");
193
		} else {
194
			out.write("invalid");
195
		}
196
		out.write("</status>");
197
		out.write("<sessionId>" + sessionId + "</sessionId></validateSession>");
198
	}
199
200
	/**
201 5070 daigle
	 * Check if a session is registered in the session hash table. Return
202
	 * true if the session is valid and false otherwise.
203
	 *
204
	 * @param sessionId
205
	 *            the id of the session to look for.
206
	 */
207
	public static boolean validateSession(String sessionId) {
208
		if (sessionId != null && !sessionId.equals(PUBLIC_SESSION_ID) && isSessionRegistered(sessionId)) {
209
			return true;
210
		} else {
211
			return false;
212
		}
213
	}
214
215
	/**
216 4297 daigle
	 * Get a registered session from the session hash table.
217
	 * TODO MCD need to time sessions out
218
	 *
219
	 * @param sessionId
220
	 *            the id of the session to retrieve.
221
	 */
222 4080 daigle
	public static SessionData getRegisteredSession(String sessionId) {
223 4780 daigle
		if (sessionId == null) {
224 5041 daigle
			logMetacat.error("SessionService.getRegisteredSession - trying to get a session with null id");
225 4780 daigle
			return null;
226
		}
227 5041 daigle
		checkTimeout(sessionId);
228
229 4080 daigle
		return sessionHash.get(sessionId);
230
	}
231
232 4297 daigle
	/**
233
	 * Get the public session from the session hash table.
234
	 */
235
	public static SessionData getPublicSession() {
236
		return sessionHash.get(PUBLIC_SESSION_ID);
237 4080 daigle
	}
238
239 4297 daigle
	/**
240
	 * Keep a session active by updating its last accessed time.
241
	 *
242
	 * @param sessionId
243
	 *            the id of the session to update.
244
	 */
245 4080 daigle
	public static synchronized void touchSession(String sessionId) {
246 4780 daigle
		if (sessionId == null) {
247 5041 daigle
			logMetacat.error("SessionService.touchSession - trying to touch a session with null id");
248 4780 daigle
		} else if (isSessionRegistered(sessionId)) {
249 4080 daigle
			SessionData sessionData = getRegisteredSession(sessionId);
250
			sessionData.setLastAccessedTime();
251
		}
252
	}
253 5041 daigle
254
	private static void checkTimeout (String sessionId) {
255
		SessionData sessionData = null;
256
		if ((sessionData = sessionHash.get(sessionId)) != null) {
257
			Calendar expireTime = Calendar.getInstance();
258
			Calendar lastAccessedTime = sessionData.getLastAccessedTime();
259
			expireTime.add(Calendar.MINUTE, 0 - sessionTimeoutMinutes);
260
			if(lastAccessedTime.compareTo(expireTime) < 0 ) {
261
				unRegisterSession(sessionId);
262
			}
263
		}
264
265
266
	}
267 4080 daigle
268
}