KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > boot > Util


1 /*
2  */

3 package com.sslexplorer.boot;
4
5 import java.io.BufferedReader JavaDoc;
6 import java.io.ByteArrayOutputStream JavaDoc;
7 import java.io.File JavaDoc;
8 import java.io.FileInputStream JavaDoc;
9 import java.io.FileOutputStream JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.io.InputStream JavaDoc;
12 import java.io.InputStreamReader JavaDoc;
13 import java.io.OutputStream JavaDoc;
14 import java.io.PrintWriter JavaDoc;
15 import java.io.StringReader JavaDoc;
16 import java.io.StringWriter JavaDoc;
17 import java.io.UnsupportedEncodingException JavaDoc;
18 import java.net.URL JavaDoc;
19 import java.net.URLClassLoader JavaDoc;
20 import java.net.URLDecoder JavaDoc;
21 import java.net.URLEncoder JavaDoc;
22 import java.util.Calendar JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Vector JavaDoc;
29
30 import javax.servlet.ServletContext JavaDoc;
31 import javax.servlet.http.HttpServletRequest JavaDoc;
32 import javax.servlet.http.HttpServletResponse JavaDoc;
33 import javax.servlet.http.HttpSession JavaDoc;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38 /**
39  * Utilities used throughout the SSL-Explorer boot environment, server
40  * implementation and web application.
41  *
42  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
43  */

44 public class Util {
45
46     final static Log log = LogFactory.getLog(Util.class);
47
48     /**
49      * Default buffer size for stream utility methods
50      */

51     public static int BUFFER_SIZE = 8192;
52
53     /*
54      * Prevent instantiation
55      */

56     private Util() {
57         super();
58     }
59
60     /**
61      * Get the statement from the current stack trace given its depth. I.e, a
62      * depth of 0 will return this method, a depth of 1 will return the method
63      * that called this method etc.
64      *
65      * @param depth depth
66      * @return statement as string
67      */

68     public static String JavaDoc getCurrentStatement(int depth) {
69         try {
70             throw new Exception JavaDoc();
71         } catch (Exception JavaDoc e) {
72             try {
73                 StringWriter JavaDoc sw = new StringWriter JavaDoc();
74                 e.printStackTrace(new PrintWriter JavaDoc(sw));
75                 BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new StringReader JavaDoc(sw.toString()));
76                 reader.readLine();
77                 reader.readLine();
78                 sw = new StringWriter JavaDoc();
79                 PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw, true);
80                 for (int i = 0; i < depth; i++) {
81                     String JavaDoc s = reader.readLine();
82                     pw.println(s.substring(7));
83                 }
84                 return sw.toString();
85
86             } catch (Throwable JavaDoc t) {
87                 return "Unknown.";
88             }
89         }
90     }
91
92     /**
93      * Trim spaces from both ends of string
94      *
95      * @param string string to trim
96      * @return trimmed string
97      */

98     public static String JavaDoc trimBoth(String JavaDoc string) {
99         string = string.trim();
100         for (int i = 0; i < string.length(); i++) {
101             if (string.charAt(i) != ' ') {
102                 return string.substring(i);
103             }
104         }
105         return string;
106     }
107
108     /**
109      * Close an output stream, ignoing any exceptions. No error will be thrown
110      * if the provided stream is <code>null</code>
111      *
112      * @param outputStream stream to close
113      */

114     public static void closeStream(OutputStream JavaDoc outputStream) {
115         if (outputStream != null) {
116             try {
117                 outputStream.close();
118             } catch (IOException JavaDoc ioe) {
119
120             }
121         }
122     }
123
124     /**
125      * Close an input stream, ignoing any exceptions. No error will be thrown if
126      * the provided stream is <code>null</code>
127      *
128      * @param inputStream stream to close
129      */

130     public static void closeStream(InputStream JavaDoc inputStream) {
131         if (inputStream != null) {
132             try {
133                 inputStream.close();
134             } catch (IOException JavaDoc ioe) {
135
136             }
137         }
138     }
139
140     /**
141      * Extract the value portion of a string in the format of a named value pair
142      * i.e. <i>[name]=[value]</i>.
143      *
144      * @param nameEqualsValue string
145      * @return value portion of name / value pair
146      */

147     public static String JavaDoc valueOfNameValuePair(String JavaDoc nameEqualsValue) {
148         String JavaDoc value = nameEqualsValue.substring(nameEqualsValue.indexOf('=') + 1).trim();
149
150         int i = value.indexOf(';');
151         if (i > 0)
152             value = value.substring(0, i);
153         if (value.startsWith("\"")) {
154             value = value.substring(1, value.indexOf('"', 1));
155         }
156
157         else {
158             i = value.indexOf(' ');
159             if (i > 0)
160                 value = value.substring(0, i);
161         }
162         return value;
163     }
164
165     /**
166      * Convert a byte array to a hex string
167      *
168      * @param data
169      * @return hex string
170      */

171     public static String JavaDoc toHexString(byte[] data) {
172         return toHexString(data, 0, data.length);
173     }
174
175     /**
176      * Convert a byte array to a hex string
177      *
178      * @param data bytes to convert
179      * @param offset offset in array to start from
180      * @param len number of bytes to convert
181      * @return hex string
182      */

183     public static String JavaDoc toHexString(byte[] data, int offset, int len) {
184         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
185         for (int i = offset; i < len; i++) {
186             String JavaDoc s = Integer.toHexString(((byte)data[i] & 0xFF));
187             if (s.length() < 2) {
188                 buf.append("0");
189             }
190             buf.append(s);
191         }
192         return buf.toString();
193     }
194
195     /**
196      * Rebuild the URI of the request by concatenating the servlet path and and
197      * request parameters
198      *
199      * @param request request to extra path from
200      * @return path
201      */

202     public static String JavaDoc getOriginalRequest(HttpServletRequest JavaDoc request) {
203         StringBuffer JavaDoc req = new StringBuffer JavaDoc(request.getServletPath());
204         if (request.getQueryString() != null && request.getQueryString().length() > 0) {
205             req.append("?");
206             req.append(request.getQueryString());
207         }
208         return req.toString();
209     }
210
211     /**
212      * Read an input stream and load it into a string.
213      *
214      * @param in input stream
215      * @param charsetName encoding or <code>null</code> for default
216      * @return string
217      * @throws IOException on any error
218      */

219     public static String JavaDoc loadStreamToString(InputStream JavaDoc in, String JavaDoc charsetName) throws IOException JavaDoc {
220         StringBuffer JavaDoc licenseText = new StringBuffer JavaDoc();
221         BufferedReader JavaDoc br = new BufferedReader JavaDoc(charsetName == null ? new InputStreamReader JavaDoc(in) : new InputStreamReader JavaDoc(in,
222                         charsetName));
223         try {
224             char[] buf = new char[65536];
225             int r = 0;
226             while ((r = br.read(buf)) != -1)
227                 licenseText.append(buf, 0, r);
228         } finally {
229             br.close();
230         }
231         return licenseText.toString();
232     }
233
234     /**
235      * Dump all session attributes to {@link System#err}.
236      *
237      * @param session session to get attributes from
238      */

239     public static void dumpSessionAttributes(HttpSession JavaDoc session) {
240         System.err.println("Session attributes for " + session.getId());
241         for (Enumeration JavaDoc e = session.getAttributeNames(); e.hasMoreElements();) {
242             String JavaDoc n = (String JavaDoc) e.nextElement();
243             System.err.println(" " + n + " = " + session.getAttribute(n));
244         }
245     }
246
247     /**
248      * Dump all request attributes to {@link System#err}.
249      *
250      * @param request request to get attributes from
251      */

252     public static void dumpRequestAttributes(HttpServletRequest JavaDoc request) {
253         System.err.println("Request attributes for " + request.getPathTranslated());
254         for (Enumeration JavaDoc e = request.getAttributeNames(); e.hasMoreElements();) {
255             String JavaDoc n = (String JavaDoc) e.nextElement();
256             System.err.println(" " + n + " = " + request.getAttribute(n));
257         }
258     }
259
260     /**
261      * Dump all request headers to {@link System#err}.
262      *
263      * @param request request to get headers from
264      */

265     public static void dumpRequestHeaders(HttpServletRequest JavaDoc request) {
266         System.err.println("Request headers for " + request.getPathTranslated());
267         for (Enumeration JavaDoc e = request.getHeaderNames(); e.hasMoreElements();) {
268             String JavaDoc n = (String JavaDoc) e.nextElement();
269             for(Enumeration JavaDoc e2 = request.getHeaders(n); e2.hasMoreElements(); ) {
270                 String JavaDoc v = (String JavaDoc)e2.nextElement();
271                 System.err.println(" " + n + " = " + v);
272             }
273         }
274     }
275
276     /**
277      * Dump all servlet context attributes to {@link System#err}.
278      *
279      * @param context context to get attributes from
280      */

281     public static void dumpServletContextAttributes(ServletContext JavaDoc context) {
282         System.err.println("Servlet context attributes for");
283         for (Enumeration JavaDoc e = context.getAttributeNames(); e.hasMoreElements();) {
284             String JavaDoc n = (String JavaDoc) e.nextElement();
285             System.err.println(" " + n + " = " + context.getAttribute(n));
286         }
287
288     }
289
290     /**
291      * Dump all request parameters to {@link System#err}
292      *
293      * @param request request to get parameters from
294      */

295     public static void dumpRequestParameters(HttpServletRequest JavaDoc request) {
296         System.err.println("Request parameters for session #" + request.getSession().getId());
297         for (Enumeration JavaDoc e = request.getParameterNames(); e.hasMoreElements();) {
298             String JavaDoc n = (String JavaDoc) e.nextElement();
299             String JavaDoc[] vals = request.getParameterValues(n);
300             for (int i = 0; i < vals.length; i++) {
301                 System.err.println(" " + n + " = " + vals[i]);
302             }
303         }
304
305     }
306
307     /**
308      * Dump all request parameters and some other useful stuff from
309      * the request to {@link System#err}
310      *
311      * @param request request to get parameters from
312      */

313     public static void dumpRequest(HttpServletRequest JavaDoc request) {
314         System.err.println("Context Path " + request.getContextPath());
315         System.err.println("Path Translated " + request.getPathTranslated());
316         System.err.println("Path Info " + request.getPathInfo());
317         System.err.println("Query: " + request.getQueryString());
318         System.err.println("Request URI: " + request.getRequestURI());
319         System.err.println("Request URL: " + request.getRequestURL());
320         System.err.println("Is Secure: " + request.isSecure());
321         System.err.println("Scheme: " + request.getScheme());
322         dumpRequestParameters(request);
323         dumpRequestAttributes(request);
324         dumpRequestHeaders(request);
325
326     }
327
328     /**
329      * Dump the contents of a {@link Map} to {@link System#err}.
330      *
331      * @param map map to dump
332      */

333     public static void dumpMap(Map JavaDoc map) {
334         System.err.println("Map dump");
335         for (Iterator JavaDoc i = map.entrySet().iterator(); i.hasNext();) {
336             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
337             System.err.println(" Key = " + entry.getKey() + " Val = " + entry.getValue());
338         }
339
340     }
341
342     /**
343      * Dump an exception to {@link System#err}.
344      *
345      * @param exception exception to dump
346      */

347     public static void printStackTrace(Throwable JavaDoc exception) {
348         Exception JavaDoc e;
349         try {
350             throw new Exception JavaDoc();
351         } catch (Exception JavaDoc ex) {
352             e = ex;
353         }
354         StackTraceElement JavaDoc[] trace = e.getStackTrace();
355         System.err.println("[REMOVE-ME] - " + trace[1].getClassName() + ":" + trace[1].getLineNumber());
356         exception.printStackTrace();
357
358     }
359
360     /**
361      * Concatenate all of the non null messages from an exception chain,
362      * appending full stops after each messages if they do not end with one.
363      *
364      * @param t trace
365      * @return exception message chain text
366      */

367     public static String JavaDoc getExceptionMessageChain(Throwable JavaDoc t) {
368         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
369         while (t != null) {
370             if (buf.length() > 0 && !buf.toString().endsWith(".")) {
371                 buf.append(". ");
372             }
373             if (t.getMessage() != null) {
374                 buf.append(t.getMessage().trim());
375             }
376             t = t.getCause();
377         }
378         return buf.toString();
379     }
380
381     /**
382      * Print a TODO message to {@link System#err}, including the current class
383      * and line number call was made along with a specified message.
384      * <p>
385      * Use for temporary debug. Calling statement should be removed.
386      * </p>
387      *
388      * @param message message to display
389      */

390     public static void toDo(String JavaDoc message) {
391         Exception JavaDoc e;
392         try {
393             throw new Exception JavaDoc();
394         } catch (Exception JavaDoc ex) {
395             e = ex;
396         }
397         StackTraceElement JavaDoc[] trace = e.getStackTrace();
398         System.err.println("[***TODO***] - " + trace[1].getClassName() + ":" + trace[1].getLineNumber() + " - " + message);
399     }
400
401     /**
402      * Print some temporary debug to {@link System#err}, including the current
403      * class and line number call was made along with a specified message.
404      * <p>
405      * Use for temporary debug. Calling statement should be removed.
406      * </p>
407      *
408      * @param message message to display
409      */

410     public static void removeMe(String JavaDoc message) {
411         Exception JavaDoc e;
412         try {
413             throw new Exception JavaDoc();
414         } catch (Exception JavaDoc ex) {
415             e = ex;
416         }
417         StackTraceElement JavaDoc[] trace = e.getStackTrace();
418         System.err.println("[REMOVE-ME] - " + trace[1].getClassName() + ":" + trace[1].getLineNumber() + " - " + message);
419
420     }
421
422     /**
423      * This method will replace '&' with "&amp;", '"' with "&quot;", '<' with
424      * "&lt;" and '>' with "&gt;".
425      *
426      * @param html html to encode
427      * @return encoded html
428      * @see #decodeHTML(String)
429      */

430     public static String JavaDoc encodeHTML(String JavaDoc html) {
431         // Does java have a method of doing this?
432
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
433         char ch;
434         for (int i = 0; i < html.length(); i++) {
435             ch = html.charAt(i);
436             switch (ch) {
437                 case '&':
438
439                     // May be already encoded
440
if (((i + 5) < html.length()) && html.substring(i + 1, i + 5).equals("amp;")) {
441                         buf.append(ch);
442                     } else {
443                         buf.append("&#38;");
444                     }
445                     break;
446                 case '"':
447                     buf.append("&#34;");
448                     break;
449                 case '<':
450                     buf.append("&#60;");
451                     break;
452                 case '>':
453                     buf.append("&#62;");
454                     break;
455                 default:
456                     buf.append(ch);
457             }
458         }
459         return buf.toString();
460     }
461
462     /**
463      * Decode HTML entities
464      *
465      * @param html encoded html
466      * @return decoded html
467      * @see #encodeHTML(String)
468      */

469     public static String JavaDoc decodeHTML(String JavaDoc html) {
470         // Does java have a method of doing this?
471
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
472         char ch;
473         for (int i = 0; i < html.length(); i++) {
474             ch = html.charAt(i);
475             switch (ch) {
476                 case '&':
477                     String JavaDoc s = html.substring(i);
478                     if (s.startsWith("&amp;")) {
479                         buf.append("&");
480                         i += 4;
481                     } else if (s.startsWith("&quote;")) {
482                         buf.append("\"");
483                         i += 6;
484                     } else if (s.startsWith("&lt;")) {
485                         buf.append("<");
486                         i += 3;
487                     } else if (s.startsWith("&gt;")) {
488                         buf.append(">");
489                         i += 3;
490                     }
491                     break;
492                 default:
493                     buf.append(ch);
494             }
495         }
496         return buf.toString();
497     }
498
499     /**
500      * Escape a string so it is suitable for including as a Javascript string.
501      *
502      * @param string string to escape
503      * @param doSingle replace single quotes
504      * @param doDouble replace double quote quotes
505      * @return escaped string
506      */

507     public static String JavaDoc escapeForJavascriptString(String JavaDoc string, boolean doSingle, boolean doDouble) {
508         if(string == null) {
509             return "";
510         }
511         string = trimBoth(string);
512         string = string.replaceAll("\\\\", "\\\\\\\\");
513         if(doSingle)
514             string = string.replaceAll("'", "\\\\'");
515         if(doDouble)
516             string = string.replaceAll("\"", "\\\\'");
517         String JavaDoc[] lines = string.split("\n");
518         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
519         for (int i = 0; i < lines.length; i++) {
520             if (buf.length() > 0) {
521                 buf.append("<br/>");
522             }
523             buf.append(trimBoth(lines[i]));
524         }
525         return buf.toString();
526     }
527
528     /**
529      * Escape a string so it is suitable for including as a Javascript string.
530      *
531      * @param string
532      * @return escaped string
533      */

534     public static String JavaDoc escapeForJavascriptString(String JavaDoc string) {
535         return escapeForJavascriptString(string, true, true);
536     }
537
538     /**
539      * Delete a file or a directory and all of its children.
540      * <p>
541      * <b>Use with care ;-)</b>
542      *
543      * @param file file or directory to delete
544      * @return file or directory deleted ok
545      */

546     public static boolean delTree(File JavaDoc file) {
547         if (log.isDebugEnabled())
548             log.debug("Deleting " + file.getAbsolutePath());
549         if (file.isDirectory()) {
550             File JavaDoc[] f = file.listFiles();
551             if (f != null) {
552                 for (int i = 0; i < f.length; i++) {
553                     if (!delTree(f[i])) {
554                         return false;
555                     }
556                 }
557             }
558         }
559         if (!file.delete()) {
560             log.warn("Failed to remove " + file.getAbsolutePath());
561             return false;
562         }
563         return true;
564     }
565
566     /**
567      * Trim a string to the specified size, optionally appending elipses (..) if
568      * the string is too large. Eclipses are included in the final size.
569      * Otherwise, the string is simply cut off at its maximum size.
570      *
571      * @param text text
572      * @param size maximum size
573      * @param addElipses add elipses if text to larget
574      * @return trimmed string
575      */

576     public static String JavaDoc trimToSize(String JavaDoc text, int size, boolean addElipses) {
577         return text.length() <= size ? text
578                         : (text.substring(0, size - (addElipses ? (size > 3 ? 3 : size) : 0)) + (addElipses ? " .." : ""));
579     }
580
581     /**
582      * Encode a url. First UTF-8 is tried, and if that fails US-ASCII.
583      *
584      * @param url url to encode
585      * @return encoded url
586      */

587     public static String JavaDoc urlEncode(String JavaDoc url) {
588         return urlEncode(url, System.getProperty("sslexplorer.urlencoding", "UTF-8"));
589     }
590     
591     /**
592      * Encode a url. First UTF-8 is tried, and if that fails US-ASCII.
593      *
594      * @param url url to encode
595      * @param charset the character set to encode with
596      * @return encoded url
597      */

598     public static String JavaDoc urlEncode(String JavaDoc url, String JavaDoc charset) {
599         try {
600             // W3C recommended
601
return URLEncoder.encode(url, charset);
602         } catch (UnsupportedEncodingException JavaDoc uee) {
603             try {
604                 //
605
return URLEncoder.encode(url, "us-ascii");
606             } catch (UnsupportedEncodingException JavaDoc uee2) {
607                 log.error("URL could not be encoded! This should NOT happen!!!");
608                 return url;
609             }
610         }
611     }
612
613     /**
614      * Decode a url. First UTF-8 is tried, and if that fails US-ASCII.
615      *
616      * @param url url to decode
617      * @return decoded url
618      */

619     public static String JavaDoc urlDecode(String JavaDoc url) {
620         try {
621             // W3C recommended
622
return URLDecoder.decode(url, System.getProperty("sslexplorer.urlencoding", "UTF-8"));
623         } catch (UnsupportedEncodingException JavaDoc uee) {
624             try {
625                 //
626
return URLDecoder.decode(url, "us-ascii");
627             } catch (UnsupportedEncodingException JavaDoc uee2) {
628                 log.error("URL could not be decoded! This should NOT happen!!!");
629                 return url;
630             }
631         }
632     }
633
634     /**
635      * Add headers to a response that will prevent compliant clients from
636      * caching.
637      *
638      * @param response response to add appropriate headers to
639      */

640     public static void noCache(HttpServletResponse JavaDoc response) {
641         response.setHeader("Pragma", "no-cache");
642         // You cannot use setDateHeader with -1. This actually sets a date
643
// rather than sending Expires: -1
644
//response.setDateHeader("Expires", new Date().getTime());
645
//response.setHeader("Expires", "-1");
646
response.setHeader("Cache-Control", "no-cache");
647     }
648
649     /**
650      * Decode a string based on the either the _charset_ request parameter that
651      * may have been suplied with a request or the requests character encoding.
652      * <p>
653      * TODO Make sure this still works and it being used correctly, im not so
654      * sure it is!
655      *
656      * @param request request to get encoding from
657      * @param string string to decode
658      * @return decoded string
659      */

660     public static String JavaDoc decodeRequestString(HttpServletRequest JavaDoc request, String JavaDoc string) {
661         String JavaDoc enc = request.getParameter("_charset_");
662         if (enc != null && !enc.equals("ISO-8859-1")) {
663             try {
664                 return new String JavaDoc(string.getBytes("ISO-8859-1"), enc);
665             } catch (Exception JavaDoc e) {
666             }
667         }
668         enc = request.getCharacterEncoding();
669         if (enc != null && !enc.equals("ISO-8859-1")) {
670             try {
671                 return new String JavaDoc(string.getBytes("ISO-8859-1"), enc);
672             } catch (Exception JavaDoc e) {
673             }
674
675         }
676         return string;
677     }
678
679     /**
680      * Create a {@link Map} from a {@link java.util.List}. The key and value
681      * objects of each entry will be identical.
682      *
683      * @param list list to turn into map
684      * @return map
685      */

686     public static Map JavaDoc listToHashMapKeys(List JavaDoc list) {
687         HashMap JavaDoc map = new HashMap JavaDoc();
688         Object JavaDoc k;
689         for (Iterator JavaDoc i = list.iterator(); i.hasNext();) {
690             k = i.next();
691             map.put(k, k);
692         }
693         return map;
694     }
695
696     /**
697      * Copy from an input stream to an output stream. It is up to the caller to
698      * close the streams.
699      *
700      * @param in input stream
701      * @param out output stream
702      * @throws IOException on any error
703      */

704     public static void copy(InputStream JavaDoc in, OutputStream JavaDoc out) throws IOException JavaDoc {
705         copy(in, out, -1);
706     }
707
708
709     /**
710      * Copy the specified number of bytes from an input stream to an output
711      * stream. It is up to the caller to close the streams.
712      *
713      * @param in input stream
714      * @param out output stream
715      * @param count number of bytes to copy
716      * @throws IOException on any error
717      */

718     public static void copy(InputStream JavaDoc in, OutputStream JavaDoc out, long count) throws IOException JavaDoc {
719         copy(in, out, count, BUFFER_SIZE);
720     }
721
722     /**
723      * Copy the specified number of bytes from an input stream to an output
724      * stream. It is up to the caller to close the streams.
725      *
726      * @param in input stream
727      * @param out output stream
728      * @param count number of bytes to copy
729      * @param bufferSize buffer size
730      * @throws IOException on any error
731      */

732     public static void copy(InputStream JavaDoc in, OutputStream JavaDoc out, long count, int bufferSize) throws IOException JavaDoc {
733         byte buffer[] = new byte[bufferSize];
734         int i = bufferSize;
735         if (count >= 0) {
736             while (count > 0) {
737                 if (count < bufferSize)
738                     i = in.read(buffer, 0, (int) count);
739                 else
740                     i = in.read(buffer, 0, bufferSize);
741
742                 if (i == -1)
743                     break;
744
745                 count -= i;
746                 out.write(buffer, 0, i);
747                 // LDP - Do not remove this flush!
748
out.flush();
749             }
750         } else {
751             while (true) {
752                 i = in.read(buffer, 0, bufferSize);
753                 if (i < 0)
754                     break;
755                 if (log.isDebugEnabled())
756                     log.debug("Transfered " + i + " bytes");
757                 out.write(buffer, 0, i);
758                 // LDP - Do not remove this flush!
759
out.flush();
760             }
761         }
762         
763     }
764
765     /**
766      * Copy a file to another file.
767      *
768      * @param f file to copy
769      * @param t target file
770      * @throws IOException on any error
771      */

772     public static void copy(File JavaDoc f, File JavaDoc t) throws IOException JavaDoc {
773         copy(f, t, false);
774     }
775
776     /**
777      * Copy a file to another file.
778      *
779      * @param f file to copy
780      * @param t target file
781      * @param onlyIfNewer only copy if the target file is new
782      * @throws IOException on any error
783      */

784     public static void copy(File JavaDoc f, File JavaDoc t, boolean onlyIfNewer) throws IOException JavaDoc {
785         if (!onlyIfNewer || f.lastModified() > t.lastModified()) {
786             if (log.isDebugEnabled())
787                 log.debug("Copying " + f.getAbsolutePath() + " to " + t.getAbsolutePath());
788             InputStream JavaDoc in = new FileInputStream JavaDoc(f);
789             try {
790                 OutputStream JavaDoc out = new FileOutputStream JavaDoc(t);
791                 try {
792                     copy(in, out);
793                 } finally {
794                     out.close();
795                 }
796             } finally {
797                 in.close();
798             }
799             t.setLastModified(f.lastModified());
800         } else {
801             if (log.isDebugEnabled())
802                 log.debug("Skipping copying of file " + f.getAbsolutePath() + " as the target is newer than the source.");
803         }
804     }
805
806     /**
807      * Copy a file to a directory.
808      *
809      * @param from file to copy
810      * @param toDir target directory
811      * @param replace replace existing file
812      * @param onlyIfNewer only copy if the target file is new
813      * @throws IOException on any error
814      */

815     public static void copyToDir(File JavaDoc from, File JavaDoc toDir, boolean replace, boolean onlyIfNewer) throws IOException JavaDoc {
816         if (!toDir.exists()) {
817             throw new IOException JavaDoc("Destination directory " + toDir.getAbsolutePath() + " doesn't exist.");
818         }
819         if (from.isDirectory()) {
820             File JavaDoc toDirDir = new File JavaDoc(toDir, from.getName());
821             if (toDirDir.exists() && replace) {
822                 delTree(toDirDir);
823             }
824             if (!toDirDir.exists()) {
825                 if (log.isDebugEnabled())
826                     log.debug("Creating directory " + toDirDir.getAbsolutePath());
827                 if (!toDirDir.mkdirs()) {
828                     throw new IOException JavaDoc("Failed to create directory " + toDirDir.getAbsolutePath());
829                 }
830             }
831             File JavaDoc[] f = from.listFiles();
832             if (f != null) {
833                 for (int i = 0; i < f.length; i++) {
834                     copyToDir(f[i], toDirDir, replace, onlyIfNewer);
835                 }
836             } else {
837                 throw new IOException JavaDoc("Failed to list " + from.getAbsolutePath());
838             }
839         } else if (from.isFile()) {
840             copy(from, new File JavaDoc(toDir, from.getName()), onlyIfNewer);
841         } else {
842             throw new IOException JavaDoc(from.getAbsolutePath() + " is not a plain file or directory.");
843         }
844     }
845
846     /**
847      * Return an empty string when null passed, otherwise return the string.
848      *
849      * @param string string or null
850      * @return string or empty string
851      */

852     public static String JavaDoc emptyWhenNull(String JavaDoc string) {
853         return string == null ? "" : string;
854     }
855
856     /**
857      * Turn a constant name into an english like phrase. E.g. <i>HTTP_ERROR</i>
858      * would be turned into <i>Http Error</i>.
859      *
860      * @param constant constant name
861      * @return readable name
862      */

863     public static String JavaDoc makeConstantReadable(String JavaDoc constant) {
864         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
865         char ch;
866         boolean firstChar = true;
867         for (int i = 0; i < constant.length(); i++) {
868             ch = constant.charAt(i);
869             if (ch == '_') {
870                 ch = ' ';
871                 firstChar = true;
872             } else {
873                 if (firstChar) {
874                     ch = Character.toUpperCase(ch);
875                     firstChar = false;
876                 } else {
877                     ch = Character.toLowerCase(ch);
878                 }
879             }
880             buf.append(ch);
881         }
882         return buf.toString();
883     }
884
885     /**
886      * Turn a key into an english like phrase. E.g. <i>webForwardURL</i>
887      * would be turned into <i>Web Forward URL</i>.
888      *
889      * @param constant constant name
890      * @return readable name
891      */

892     public static String JavaDoc makeKeyReadable(String JavaDoc constant) {
893         // vFSPath
894
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
895         char ch;
896         char lastChar = 0;
897         for (int i = 0; i < constant.length(); i++) {
898             ch = constant.charAt(i);
899             if(i == 0) {
900                 ch = Character.toUpperCase(ch);
901             }
902             else {
903                 if(Character.isUpperCase(ch)) {
904                     if(!Character.isUpperCase(lastChar)) {
905                         buf.append(" ");
906                     }
907                 }
908             }
909             buf.append(ch);
910             lastChar = ch;
911         }
912         return buf.toString();
913     }
914
915     /**
916      * Turn a constant like name into an key like structure. E.g. <i>HTTP_ERROR</i>
917      * would be turned into <i>httpError</i>.
918      *
919      * @param constant constant
920      * @return key
921      */

922     public static String JavaDoc makeConstantKey(String JavaDoc constant) {
923         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
924         char ch;
925         boolean firstChar = false;
926         for (int i = 0; i < constant.length(); i++) {
927             ch = constant.charAt(i);
928             if (ch == '_') {
929                 firstChar = true;
930             } else {
931                 if (firstChar) {
932                     ch = Character.toUpperCase(ch);
933                     firstChar = false;
934                 } else {
935                     ch = Character.toLowerCase(ch);
936                 }
937                 buf.append(ch);
938             }
939         }
940         return buf.toString();
941     }
942
943     /**
944      * Re-process the case of a space separated string of words. The first
945      * character is capitalised, all others or lower cased.
946      *
947      * @param unCased uncased string
948      * @return cased string
949      */

950     public static String JavaDoc reCase(String JavaDoc unCased) {
951         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
952         char ch;
953         boolean wordNext = false;
954         for (int i = 0; i < unCased.length(); i++) {
955             ch = unCased.charAt(i);
956             if (ch == ' ') {
957                 wordNext = true;
958             } else {
959                 if (wordNext) {
960                     ch = Character.toUpperCase(ch);
961                     wordNext = false;
962                 } else {
963                     ch = Character.toLowerCase(ch);
964                 }
965                 buf.append(ch);
966             }
967         }
968         return buf.toString();
969     }
970
971     /**
972      * Read from the provided input stream until the buffer is full, blocking if
973      * there are no bytes available until there are.
974      *
975      * @param in input stream
976      * @param buf buffer to read into
977      * @return bytes read
978      * @throws IOException on any error
979      */

980     public static int readFullyIntoBuffer(InputStream JavaDoc in, byte[] buf) throws IOException JavaDoc {
981         int read;
982         while ((read = in.read(buf)) > -1) {
983             ;
984         }
985         return read;
986     }
987
988     /**
989      * Parse a simple pattern into a regular expression. Simple expressions
990      * simply support '*' and '?' for 'any characters' and 'single character'.
991      * By simplifying of the pattern may be defeated by starting the string with
992      * a '#' or any exact matched may be specified by starting the string with a
993      * '='.
994      *
995      * @param simplePattern simple pattern
996      * @return regular expression pattern
997      *
998      */

999     public static String JavaDoc parseSimplePatternToRegExp(String JavaDoc simplePattern) {
1000        if (simplePattern.startsWith("#")) {
1001            simplePattern = simplePattern.substring(1);
1002        } else if (simplePattern.startsWith("=")) {
1003            simplePattern = "^" + Util.simplePatternToRegExp(simplePattern.substring(1)) + "$";
1004        } else {
1005            simplePattern = "^" + Util.simplePatternToRegExp(simplePattern)
1006                            + (simplePattern.indexOf('*') == -1 && simplePattern.indexOf('?') == -1 ? ".*" : "") + "$";
1007        }
1008        return simplePattern;
1009    }
1010
1011    /*
1012     * Convert a simple pattern into a regular expression. Simple expressions
1013     * simply support '*' and '?' for 'any characters' and 'single character'.
1014     *
1015     * @param simplePattern simple pattern @return regular expression pattern
1016     */

1017    static String JavaDoc simplePatternToRegExp(String JavaDoc simplePattern) {
1018        int c = simplePattern.length();
1019        char ch;
1020        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1021        for (int i = 0; i < c; i++) {
1022            ch = simplePattern.charAt(i);
1023            if (Character.isLetterOrDigit(ch)) {
1024                buf.append(ch);
1025            } else if (ch == '*') {
1026                buf.append(".*");
1027            } else if (ch == '?') {
1028                buf.append(".?");
1029            } else {
1030                buf.append("\\");
1031                buf.append(ch);
1032            }
1033        }
1034        return buf.toString();
1035    }
1036
1037    /**
1038     * Get the class path from a class loader (must be an instance
1039     * of a {@link java.net.URLClassLoader}.
1040     *
1041     * @param classLoader
1042     * @return class path
1043     */

1044    public static String JavaDoc getClassPath(ClassLoader JavaDoc classLoader) {
1045        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1046        if(classLoader instanceof URLClassLoader JavaDoc) {
1047            URLClassLoader JavaDoc urlc = (URLClassLoader JavaDoc)classLoader;
1048            URL JavaDoc[] urls = urlc.getURLs();
1049            for(int i = 0 ; i < urls.length; i++) {
1050                if(urls[i].getProtocol().equals("file")) {
1051                    File JavaDoc f = new File JavaDoc(Util.urlDecode(urls[i].getPath()));
1052                    if(buf.length() > 0) {
1053                        buf.append(File.pathSeparator);
1054                    }
1055                    buf.append(f.getPath());
1056                }
1057            }
1058        }
1059        return buf.toString();
1060    }
1061
1062    /**
1063     * Append a string to another string inserting a comma if the original
1064     * string is not blank. If the original string is <code>null</code> it will be
1065     * treated as if it were blank. The value to append cannot be <code>null</code>.
1066     *
1067     * @param original original string
1068     * @param value string to append
1069     * @return new string
1070     */

1071    public static String JavaDoc appendToCommaSeparatedList(String JavaDoc original, String JavaDoc value) {
1072        if(original == null || original.equals("")) {
1073            return value;
1074        }
1075        return original + "," + value;
1076    }
1077
1078    /**
1079     * Append a string to the value of a system property insert a comma
1080     * if the original value is not blank. If the current value of the
1081     * original string is <code>null</code> it will be
1082     * treated as if it were blank. The value to append cannot be <code>null</code>.
1083     *
1084     * @param systemPropertyName system property name to append
1085     * @param value string to append
1086     */

1087    public static void appendToCommaSeparatedSystemProperty(String JavaDoc systemPropertyName, String JavaDoc value) {
1088        System.setProperty(systemPropertyName, appendToCommaSeparatedList(System.getProperty(systemPropertyName), value));
1089    }
1090
1091    /**
1092     * Get the simple name of a class.
1093     *
1094     * @param cls class
1095     * @return simple name
1096     */

1097    public static String JavaDoc getSimpleClassName(Class JavaDoc cls) {
1098        int idx = cls.getName().lastIndexOf(".");
1099        return idx == -1 ? cls.getName() : cls.getName().substring(idx + 1);
1100    }
1101
1102    /**
1103     * Split a string into an array taking into account delimiters, quotes and
1104     * escapes
1105     *
1106     * @param str string to split
1107     * @param delim delimiter
1108     * @param quote quote character
1109     * @param escape escape character
1110     * @return array
1111     */

1112    
1113    public static String JavaDoc[] splitString(String JavaDoc str, char delim, char quote, char escape) {
1114        Vector JavaDoc v = new Vector JavaDoc();
1115        StringBuffer JavaDoc str1 = new StringBuffer JavaDoc();
1116        char ch = ' ';
1117        boolean inQuote = false;
1118        boolean escaped = false;
1119    
1120        for (int i = 0; i < str.length(); i++) {
1121            ch = str.charAt(i);
1122    
1123            if ((escape != -1) && (ch == escape) && !escaped) {
1124                escaped = true;
1125            } else {
1126                if ((quote != -1) && (ch == quote) && !escaped) {
1127                    inQuote = !inQuote;
1128                } else if (!inQuote && (ch == delim && !escaped)) {
1129                    v.addElement(str1.toString());
1130                    str1.setLength(0);
1131                } else {
1132                    str1.append(ch);
1133                }
1134                if (escaped) {
1135                    escaped = false;
1136                }
1137            }
1138        }
1139    
1140        if (str.length() > 0) {
1141            v.addElement(str1.toString());
1142    
1143        }
1144        String JavaDoc[] array;
1145        array = new String JavaDoc[v.size()];
1146        v.copyInto(array);
1147    
1148        return array;
1149    }
1150
1151    /**
1152     * Escape a string suitable for RFC2253.
1153     *
1154     * @param string
1155     * @return escaped string
1156     */

1157    public static String JavaDoc escapeForDNString(String JavaDoc string) {
1158        char ch;
1159        StringBuffer JavaDoc b = new StringBuffer JavaDoc(string.length());
1160        for(int i = 0 ; i < string.length(); i++) {
1161            ch = string.charAt(i);
1162            if(ch == ',' || ch == '+' || ch == '"' || ch == '<' || ch == '>' || ch == ';' || ch == '.') {
1163                b.append("\\");
1164                b.append(Integer.toHexString(ch));
1165            }
1166            else {
1167                b.append(ch);
1168            }
1169        }
1170        return b.toString();
1171    }
1172
1173    
1174    public static boolean checkVersion(String JavaDoc actual, String JavaDoc required) {
1175
1176        int[] applicationVersion = getVersion(actual);
1177        int[] installedJREVersion = getVersion(required);
1178
1179        for (int i = 0; i < applicationVersion.length && i < installedJREVersion.length; i++) {
1180            if (applicationVersion[i] < installedJREVersion[i])
1181                return false;
1182        }
1183
1184        return true;
1185    }
1186
1187    public static int[] getVersion(String JavaDoc version) {
1188
1189        int idx = 0;
1190        int pos = 0;
1191        int[] result = new int[0];
1192        do {
1193
1194            idx = version.indexOf('.', pos);
1195            int v;
1196            if (idx > -1) {
1197                v = Integer.parseInt(version.substring(pos, idx));
1198                pos = idx + 1;
1199            } else {
1200                try {
1201                    int sub = version.indexOf('_', pos);
1202                    if (sub == -1) {
1203                        sub = version.indexOf('-', pos);
1204                    }
1205                    if (sub > -1) {
1206                        v = Integer.parseInt(version.substring(pos, sub));
1207                    } else {
1208                        v = Integer.parseInt(version.substring(pos));
1209                    }
1210                } catch (NumberFormatException JavaDoc ex) {
1211                    // Ignore the exception and return what version we have
1212
break;
1213                }
1214            }
1215            int[] tmp = new int[result.length + 1];
1216            System.arraycopy(result, 0, tmp, 0, result.length);
1217            tmp[tmp.length - 1] = v;
1218            result = tmp;
1219
1220        } while (idx > -1);
1221
1222        return result;
1223    }
1224
1225    public static String JavaDoc escapeForRegexpReplacement(String JavaDoc repl) {
1226        StringBuffer JavaDoc buf = new StringBuffer JavaDoc(repl.length());
1227        char ch;
1228        int len = repl.length();
1229        for(int i = 0 ; i < len; i++) {
1230            ch = repl.charAt(i);
1231            if(ch == '\\') {
1232                buf.append(ch);
1233            }
1234            else if(ch == '$') {
1235                buf.append('\\');
1236            }
1237            buf.append(ch);
1238        }
1239        return buf.toString();
1240    }
1241    
1242    /**
1243     * Get a day of week constant suitable for use with {@link Calendar}
1244     * given an english day day. This may be any case and only the first
1245     * 3 characters are tested for (i.e. sun, mon, tue, etc ..)
1246     *
1247     * @param text
1248     * @return day of week
1249     */

1250    public static int getDayOfWeekForText(String JavaDoc text) {
1251        text = text.toLowerCase();
1252        if(text.startsWith("sun")) {
1253            return Calendar.SUNDAY;
1254        }
1255        else if(text.startsWith("mon")) {
1256            return Calendar.MONDAY;
1257        }
1258        else if(text.startsWith("tue")) {
1259            return Calendar.TUESDAY;
1260        }
1261        else if(text.startsWith("wed")) {
1262            return Calendar.WEDNESDAY;
1263        }
1264        else if(text.startsWith("thu")) {
1265            return Calendar.THURSDAY;
1266        }
1267        else if(text.startsWith("fri")) {
1268            return Calendar.FRIDAY;
1269        }
1270        else if(text.startsWith("sat")) {
1271            return Calendar.SATURDAY;
1272        }
1273        return 0;
1274    }
1275
1276    /**
1277     * Set a value in the system.properties file without destroying the
1278     * format. Note, be careful with this, its pretty simple at the moment
1279     * and doesn't encode property values.
1280     *
1281     * @param key key (required)
1282     * @param value value or <code>null</code> to comment
1283     * @param comment comment to set for new value or <code>null</code> to omit
1284     * @throws IOException on any error
1285     */

1286    public static void setSystemProperty(String JavaDoc key, String JavaDoc value, String JavaDoc comment) throws IOException JavaDoc {
1287        InputStream JavaDoc in = null;
1288        OutputStream JavaDoc out = null;
1289        File JavaDoc f = new File JavaDoc(ContextHolder.getContext().getConfDirectory(), "system.properties");
1290        File JavaDoc tf = new File JavaDoc(ContextHolder.getContext().getConfDirectory(), "system.properties.tmp");
1291        File JavaDoc of = new File JavaDoc(ContextHolder.getContext().getConfDirectory(), "system.properties.old");
1292        try {
1293            in = new FileInputStream JavaDoc(f);
1294            out = new FileOutputStream JavaDoc(tf);
1295            BufferedReader JavaDoc br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in));
1296            PrintWriter JavaDoc pw = new PrintWriter JavaDoc(out);
1297            String JavaDoc line = null;
1298            boolean found = false;
1299            while( ( line = br.readLine() ) != null ) {
1300                if(found) {
1301                    pw.println(line);
1302                }
1303                else {
1304                    String JavaDoc trimLine = Util.trimBoth(line);
1305                    boolean commented = false;
1306                    int idx = 0;
1307                    while(idx < trimLine.length() && trimLine.charAt(idx) == '#') {
1308                        commented = true;
1309                        idx++;
1310                    }
1311                    String JavaDoc tVal = trimLine.substring(idx);
1312                    if(tVal.startsWith(key + "=")) {
1313                        found = true;
1314                        if(commented) {
1315                            if(value == null) {
1316                            // leave alone
1317
}
1318                            else {
1319                                // set value
1320
pw.println(key + "=" + value);
1321                            }
1322                        }
1323                        else {
1324                            if(value == null) {
1325                                // comment
1326
pw.println("#" + line);
1327                            }
1328                            else {
1329                                // set value
1330
pw.println(key + "=" + value);
1331                            }
1332                        }
1333                    }
1334                    else {
1335                        pw.println(line);
1336                    }
1337                    trimLine.startsWith("#");
1338                }
1339                
1340            }
1341            if(!found) {
1342                if(comment != null) {
1343                    pw.println();
1344                    pw.println(comment);
1345                }
1346                pw.println(key + "=" + value);
1347            }
1348            pw.flush();
1349            
1350        } finally {
1351            Util.closeStream(in);
1352            Util.closeStream(out);
1353        }
1354        
1355        // Move files
1356
if(of.exists() && !of.delete()) {
1357            log.warn("Failed to delete old backup system properties file");
1358        }
1359        copy(f, of);
1360        copy(tf, f);
1361        if(!tf.delete()) {
1362            log.warn("Failed to delete temporary system properties file");
1363        }
1364        
1365
1366    }
1367
1368    /**
1369     * Convert an array of objects to a comma separated string (using
1370     * each elements {@link Object#toString()} method.
1371     *
1372     * @param elements
1373     * @return as comma separated string
1374     */

1375    public static String JavaDoc arrayToCommaSeparatedList(Object JavaDoc[] elements) {
1376        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1377        for(int i = 0 ; i < elements.length; i++) {
1378            if(i > 0)
1379                buf.append(",");
1380            buf.append(elements[i].toString());
1381        }
1382        return buf.toString();
1383    }
1384
1385    /**
1386     * Test if a string is <code>null</code> if it is an
1387     * empty string when trimmed.
1388     *
1389     * @param string
1390     * @return null or trimmed blank string
1391     */

1392    public static boolean isNullOrTrimmedBlank(String JavaDoc string) {
1393        return string == null || string.trim().length() == 0;
1394    }
1395
1396    /**
1397     * Return a trimmed string regardless of whether the
1398     * source string is <code>null</code> (in which case an
1399     * empty string will be retuned).
1400     *
1401     * @param string
1402     * @return trimmed or blank string
1403     */

1404    public static String JavaDoc trimmedOrBlank(String JavaDoc string) {
1405        return string == null ? "" : string.trim();
1406    }
1407
1408    /**
1409     * Return a trimmed string (both ends) regardless of whether the
1410     * source string is <code>null</code> (in which case an
1411     * empty string will be retuned).
1412     *
1413     * @param string
1414     * @return trimmed or blank string
1415     */

1416    public static String JavaDoc trimmedBothOrBlank(String JavaDoc string) {
1417        return trimBoth(string == null ? "" : string.trim());
1418    }
1419
1420    /**
1421     * Attempt to make a file executable. Only current works on
1422     * systems that have the <b>chmod</b> command available.
1423     *
1424     * @param binLocation
1425     * @throws IOException on any error
1426     */

1427    public static void makeExecutable(File JavaDoc binLocation) throws IOException JavaDoc {
1428        Process JavaDoc p = Runtime.getRuntime().exec(new String JavaDoc[] { "chmod", "ug+rx", binLocation.getAbsolutePath() });
1429        try {
1430            copy(p.getErrorStream(), new ByteArrayOutputStream JavaDoc());
1431        }
1432        finally {
1433            try {
1434                if(p.waitFor() != 0) {
1435                    throw new IOException JavaDoc("Failed to set execute permission. Return code " + p.exitValue() + ".");
1436                }
1437            } catch (InterruptedException JavaDoc e) {
1438            }
1439        }
1440        
1441    }
1442}
Popular Tags