KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > app > webui > util > UIUtil


1 /*
2  * UIUtil.java
3  *
4  * Version: $Revision: 1.21 $
5  *
6  * Date: $Date: 2006/11/28 14:46:56 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.app.webui.util;
41
42 import java.io.PrintWriter JavaDoc;
43 import java.io.StringWriter JavaDoc;
44 import java.sql.SQLException JavaDoc;
45 import java.util.Date JavaDoc;
46 import java.util.Enumeration JavaDoc;
47 import java.net.URLEncoder JavaDoc;
48
49 import javax.servlet.http.HttpServletRequest JavaDoc;
50 import javax.servlet.http.HttpSession JavaDoc;
51
52 import org.apache.log4j.Logger;
53 import org.dspace.content.Collection;
54 import org.dspace.content.Community;
55 import org.dspace.content.DCDate;
56 import org.dspace.core.ConfigurationManager;
57 import org.dspace.core.Constants;
58 import org.dspace.core.Context;
59 import org.dspace.core.Email;
60 import org.dspace.eperson.EPerson;
61 import org.dspace.eperson.AuthenticationManager;
62
63 /**
64  * Miscellaneous UI utility methods
65  *
66  * @author Robert Tansley
67  * @version $Revision: 1.21 $
68  */

69 public class UIUtil
70 {
71     /** log4j category */
72     private static Logger log = Logger.getLogger(UIUtil.class);
73
74     /**
75      * Obtain a new context object. If a context object has already been created
76      * for this HTTP request, it is re-used, otherwise it is created. If a user
77      * has authenticated with the system, the current user of the context is set
78      * appropriately.
79      *
80      * @param request
81      * the HTTP request
82      *
83      * @return a context object
84      */

85     public static Context obtainContext(HttpServletRequest JavaDoc request)
86             throws SQLException JavaDoc
87     {
88         
89         //Set encoding to UTF-8, if not set yet
90
//This avoids problems of using the HttpServletRequest
91
//in the getSpecialGroups() for an AuthenticationMethod,
92
//which causes the HttpServletRequest to default to
93
//non-UTF-8 encoding.
94
try
95         {
96             if(request.getCharacterEncoding()==null)
97                 request.setCharacterEncoding(Constants.DEFAULT_ENCODING);
98         }
99         catch(Exception JavaDoc e)
100         {
101             log.error("Unable to set encoding to UTF-8.", e);
102         }
103         
104         Context c = (Context) request.getAttribute("dspace.context");
105
106         if (c == null)
107         {
108             // No context for this request yet
109
c = new Context();
110
111             // See if a user has authentication
112
HttpSession JavaDoc session = request.getSession();
113             Integer JavaDoc userID = (Integer JavaDoc) session.getAttribute(
114                     "dspace.current.user.id");
115
116             if (userID != null)
117             {
118                 String JavaDoc remAddr = (String JavaDoc)session.getAttribute("dspace.current.remote.addr");
119                 if (remAddr != null && remAddr.equals(request.getRemoteAddr()))
120                 {
121                 EPerson e = EPerson.find(c, userID.intValue());
122
123                 Authenticate.loggedIn(c, request, e);
124             }
125                 else
126                 {
127                     log.warn("POSSIBLE HIJACKED SESSION: request from "+
128                              request.getRemoteAddr()+" does not match original "+
129                              "session address: "+remAddr+". Authentication rejected.");
130                 }
131             }
132
133             // Set any special groups - invoke the authentication mgr.
134
int[] groupIDs = AuthenticationManager.getSpecialGroups(c, request);
135
136             for (int i = 0; i < groupIDs.length; i++)
137             {
138                 c.setSpecialGroup(groupIDs[i]);
139                 log.debug("Adding Special Group id="+String.valueOf(groupIDs[i]));
140             }
141
142             // Set the session ID and IP address
143
c.setExtraLogInfo("session_id=" + request.getSession().getId() + ":ip_addr=" + request.getRemoteAddr());
144
145             // Store the context in the request
146
request.setAttribute("dspace.context", c);
147         }
148
149         return c;
150     }
151
152     /**
153      * Get the current community location, that is, where the user "is". This
154      * returns <code>null</code> if there is no location, i.e. "all of DSpace"
155      * is the location.
156      *
157      * @param request
158      * current HTTP request
159      *
160      * @return the current community location, or null
161      */

162     public static Community getCommunityLocation(HttpServletRequest JavaDoc request)
163     {
164         return ((Community) request.getAttribute("dspace.community"));
165     }
166
167     /**
168      * Get the current collection location, that is, where the user "is". This
169      * returns null if there is no collection location, i.e. the location is
170      * "all of DSpace" or a community.
171      *
172      * @param request
173      * current HTTP request
174      *
175      * @return the current collection location, or null
176      */

177     public static Collection getCollectionLocation(HttpServletRequest JavaDoc request)
178     {
179         return ((Collection) request.getAttribute("dspace.collection"));
180     }
181
182     /**
183      * Put the original request URL into the request object as an attribute for
184      * later use. This is necessary because forwarding a request removes this
185      * information. The attribute is only written if it hasn't been before; thus
186      * it can be called after a forward safely.
187      *
188      * @param request
189      * the HTTP request
190      */

191     public static void storeOriginalURL(HttpServletRequest JavaDoc request)
192     {
193         String JavaDoc orig = (String JavaDoc) request.getAttribute("dspace.original.url");
194
195         if (orig == null)
196         {
197             String JavaDoc fullURL = request.getRequestURL().toString();
198
199             if (request.getQueryString() != null)
200             {
201                 fullURL = fullURL + "?" + request.getQueryString();
202             }
203
204             request.setAttribute("dspace.original.url", fullURL);
205         }
206     }
207
208     /**
209      * Get the original request URL.
210      *
211      * @param request
212      * the HTTP request
213      *
214      * @return the original request URL
215      */

216     public static String JavaDoc getOriginalURL(HttpServletRequest JavaDoc request)
217     {
218         // Make sure there's a URL in the attribute
219
storeOriginalURL(request);
220
221         return ((String JavaDoc) request.getAttribute("dspace.original.url"));
222     }
223
224     /**
225      * Utility method to convert spaces in a string to HTML non-break space
226      * elements.
227      *
228      * @param s
229      * string to change spaces in
230      * @return the string passed in with spaces converted to HTML non-break
231      * spaces
232      */

233     public static String JavaDoc nonBreakSpace(String JavaDoc s)
234     {
235         StringBuffer JavaDoc newString = new StringBuffer JavaDoc();
236
237         for (int i = 0; i < s.length(); i++)
238         {
239             char ch = s.charAt(i);
240
241             if (ch == ' ')
242             {
243                 newString.append("&nbsp;");
244             }
245             else
246             {
247                 newString.append(ch);
248             }
249         }
250
251         return newString.toString();
252     }
253
254     /**
255      * Write a human-readable version of a DCDate.
256      *
257      * @param d
258      * the date
259      * @param time
260      * if true, display the time with the date
261      * @param localTime
262      * if true, adjust for local timezone, otherwise GMT
263      *
264      * @return the date in a human-readable form.
265      */

266     public static String JavaDoc displayDate(DCDate d, boolean time, boolean localTime)
267     {
268         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
269
270         if (d != null)
271         {
272             int year;
273             int month;
274             int day;
275             int hour;
276             int minute;
277             int second;
278
279             if (localTime)
280             {
281                 year = d.getYear();
282                 month = d.getMonth();
283                 day = d.getDay();
284                 hour = d.getHour();
285                 minute = d.getMinute();
286                 second = d.getSecond();
287             }
288             else
289             {
290                 year = d.getYearGMT();
291                 month = d.getMonthGMT();
292                 day = d.getDayGMT();
293                 hour = d.getHourGMT();
294                 minute = d.getMinuteGMT();
295                 second = d.getSecondGMT();
296             }
297
298             if (year > -1)
299             {
300                 if (month > -1)
301                 {
302                     if (day > -1)
303                     {
304                         sb.append(day + "-");
305                     }
306
307                     sb.append(DCDate.getMonthName(month).substring(0, 3) + "-");
308                 }
309
310                 sb.append(year + " ");
311             }
312
313             if (time && (hour > -1))
314             {
315                 String JavaDoc hr = String.valueOf(hour);
316
317                 while (hr.length() < 2)
318                 {
319                     hr = "0" + hr;
320                 }
321
322                 String JavaDoc mn = String.valueOf(minute);
323
324                 while (mn.length() < 2)
325                 {
326                     mn = "0" + mn;
327                 }
328
329                 String JavaDoc sc = String.valueOf(second);
330
331                 while (sc.length() < 2)
332                 {
333                     sc = "0" + sc;
334                 }
335
336                 sb.append(hr + ":" + mn + ":" + sc + " ");
337             }
338         }
339         else
340         {
341             sb.append("Unset");
342         }
343
344         return (sb.toString());
345     }
346
347     /**
348      * Return a string for logging, containing useful information about the
349      * current request - the URL, the method and parameters.
350      *
351      * @param request
352      * the request object.
353      * @return a multi-line string containing information about the request.
354      */

355     public static String JavaDoc getRequestLogInfo(HttpServletRequest JavaDoc request)
356     {
357         String JavaDoc report;
358
359         report = "-- URL Was: " + getOriginalURL(request) + "\n";
360         report = report + "-- Method: " + request.getMethod() + "\n";
361
362         // First write the parameters we had
363
report = report + "-- Parameters were:\n";
364
365         Enumeration JavaDoc e = request.getParameterNames();
366
367         while (e.hasMoreElements())
368         {
369             String JavaDoc name = (String JavaDoc) e.nextElement();
370
371             if (name.equals("login_password"))
372             {
373                 // We don't want to write a clear text password
374
// to the log, even if it's wrong!
375
report = report + "-- " + name + ": *not logged*\n";
376             }
377             else
378             {
379                 report = report + "-- " + name + ": \""
380                         + request.getParameter(name) + "\"\n";
381             }
382         }
383
384         return report;
385     }
386
387     /**
388      * Obtain a parameter from the given request as an int. <code>-1</code> is
389      * returned if the parameter is garbled or does not exist.
390      *
391      * @param request
392      * the HTTP request
393      * @param param
394      * the name of the parameter
395      *
396      * @return the integer value of the parameter, or -1
397      */

398     public static int getIntParameter(HttpServletRequest JavaDoc request, String JavaDoc param)
399     {
400         String JavaDoc val = request.getParameter(param);
401
402         try
403         {
404             return Integer.parseInt(val);
405         }
406         catch (Exception JavaDoc e)
407         {
408             // Problem with parameter
409
return -1;
410         }
411     }
412
413     /**
414      * Obtain an array of int parameters from the given request as an int. null
415      * is returned if parameter doesn't exist. <code>-1</code> is returned in
416      * array locations if that particular value is garbled.
417      *
418      * @param request
419      * the HTTP request
420      * @param param
421      * the name of the parameter
422      *
423      * @return array of integers or null
424      */

425     public static int[] getIntParameters(HttpServletRequest JavaDoc request,
426             String JavaDoc param)
427     {
428         String JavaDoc[] request_values = request.getParameterValues(param);
429
430         if (request_values == null)
431         {
432             return null;
433         }
434
435         int[] return_values = new int[request_values.length];
436
437         for (int x = 0; x < return_values.length; x++)
438         {
439             try
440             {
441                 return_values[x] = Integer.parseInt(request_values[x]);
442             }
443             catch (Exception JavaDoc e)
444             {
445                 // Problem with parameter, stuff -1 in this slot
446
return_values[x] = -1;
447             }
448         }
449
450         return return_values;
451     }
452
453     /**
454      * Obtain a parameter from the given request as a boolean.
455      * <code>false</code> is returned if the parameter is garbled or does not
456      * exist.
457      *
458      * @param request
459      * the HTTP request
460      * @param param
461      * the name of the parameter
462      *
463      * @return the integer value of the parameter, or -1
464      */

465     public static boolean getBoolParameter(HttpServletRequest JavaDoc request,
466             String JavaDoc param)
467     {
468         return ((request.getParameter(param) != null) && request.getParameter(
469                 param).equals("true"));
470     }
471
472     /**
473      * Get the button the user pressed on a submitted form. All buttons should
474      * start with the text <code>submit</code> for this to work. A default
475      * should be supplied, since often the browser will submit a form with no
476      * submit button pressed if the user presses enter.
477      *
478      * @param request
479      * the HTTP request
480      * @param def
481      * the default button
482      *
483      * @return the button pressed
484      */

485     public static String JavaDoc getSubmitButton(HttpServletRequest JavaDoc request, String JavaDoc def)
486     {
487         Enumeration JavaDoc e = request.getParameterNames();
488
489         while (e.hasMoreElements())
490         {
491             String JavaDoc parameterName = (String JavaDoc) e.nextElement();
492
493             if (parameterName.startsWith("submit"))
494             {
495                 return parameterName;
496             }
497         }
498
499         return def;
500     }
501
502     /**
503      * Send an alert to the designated "alert recipient" - that is, when a
504      * database error or internal error occurs, this person is sent an e-mail
505      * with details.
506      * <P>
507      * The recipient is configured via the "alert.recipient" property in
508      * <code>dspace.cfg</code>. If this property is omitted, no alerts are
509      * sent.
510      * <P>
511      * This method "swallows" any exception that might occur - it will just be
512      * logged. This is because this method will usually be invoked as part of an
513      * error handling routine anyway.
514      *
515      * @param request
516      * the HTTP request leading to the error
517      * @param exception
518      * the exception causing the error, or null
519      */

520     public static void sendAlert(HttpServletRequest JavaDoc request, Exception JavaDoc exception)
521     {
522         String JavaDoc logInfo = UIUtil.getRequestLogInfo(request);
523
524         try
525         {
526             String JavaDoc recipient = ConfigurationManager
527                     .getProperty("alert.recipient");
528
529             if (recipient != null)
530             {
531                 Email email = ConfigurationManager.getEmail("internal_error");
532
533                 email.addRecipient(recipient);
534                 email.addArgument(ConfigurationManager
535                         .getProperty("dspace.url"));
536                 email.addArgument(new Date JavaDoc());
537                 email.addArgument(request.getSession().getId());
538                 email.addArgument(logInfo);
539
540                 String JavaDoc stackTrace;
541
542                 if (exception != null)
543                 {
544                     StringWriter JavaDoc sw = new StringWriter JavaDoc();
545                     PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
546                     exception.printStackTrace(pw);
547                     pw.flush();
548                     stackTrace = sw.toString();
549                 }
550                 else
551                 {
552                     stackTrace = "No exception";
553                 }
554
555                 email.addArgument(stackTrace);
556                 email.send();
557             }
558         }
559         catch (Exception JavaDoc e)
560         {
561             // Not much we can do here!
562
log.warn("Unable to send email alert", e);
563         }
564     }
565     
566     /**
567      * Encode a bitstream name for inclusion in a URL in an HTML document. This
568      * differs from the usual URL-encoding, since we want pathname separators to
569      * be passed through verbatim; this is required so that relative paths in
570      * bitstream names and HTML references work correctly.
571      * <P>
572      * If the link to a bitstream is generated with the pathname separators
573      * escaped (e.g. "%2F" instead of "/") then the Web user agent perceives it
574      * to be one pathname element, and relative URI paths within that document
575      * containing ".." elements will be handled incorrectly.
576      * <P>
577      *
578      * @param stringIn
579      * input string to encode
580      * @param encoding
581      * character encoding, e.g. UTF-8
582      * @return the encoded string
583      */

584     public static String JavaDoc encodeBitstreamName(String JavaDoc stringIn, String JavaDoc encoding)
585             throws java.io.UnsupportedEncodingException JavaDoc
586     {
587         // FIXME: This should be moved elsewhere, as it is used outside the UI
588
StringBuffer JavaDoc out = new StringBuffer JavaDoc();
589
590         final String JavaDoc[] pctEncoding = { "%00", "%01", "%02", "%03", "%04",
591                 "%05", "%06", "%07", "%08", "%09", "%0a", "%0b", "%0c", "%0d",
592                 "%0e", "%0f", "%10", "%11", "%12", "%13", "%14", "%15", "%16",
593                 "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f",
594                 "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27", "%28",
595                 "%29", "%2a", "%2b", "%2c", "%2d", "%2e", "%2f", "%30", "%31",
596                 "%32", "%33", "%34", "%35", "%36", "%37", "%38", "%39", "%3a",
597                 "%3b", "%3c", "%3d", "%3e", "%3f", "%40", "%41", "%42", "%43",
598                 "%44", "%45", "%46", "%47", "%48", "%49", "%4a", "%4b", "%4c",
599                 "%4d", "%4e", "%4f", "%50", "%51", "%52", "%53", "%54", "%55",
600                 "%56", "%57", "%58", "%59", "%5a", "%5b", "%5c", "%5d", "%5e",
601                 "%5f", "%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67",
602                 "%68", "%69", "%6a", "%6b", "%6c", "%6d", "%6e", "%6f", "%70",
603                 "%71", "%72", "%73", "%74", "%75", "%76", "%77", "%78", "%79",
604                 "%7a", "%7b", "%7c", "%7d", "%7e", "%7f", "%80", "%81", "%82",
605                 "%83", "%84", "%85", "%86", "%87", "%88", "%89", "%8a", "%8b",
606                 "%8c", "%8d", "%8e", "%8f", "%90", "%91", "%92", "%93", "%94",
607                 "%95", "%96", "%97", "%98", "%99", "%9a", "%9b", "%9c", "%9d",
608                 "%9e", "%9f", "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6",
609                 "%a7", "%a8", "%a9", "%aa", "%ab", "%ac", "%ad", "%ae", "%af",
610                 "%b0", "%b1", "%b2", "%b3", "%b4", "%b5", "%b6", "%b7", "%b8",
611                 "%b9", "%ba", "%bb", "%bc", "%bd", "%be", "%bf", "%c0", "%c1",
612                 "%c2", "%c3", "%c4", "%c5", "%c6", "%c7", "%c8", "%c9", "%ca",
613                 "%cb", "%cc", "%cd", "%ce", "%cf", "%d0", "%d1", "%d2", "%d3",
614                 "%d4", "%d5", "%d6", "%d7", "%d8", "%d9", "%da", "%db", "%dc",
615                 "%dd", "%de", "%df", "%e0", "%e1", "%e2", "%e3", "%e4", "%e5",
616                 "%e6", "%e7", "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee",
617                 "%ef", "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
618                 "%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff" };
619
620         byte[] bytes = stringIn.getBytes(encoding);
621
622         for (int i = 0; i < bytes.length; i++)
623         {
624             // Any unreserved char or "/" goes through unencoded
625
if ((bytes[i] >= 'A' && bytes[i] <= 'Z')
626                     || (bytes[i] >= 'a' && bytes[i] <= 'z')
627                     || (bytes[i] >= '0' && bytes[i] <= '9') || bytes[i] == '-'
628                     || bytes[i] == '.' || bytes[i] == '_' || bytes[i] == '~'
629                     || bytes[i] == '/')
630             {
631                 out.append((char) bytes[i]);
632             }
633             else if (bytes[i] >= 0)
634             {
635                 // encode other chars (byte code < 128)
636
out.append(pctEncoding[bytes[i]]);
637             }
638             else
639             {
640                 // encode other chars (byte code > 127, so it appears as
641
// negative in Java signed byte data type)
642
out.append(pctEncoding[256 + bytes[i]]);
643             }
644         }
645         log.debug("encoded \"" + stringIn + "\" to \"" + out.toString() + "\"");
646
647         return out.toString();
648     }
649
650     /** Version of encodeBitstreamName with one parameter, uses default encoding
651      * <P>
652      * @param stringIn
653      * input string to encode
654      * @return the encoded string
655      */

656      public static String JavaDoc encodeBitstreamName(String JavaDoc stringIn)
657      throws java.io.UnsupportedEncodingException JavaDoc
658      {
659         return encodeBitstreamName(stringIn, Constants.DEFAULT_ENCODING);
660      }
661 }
662
Popular Tags