Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements administrative 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: leinfelder $'
9
 *     '$Date: 2011-02-04 06:17:53 -0800 (Fri, 04 Feb 2011) $'
10
 * '$Revision: 5914 $'
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.util;
28

    
29
import java.io.InputStream;
30
import java.io.InputStreamReader;
31
import java.io.IOException;
32
import java.io.BufferedReader;
33
import java.io.PrintWriter;
34
import java.net.MalformedURLException;
35
import java.net.URL;
36
import java.net.URLConnection;
37
import java.util.ArrayList;
38
import java.util.Enumeration;
39
import java.util.HashMap;
40
import java.util.Hashtable;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.Set;
44
import java.util.Vector;
45

    
46
import javax.servlet.ServletContext;
47
import javax.servlet.ServletException;
48
import javax.servlet.http.Cookie;
49
import javax.servlet.http.HttpServletRequest;
50
import javax.servlet.http.HttpServletResponse;
51
import javax.servlet.http.HttpSession;
52

    
53
import org.apache.commons.io.IOUtils;
54
import org.apache.http.HttpException;
55
import org.apache.http.HttpResponse;
56
import org.apache.http.HttpVersion;
57
import org.apache.http.NameValuePair;
58
import org.apache.http.client.HttpClient;
59
import org.apache.http.client.entity.UrlEncodedFormEntity;
60
import org.apache.http.client.methods.HttpPost;
61
import org.apache.http.impl.client.DefaultHttpClient;
62
import org.apache.http.message.BasicNameValuePair;
63
import org.apache.http.params.CoreProtocolPNames;
64
import org.apache.log4j.Logger;
65

    
66
import edu.ucsb.nceas.metacat.properties.PropertyService;
67
import edu.ucsb.nceas.metacat.service.SessionService;
68
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
69
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
70

    
71
public class RequestUtil {
72
	
73
	private static Logger logMetacat = Logger.getLogger(RequestUtil.class);
74
	private static String encoding = "UTF-8";
75
	
76
	/**
77
	 * private constructor - all methods are static so there is no
78
     * no need to instantiate.
79
	 */
80
	private RequestUtil() {}
81
	
82
	/**
83
	 * Forward a request that was received by this servlet on to another JSP
84
	 * page or servlet to continue handling the request.
85
	 * 
86
	 * @param request
87
	 *            to be forwarded
88
	 * @param response
89
	 *            that can be used for writing output to the client
90
	 * @param destination
91
	 *            the context-relative URL to which the request is forwarded
92
	 * @param params the request parameters.  these will be added to the request
93
	 */
94
	public static void forwardRequest(HttpServletRequest request, HttpServletResponse response, 
95
			String destinationUrl, Hashtable<String, String[]> params) throws MetacatUtilException {
96

    
97
		destinationUrl += "?" + paramsToQuery(params);
98
		
99
		logMetacat.debug("Forwarding request to " + destinationUrl);
100
		ServletContext servletContext = request.getSession()
101
				.getServletContext();
102

    
103
		try {
104
			servletContext.getRequestDispatcher(destinationUrl).forward(request, response);
105
		}  catch (IOException ioe) {
106
			throw new MetacatUtilException("RequestUtil.forwardRequest - I/O error when forwarding to " + 
107
					destinationUrl + " : " + ioe.getMessage());			
108
		} catch (ServletException se) {
109
			throw new MetacatUtilException("RequestUtil.forwardRequest - Servlet error when forwarding to " + 
110
					destinationUrl + " : " + se.getMessage());			
111
		}
112
	}
113
	
114
	/**
115
	 * Forward a request that was received by this servlet on to another JSP
116
	 * page or servlet to continue handling the request.  In this case, the page
117
	 * must be referenced in a paramter named "forwardto".  If the qformat is 
118
	 * provided, the file will be retrieved from that skin.  Otherwise, the file 
119
	 * will be retrieved from the system default skin.
120
	 * 
121
	 * For more specific file location, use: forwardRequest(request,response, destinationUrl, params)
122
	 * 
123
	 * @param request
124
	 *            to be forwarded
125
	 * @param response
126
	 *            that can be used for writing output to the client
127
	 * @param params
128
	 *            the request parameters.  these will be added to the request.
129
	 */
130
	public static void forwardRequest(HttpServletRequest request, HttpServletResponse response, 
131
			Hashtable<String, String[]> params) throws MetacatUtilException {
132

    
133
		String forwardTos[] = params.get("forwardto");
134
		if (forwardTos == null || forwardTos[0].equals("")) {
135
			throw new MetacatUtilException("RequestUtil.forwardRequest - forwardto must be set in parameters when forwarding.");			
136
		}
137
		
138
		String forwardTo = forwardTos[0];
139
		String qformat = null;
140
		
141
		String qformats[] = params.get("qformat");
142
		if (qformats == null || qformats.length == 0) {
143
			try {
144
				qformat = PropertyService.getProperty("application.default-style");
145
			} catch (PropertyNotFoundException pnfe) {
146
				qformat = "default";
147
				logMetacat.warn("RequestUtil.forwardRequest - could not get property " + 
148
						"'application.default-style'. Using 'default'");
149
			}
150
		} else {
151
			qformat = qformats[0];
152
		}
153
		
154
		String destinationUrl = "/style/skins/" + qformat + "/" + forwardTo;
155
		destinationUrl += "?" + paramsToQuery(params);
156
		
157
		logMetacat.debug("RequestUtil.forwardRequest - Forwarding request to " + destinationUrl);
158
		ServletContext servletContext = request.getSession()
159
				.getServletContext();
160
		try {
161
			servletContext.getRequestDispatcher(destinationUrl).forward(request, response);
162
		} catch (IOException ioe) {
163
			throw new MetacatUtilException("RequestUtil.forwardRequest - I/O error when forwarding to " + 
164
					destinationUrl + " : " + ioe.getMessage());			
165
		} catch (ServletException se) {
166
			throw new MetacatUtilException("RequestUtil.forwardRequest - Servlet error when forwarding to " + 
167
					destinationUrl + " : " + se.getMessage());			
168
		}
169
	}
170
	
171

    
172

    
173
	/**
174
	 * Post a request and return the response body
175
	 * 
176
	 * @param httpClient
177
	 *            The HttpClient to use in the post.  This is passed in because
178
     * 			  the same client may be used in several posts
179
	 * @param url
180
	 *            the url to post to
181
	 * @param paramMap
182
	 *            map of parameters to add to the post
183
	 * @returns a string holding the response body
184
	 */
185
	public static String post(HttpClient httpclient, String url,
186
			HashMap<String, String> paramMap) throws IOException, HttpException {
187

    
188
        httpclient.getParams().setParameter(
189
        		CoreProtocolPNames.PROTOCOL_VERSION, 
190
        	    HttpVersion.HTTP_1_1);
191
    	httpclient.getParams().setParameter(
192
    			CoreProtocolPNames.HTTP_CONTENT_CHARSET, 
193
    			encoding );
194
        HttpPost post = new HttpPost(url);
195
        //set the params
196
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
197
        Iterator<String> keys = paramMap.keySet().iterator();
198
        while (keys.hasNext()) {
199
        	String key = keys.next();
200
        	String value = paramMap.get(key);
201
        	NameValuePair nvp = new BasicNameValuePair(key, value);
202
        	nameValuePairs.add(nvp);
203
        }
204
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs, encoding));
205
        //post.setHeader("Cookie", "JSESSIONID="+ sessionId);
206
        HttpResponse httpResponse = httpclient.execute(post);
207
        if (httpResponse.getStatusLine().getStatusCode() != -1) {
208
            InputStream result = httpResponse.getEntity().getContent();
209
            String contents = IOUtils.toString(result, encoding);
210
            return contents;
211
        }
212
        
213
		return null;
214
	}
215
	
216
	public static String get(String urlString, Hashtable<String, String[]> params)  throws MetacatUtilException {	
217
		try {
218
			URL url = new URL(urlString);
219
			URLConnection urlConn = url.openConnection();
220
			
221
			urlConn.setDoOutput(true);
222
			
223
			PrintWriter pw = new PrintWriter(urlConn.getOutputStream());
224
			String queryString = paramsToQuery(params);
225
			logMetacat.debug("Sending get request: " + urlString + "?" + queryString);
226
			pw.print(queryString);
227
			pw.close();
228
			
229
			// get the input from the request
230
			BufferedReader in = 
231
				new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
232
			
233
			StringBuffer sb = new StringBuffer();
234
			String line;
235
			while ((line = in.readLine()) != null) {
236
				sb.append(line);
237
			}
238
			in.close();
239
			
240
			return sb.toString();
241
		} catch (MalformedURLException mue) {
242
			throw new MetacatUtilException("URL error when contacting: " + urlString + " : " + mue.getMessage());
243
		} catch (IOException ioe) {
244
			throw new MetacatUtilException("I/O error when contacting: " + urlString + " : " + ioe.getMessage());
245
		} 
246
	}
247
	
248
	/**
249
	 * Get a cookie from a request by the cookie name
250
	 * 
251
	 * @param request
252
	 *            the request from which to get the cookie
253
	 * @param cookieName
254
	 *            the name of the cookie to look for
255
	 */
256
	public static Cookie getCookie(HttpServletRequest request, String cookieName)  {
257
		Cookie sessionCookies[] = request.getCookies();
258

    
259
		if (sessionCookies == null) {
260
			return null;
261
		}
262
		
263
		for (int i = 0; i < sessionCookies.length; i++) {
264
			if(sessionCookies[i].getName().equals(cookieName)) {
265
				return sessionCookies[i];
266
			}
267
		}	
268
		
269
		return null;
270
	}
271
	
272
	/**
273
	 * Get the session data from a request. The Scenarios we can run across
274
	 * here: 
275
	 * -- the session id parameter was set in the request parameters 
276
	 * -- request.getSession returns a new session. There is a chance that the
277
	 *    session id was set in a cookie. Check for a JSESSIONID cookie and use
278
	 *    that id if provided. 
279
	 * -- request.getSession returns a session that is a)
280
	 *    preexisting or b) new but without a JSESSIONID cookie. Use the session id
281
	 *    from this session
282
	 * 
283
	 * @param request
284
	 *            the request from which to get the session data
285
	 * @return the session data object representing the active session for this
286
	 *         request. If there is no active session, the public session data
287
	 *         is returned
288
	 */
289
	public static SessionData getSessionData(HttpServletRequest request) {
290
		SessionData sessionData = null;
291
		String sessionId = null;
292

    
293
		Hashtable<String, String[]> params = getParameters(request);
294

    
295
		if (params.containsKey("sessionid")) {
296
			// the session id is specified in the request parameters
297
			sessionId = ((String[]) params.get("sessionid"))[0];
298
			logMetacat.debug("session ID provided in request properties: " + sessionId);
299
		} else {
300
			HttpSession session = request.getSession(true);
301
			if (session.isNew()) {
302
				// this is a new session
303
				Cookie sessionCookie = RequestUtil.getCookie(request, "JSESSIONID");
304
				if (sessionCookie != null) {
305
					// and there is a JSESSIONID cookie
306
					sessionId = sessionCookie.getValue();
307
					logMetacat.debug("session ID provided in request cookie: "
308
							+ sessionId);
309
				}
310
			}
311
			if (sessionId == null) {
312
				// there is an existing session (session is old)
313
				sessionId = session.getId();
314
				logMetacat.debug("session ID retrieved from request: " + sessionId);
315
			}
316
		}
317

    
318
		// if the session id is registered in SessionService, get the
319
		// SessionData for it. Otherwise, use the public session.
320
		if (SessionService.getInstance().isSessionRegistered(sessionId)) {
321
			logMetacat.debug("retrieving session data from session service "
322
					+ "for session id " + sessionId);
323
			sessionData = SessionService.getInstance().getRegisteredSession(sessionId);
324
		} else {
325
			logMetacat.debug("using public session.  Given session id is "
326
					+ "registered: " + sessionId);
327
			sessionData = SessionService.getInstance().getPublicSession();
328
		}
329
		
330
		return sessionData;
331
	}
332

    
333
	/**
334
	 * Get a cookie from a request by the cookie name
335
	 * 
336
	 * @param request
337
	 *            the request from which to get the cookie
338
	 * @param cookieName
339
	 *            the name of the cookie to look for
340
	 */
341
	@SuppressWarnings("unchecked")
342
	public static Hashtable<String, String[]> getParameters(HttpServletRequest request)  {
343
		Hashtable<String, String[]> params = new Hashtable<String, String[]>();
344
		
345
		Enumeration<String> paramlist = (Enumeration<String>)request.getParameterNames();
346
		while (paramlist.hasMoreElements()) {
347
			String name = (String) paramlist.nextElement();
348
			String[] value = request.getParameterValues(name);
349
			params.put(name, value);
350
		}
351
		
352
		return params;
353
	}
354
	
355
	/**
356
	 * Add a list of errors to the request. The pages will pick up the errors
357
	 * and display them where appropriate.
358
	 * 
359
	 * @param request
360
	 *            the request that will get forwarded
361
	 * @param errorVector
362
	 *            a list of error strings
363
	 */
364
	public static void setRequestErrors(HttpServletRequest request,
365
			Vector<String> errorVector) {
366
		request.setAttribute("formErrors", "true");
367
		request.setAttribute("processingErrors", errorVector);
368
	}
369
	
370
	/**
371
	 * Add a list of form errors to the request. The pages will pick up the
372
	 * errors and display them where appropriate.
373
	 * 
374
	 * @param request
375
	 *            the request that will get forwarded
376
	 * @param errorVector
377
	 *            a list of form error strings
378
	 */
379
	public static void setRequestFormErrors(HttpServletRequest request,
380
			Vector<String> errorVector) {
381
		request.setAttribute("formErrors", "true");
382
		request.setAttribute("formFieldErrors", errorVector);
383
	}
384
	
385
	/**
386
	 * Add a list of success messages to the request. The pages will pick up the
387
	 * messages and display them where appropriate.
388
	 * 
389
	 * @param request
390
	 *            the request that will get forwarded
391
	 * @param errorVector
392
	 *            a list of success message strings
393
	 */
394
	public static void setRequestSuccess(HttpServletRequest request,
395
			Vector<String> successVector) {
396
		request.setAttribute("formSuccess", "true");
397
		request.setAttribute("processingSuccess", successVector);
398
	}
399
	
400
	/**
401
	 * Add a list of general messages to the request. The pages will pick up the
402
	 * messages and display them where appropriate.
403
	 * 
404
	 * @param request
405
	 *            the request that will get forwarded
406
	 * @param errorVector
407
	 *            a list of general message strings
408
	 */
409
	public static void setRequestMessage(HttpServletRequest request,
410
			Vector<String> messageVector) {
411
		request.setAttribute("formMessage", "true");
412
		request.setAttribute("processingMessage", messageVector);
413
	}
414
	
415
	/**
416
	 * Add a list of general messages to the request. The pages will pick up the
417
	 * messages and display them where appropriate.
418
	 * 
419
	 * @param request
420
	 *            the request that will get forwarded
421
	 * @param errorVector
422
	 *            a list of general message strings
423
	 */
424
	public static void clearRequestMessages(HttpServletRequest request) {
425
		request.setAttribute("formMessage", null);
426
		request.setAttribute("formSuccess", null);
427
		request.setAttribute("formErrors", null);
428
		request.setAttribute("processingMessage", null);
429
		request.setAttribute("processingSuccess", null);
430
		request.setAttribute("formFieldErrors", null);
431
		request.setAttribute("processingErrors", null);
432
	}
433
	
434
	/**
435
	 * Add the user's login id to the session on this request
436
	 * 
437
	 * @param request
438
	 *            the request that will get forwarded
439
	 * @param userId
440
	 *            the user's login id
441
	 */
442
	public static void setUserId(HttpServletRequest request, String userId) {
443
		request.getSession().setAttribute("userId", userId);
444
	}
445
	
446
	private static String paramsToQuery(Hashtable<String, String[]> params) {
447
		String query = "";
448
		if (params != null) {
449
			boolean firstParam = true;
450
			for (String paramName : params.keySet()) {
451
				if (firstParam) {
452
					firstParam = false;
453
				} else {
454
					query += "&";
455
				}
456
				query += paramName + "=" + params.get(paramName)[0];
457
			}
458
		}
459
		
460
		return query;
461
	}
462
	
463

    
464
}
(11-11/15)