KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > commons > cbutil > CBUtility


1 package com.ca.commons.cbutil;
2
3 import javax.swing.*;
4 import java.awt.*;
5 import java.awt.event.WindowAdapter JavaDoc;
6 import java.awt.event.WindowEvent JavaDoc;
7 import java.io.*;
8 import java.net.URL JavaDoc;
9 import java.util.*;
10 import java.util.logging.Level JavaDoc;
11 import java.util.logging.Logger JavaDoc;
12
13 /**
14  * This is a grab bag of useful classes and static functions that are
15  * not important enough to merit being top level entities. Most of them
16  * are concerned with string handling, file handling, and i18n issues.
17  */

18
19 public class CBUtility
20 {
21
22     private static Cursor savedCursor;
23     private static Frame displayFrame = null;
24
25     private static Logger JavaDoc log = Logger.getLogger(CBUtility.class.getName());
26
27     private CBUtility()
28     {
29     }
30
31     /**
32      * A utility ftn used to make a closing window shut down
33      * the current application. Useful for small test progs.
34      */

35     public static class BasicWindowMonitor extends WindowAdapter JavaDoc
36     {
37         public void windowClosing(WindowEvent JavaDoc e)
38         {
39             Window w = e.getWindow();
40             w.setVisible(false);
41             w.dispose();
42             //System.exit(0);
43
}
44     }
45
46     /**
47      * Returns the raw text (i.e. with tags as "\<...\>" strings) of a web page
48      *
49      * @param url the url of the web age to read as plain text.
50      * @return a StringBuffer containing the raw html text
51      */

52
53     public static StringBuffer JavaDoc readURLText(URL JavaDoc url)
54     {
55         return readURLText(url, new StringBuffer JavaDoc("error: can't read URL " + url.toString()));
56     }
57
58     /**
59      * Returns the raw text (i.e. with tags as "\<...\>" strings) of a web page
60      *
61      * @param url the url of the web age to read as plain text.
62      * @param errorText a custom message to return if something goes wrong.
63      * @return a StringBuffer containing the raw html text
64      */

65
66     public static StringBuffer JavaDoc readURLText(URL JavaDoc url, StringBuffer JavaDoc errorText)
67     {
68         StringBuffer JavaDoc page = new StringBuffer JavaDoc("");
69         String JavaDoc thisLine;
70         try
71         {
72             BufferedReader source = new BufferedReader(new InputStreamReader(url.openStream()));
73
74             while ((thisLine = source.readLine()) != null)
75             {
76                 page.append(thisLine + "\n");
77             }
78             return page;
79         }
80         catch (Exception JavaDoc e)
81         {
82             return errorText;
83         }
84     }
85
86     /**
87      * Reads an input stream into a byte array.
88      */

89
90     public static byte[] readStream(InputStream is) throws IOException
91     {
92         byte[] data = null;
93         byte[] buffer = new byte[16384];
94         int blockSize = 0;
95         int size = 0;
96
97         while ((blockSize = is.read(buffer)) != -1) // kinda clumsy, reallocating
98
{ // memory like this I guess,
99
byte[] temp = new byte[size + blockSize]; // but since we don't know
100
if (size != 0) // how big the stream is, what
101
System.arraycopy(data, 0, temp, 0, size); // else can we do? (?)
102

103             System.arraycopy(buffer, 0, temp, size, blockSize);
104             data = temp;
105             size += blockSize;
106         }
107         return data;
108     }
109
110
111     /**
112      * Reads a text file, and returns the result as a String. Not
113      * Recommended for large (say > 100k) files.
114      *
115      * @param file the ascii file to read from.
116      */

117
118     public static String JavaDoc readTextFile(File file)
119             throws IOException
120     {
121         // special handling for file reading in non-english locales...
122

123         if (Locale.getDefault().getLanguage().equals("en") == false)
124             return readI18NFile(file);
125
126         // Read File into String Buffer
127
FileReader in = new FileReader(file);
128         int size = (int) file.length();
129         char[] data = new char[size];
130         int chars_read = 0;
131         while (chars_read < size)
132             chars_read += in.read(data, chars_read, size - chars_read);
133
134         return new String JavaDoc(data); // use default locale encoding...
135
}
136
137     /**
138      * Reads a text file, and returns the result as a StringBuffer. Not
139      * Recommended for large (say > 100k) files.<p>
140      * <p/>
141      * This function attempts to automatically determine the encoding
142      * of the file it is to read, as either UTF-16, UTF-8, or default
143      * locale encoding, based on 1) whether the first two bytes are
144      * Unicode byte-ordering markers ('FFFE' or 'FEFF'), UTF-8 (based
145      * on whether the file is a valid UTF8 string) or,
146      * failing this, the default locale encoding.
147      *
148      * @param file the local encoding/unicode/utf8 file to read from.
149      */

150
151     public static String JavaDoc readI18NFile(File file)
152             throws IOException
153     {
154         // Read File into String Buffer
155

156         FileInputStream in = new FileInputStream(file);
157         int size = (int) file.length();
158         byte[] data = new byte[size];
159         int bytes_read = 0;
160
161         while (bytes_read < size)
162             bytes_read += in.read(data, bytes_read, size - bytes_read);
163
164         return readI18NByteArray(data);
165     }
166
167     public static String JavaDoc readI18NByteArray(byte[] data)
168     {
169         // Try to work out whether this is unicode double bytes (utf-16),
170
// unicode (or *cough* 7 bit ascii) in utf-8 format, or local
171
// encoding...
172
try
173         {
174             if (CBParse.isUnicode(data))
175             {
176                 log.finer("reading unicode 16 bit text");
177                 String JavaDoc text = new String JavaDoc(data, "UTF-16"); // return as 16 bit unicode
178
if (text.length() > 0) return text;
179                 return new String JavaDoc(data); // something went wrong - try again with default encoding...
180
}
181             else
182             {
183                 byte[] test = new byte[250]; // grab the start of the file to test...
184

185                 if (data.length < 250)
186                     test = data;
187                 else
188                     System.arraycopy(data, 0, test, 0, 250);
189
190                 if (CBParse.isNonAsciiUTF8(test))
191                 {
192                     log.finer("reading utf8 text");
193                     String JavaDoc text = new String JavaDoc(data, "UTF-8"); // return as UTF-8
194
if (text.length() > 0) return text;
195                     return (new String JavaDoc(data)); // something went wrong - try again with default encoding
196
}
197                 else
198                 {
199                     log.finer("reading local encoding text");
200
201                     String JavaDoc newString = new String JavaDoc(data);
202                     if (newString.indexOf("\\u") == -1)
203                     {
204                         return newString; // no need for special processing.
205
}
206
207                     // MANUALLY (!) decode \ u java unicode escape strings...
208
// (Why? Because someone may be in a foreign locale, but
209
// still using broken java unicode escape syntax from standard
210
// property files.)
211

212                     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(newString);
213
214                     int pos = 0;
215                     while (pos + 6 < buffer.length())
216                     {
217                         if (buffer.charAt(pos) != '\\')
218                             pos++;
219                         else if (buffer.charAt(pos + 1) != 'u')
220                             pos += 2;
221                         else
222                         {
223                             String JavaDoc unicode = buffer.substring(pos + 2, pos + 6);
224                             int uni = Integer.parseInt(unicode, 16);
225                             buffer = buffer.delete(pos, pos + 6);
226                             buffer = buffer.insert(pos, (char) uni);
227                             pos++;
228                         }
229
230                     }
231
232                     return buffer.toString(); // return as default locale encoding
233
}
234             }
235         }
236
237                 /* If anything goes wrong (UnsupportedEncodingException, or hopefully if
238                  * the utf-8 string turns out not to be) fall back on using the
239                  * default encoding.
240                  */

241
242         catch (Exception JavaDoc e)
243         {
244             log.warning("Confused Reading File: " + e.toString() + "\n -> reverting to default encoding");
245             return new String JavaDoc(data); // return as default locale encoding
246
}
247     }
248
249
250     /**
251      * Reads an array of strings from a file
252      * (via a property file, 'cause I'm lazy).
253      *
254      * @param fileName the file to read from
255      */

256     public static String JavaDoc[] readStringArrayFile(String JavaDoc fileName)
257     {
258         Properties props = readPropertyFile(fileName);
259         String JavaDoc[] values = new String JavaDoc[props.size()];
260         Enumeration en = props.elements();
261         int count = 0;
262         while (en.hasMoreElements())
263         {
264             values[count++] = en.nextElement().toString();
265         }
266         return values;
267     }
268
269     /**
270      * Reads a java Properties list from a file.
271      *
272      * @param fileName the full path and file name of the properties file
273      * to read in.
274      */

275
276     public static Properties readPropertyFile(String JavaDoc fileName)
277     {
278         Properties propertyList = new Properties();
279
280         try
281         {
282             File propertyFile = new File(fileName);
283             if (propertyFile == null || propertyFile.exists() == false)
284             {
285                 log.warning("No property list:\n" + fileName);
286                 return propertyList; // return empty properties list
287
}
288
289             FileInputStream in = new FileInputStream(propertyFile);
290             propertyList.load(in);
291             return propertyList;
292         }
293         catch (Exception JavaDoc e)
294         {
295             log.log(Level.WARNING, "Can't read property list:\n" + fileName + "\n", e);
296             return propertyList;
297         }
298     }
299
300     /**
301      * Writes an array of strings into a file
302      * (via a property file, 'cause I'm lazy).
303      * (XXX Warning - will only write unique values; doubles will be lost).
304      *
305      * @param fileName the file to read to
306      * @param strings the array of strings
307      */

308     public static void writeStringArrayFile(String JavaDoc fileName, String JavaDoc[] strings)
309     {
310         Properties props = new Properties();
311         for (int i = 0; i < strings.length; i++)
312             props.put(strings[i], strings[i]); // so it's redundant. sue me.
313

314         writePropertyFile(fileName, props, "generated string array list");
315     }
316
317
318     /**
319      * Writes a java Properties list to a file.
320      *
321      * @param fileName the full path and file name of the properties file
322      * to read in.
323      */

324
325     public static void writePropertyFile(String JavaDoc fileName, Properties propertyList, String JavaDoc comments)
326     {
327         // do hack to get propertyList to print out in alphabetical order...
328

329         CBProperties orderedPropertyList = new CBProperties(propertyList);
330
331         try
332         {
333             File propertyFile = new File(fileName);
334
335             FileOutputStream out = new FileOutputStream(propertyFile);
336
337             orderedPropertyList.store(out, "Generated Property List " + fileName + "\n" + ((comments != null) ? comments : ""));
338         }
339         catch (Exception JavaDoc e)
340         {
341             log.log(Level.WARNING, "Can't write property list:\n" + fileName + "\n", e);
342         }
343     }
344
345     /**
346      * Turns a string into HTML displayable text by escaping
347      * special characters ('<','&' etc...).
348      * <p/>
349      * ... add new ones as required; or see if an existing ftn somewhere
350      * does this already...
351      *
352      * @deprecated use CBParse method instead
353      */

354
355     public static String JavaDoc toHTML(String JavaDoc rawText)
356     {
357         String JavaDoc test;
358         if (rawText.length() > 14)
359             test = rawText.substring(0, 14).toLowerCase();
360         else
361             test = rawText.toLowerCase();
362
363         if (test.startsWith("<html>") || test.startsWith("<!doctype html>"))
364         {
365
366 // XXX this was commented out, but it seems to be necessaary/desirable?
367
if (test.startsWith("<html>"))
368                 rawText = rawText.substring(6);
369             else if (test.startsWith("<!doctype html>"))
370                 rawText = rawText.substring(15);
371
372             if (rawText.toLowerCase().endsWith("</html>"))
373             {
374                 rawText = rawText.substring(0, rawText.length() - 7);
375             }
376
377 // END XXX
378

379             return rawText;
380         }
381         char C;
382         StringBuffer JavaDoc temp = new StringBuffer JavaDoc(rawText);
383
384         for (int pos = 0; pos < temp.length(); pos++)
385         {
386             C = temp.charAt(pos);
387
388             switch (C)
389             {
390                 case '<':
391                     CBParse.replaceChar(temp, pos, "&lt;");
392                     break;
393                 case '>':
394                     CBParse.replaceChar(temp, pos, "&gt;");
395                     break;
396                 case '&':
397                     CBParse.replaceChar(temp, pos, "&amp;");
398                     break;
399                 case '\"':
400                     CBParse.replaceChar(temp, pos, "&quot;");
401                     break;
402                 case '#':
403                     CBParse.replaceChar(temp, pos, "&#35;");
404                     pos++;
405                     break;
406             }
407         }
408         return temp.toString();
409     }
410
411     /**
412      * Deletes a character in <i>text</i> at position <i>pos<i> and replaces
413      * it with the string <i>replacement</i>.
414      *
415      * @param text the text to be modified
416      * @param pos the position of the character to be deleted
417      * @param replacement the string the character is to be replaced with.
418      * @deprecated use CBParse method instead
419      */

420
421     public static int replaceChar(StringBuffer JavaDoc text, int pos, String JavaDoc replacement)
422     {
423         text.deleteCharAt(pos);
424         text.insert(pos, replacement);
425         return (pos + replacement.length());
426     }
427
428     /**
429      * Deletes all characters <i>c</i> in <i>text</i> replaces
430      * it with the string <i>replacement</i>.
431      *
432      * @param text the text to be modified
433      * @param replacement the string the character is to be replaced with.
434      * @deprecated use CBParse method instead
435      */

436
437     public static String JavaDoc replaceAllChar(StringBuffer JavaDoc text, char c, String JavaDoc replacement)
438     {
439         return CBParse.replaceAllBufferChar(text, c, replacement).toString();
440     }
441
442     /**
443      * Deletes all characters <i>c</i> in <i>text</i> replaces
444      * it with the string <i>replacement</i>.
445      *
446      * @param text the text to be modified
447      * @param replacement the string the character is to be replaced with.
448      * @deprecated use CBParse method instead
449      */

450
451     public static StringBuffer JavaDoc replaceAllBufferChar(StringBuffer JavaDoc text, char c, String JavaDoc replacement)
452     {
453         int pos = 0;
454         while (pos != -1)
455         {
456             pos = text.toString().indexOf(c, pos);
457             if (pos != -1)
458                 pos = CBParse.replaceChar(text, pos, replacement);
459         }
460         return text;
461     }
462
463     /**
464      * Deletes a substring in <i>text</i> at position <i>pos<i>, of length <i>len</i> and replaces
465      * it with the string <i>replacement</i>.
466      *
467      * @param text the text to be modified
468      * @param pos the position of the character to be deleted
469      * @param replacement the string the character is to be replaced with.
470      * @deprecated use CBParse method instead
471      */

472
473     public static int replaceString(StringBuffer JavaDoc text, int pos, int len, String JavaDoc replacement)
474     {
475         text.replace(pos, pos + len, replacement);
476         //text.delete(pos, pos+len);
477
//text.insert(pos, replacement);
478
return (pos + replacement.length());
479     }
480
481     /**
482      * Deletes all characters <i>orig</i> in <i>text</i> and replaces
483      * it with the string <i>replacement</i>.
484      *
485      * @param text the text to be modified
486      * @param orig the original text substring to be changed
487      * @param replacement the string the original substring is to be replaced with.
488      * @deprecated use CBParse method instead
489      */

490
491     public static String JavaDoc replaceAllString(StringBuffer JavaDoc text, String JavaDoc orig, String JavaDoc replacement)
492     {
493         return CBParse.replaceAllBufferString(text, orig, replacement).toString();
494     }
495
496     /**
497      * Deletes all characters <i>orig</i> in <i>text</i> replaces
498      * it with the string <i>replacement</i>.
499      *
500      * @param text the text to be modified
501      * @param orig the original text substring to be changed
502      * @param replacement the string the original substring is to be replaced with.
503      * @deprecated use CBParse method instead
504      */

505
506     public static StringBuffer JavaDoc replaceAllBufferString(StringBuffer JavaDoc text, String JavaDoc orig, String JavaDoc replacement)
507     {
508         int pos = 0;
509         while (pos != -1)
510         {
511             pos = text.toString().indexOf(orig, pos);
512             if (pos != -1)
513                 pos = CBParse.replaceString(text, pos, orig.length(), replacement);
514         }
515         return text;
516     }
517
518
519     /**
520      * Utility for micro-parser. Gets the next character pos in a string
521      * after an initial offset that either matches, or does not match, <i>any</i>
522      * of a set of comparison characters.
523      *
524      * @param pos the position to start searching from
525      * @param searchMe the string to search
526      * @param compare a string containing characters to compare against
527      * @param match whether the match is for characters in the compare string (true)
528      * or <i>not</i> in the compare string (false)
529      * @return the position found, or -1 if no position is found.
530      * @deprecated use CBParse method instead
531      */

532
533     public static int nextCharIn(int pos, String JavaDoc searchMe, String JavaDoc compare, boolean match)
534     {
535         char test;
536         int length = searchMe.length();
537         while (pos < length)
538         {
539             test = searchMe.charAt(pos);
540             if ((compare.indexOf(test) != -1) == match)
541                 return pos;
542             pos++;
543         }
544         return -1;
545     }
546
547     /**
548      * Reads a directory, returning all file names of the given extension.
549      *
550      * @param dirPath directory to read
551      * @param extension the file extension to filter files with.
552      * @return list of full file names
553      */

554
555     public static String JavaDoc[] readFilteredDirectory(String JavaDoc dirPath, String JavaDoc extension)
556     {
557         String JavaDoc[] extensions = new String JavaDoc[1];
558         extensions[0] = extension;
559
560         return readFilteredDirectory(dirPath, extensions);
561     }
562
563     /**
564      * Reads a directory, returning all file names of the given extensions
565      *
566      * @param dirPath directory to read
567      * @param fileExtensions extension a list of file extensions to filter files with.
568      * @return list of full file names
569      */

570
571     public static String JavaDoc[] readFilteredDirectory(String JavaDoc dirPath, String JavaDoc[] fileExtensions)
572     {
573         final String JavaDoc[] extensions = fileExtensions;
574         File dir = new File(dirPath);
575 //XXX Could use CBFileFilter here?
576
String JavaDoc[] templates = dir.list(new FilenameFilter()
577         {
578             public boolean accept(File dir, String JavaDoc name)
579             {
580                 for (int i = 0; i < extensions.length; i++)
581                 {
582                     if (name.endsWith(extensions[i]))
583                         return true;
584                 }
585                 return false;
586             }
587         });
588
589         return templates;
590     }
591
592
593     /**
594      * Sets the cursor to the wait cursor.
595      *
596      * @param C the owning component.
597      */

598
599     public static void setWaitCursor(Component C)
600     {
601         C.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
602     }
603
604
605     /**
606      * Sets the cursor to the normal cursor.
607      *
608      * @param C the owning component.
609      */

610
611     public static void setNormalCursor(Component C)
612     {
613         C.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
614     }
615
616
617     /**
618      * Sets the cursor to the hand cursor.
619      *
620      * @param C the owning component.
621      */

622
623     public static void setHandCursor(Component C)
624     {
625         C.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
626     }
627
628
629     /**
630      * Saves a cursor. One cursor. That's all. Just one. Try to
631      * save another one, it'll overwrite this one. So don't.
632      *
633      * @param C the owning component.
634      */

635
636     public static void saveCursor(Component C)
637     {
638         savedCursor = C.getCursor();
639     }
640
641
642     /**
643      * Gets the cursor back that you just saved. Probably better
644      * make sure it's the same component you saved it from. Wouldn't
645      * care to guess what happens if it isn't...
646      *
647      * @param C the owning component.
648      */

649     public static void restoreCursor(Component C)
650     {
651         if (savedCursor != null)
652             C.setCursor(savedCursor);
653         else
654             log.info("graphics error: can't restore cursor; no cursor saved...");
655     }
656
657     /**
658      * Sets the level of logging on a scale of 0 (none) to 10 (everything).
659      * @param L the log level.
660      */

661
662     //public static void setLogDebugLevel(int L) { debugLevel = L; }
663

664     /**
665      * Returns the global debug level.
666      */

667
668     //public static int getLogDebugLevel() { return debugLevel; }
669

670
671
672     /**
673      * Sets the type of logging, using the strings 'none', 'console' or 'file'.
674      * @param logType the type of logging to use.
675      */

676     //public static void setLogType(String logType) {setLogType(logType, null);}
677

678     /**
679      * Sets the type of logging, using the strings 'none', 'console' or 'file'.
680      * @param logType the type of logging to use.
681      * @param fileName the name of the log file to use, (unused if logType != 'file')
682      */

683 /*
684     public static void setLogType(String logType, String fileName)
685     {
686         if (logType.equalsIgnoreCase("none")) loggingStyle = NOLOG;
687         else if (logType.equalsIgnoreCase("console")) loggingStyle = CONSOLE;
688         else if (logType.equalsIgnoreCase("file") || logType.equalsIgnoreCase("both"))
689         {
690             String logFileName = (fileName==null)?"jxplorer.log":fileName;
691             try
692             {
693                 logfile = new FileWriter(logFileName);
694                 if (logType.equalsIgnoreCase("both"))
695                     loggingStyle=CONSOLEANDFILE;
696                 else
697                     loggingStyle = FILE;
698             }
699             catch (Exception e)
700             {
701                 CBUtility.log("unable to open log file " + logFileName + "\nreverting to console logging");
702                 loggingStyle = CONSOLE;
703             }
704         }
705         else loggingStyle = CONSOLE; // console is default...
706
707         log("Logging Initialised to " + logType, 1);
708     }
709 */

710     /**
711      * Closes the log file.
712      */

713 /*
714     public static void closeLog()
715     {
716         try
717         {
718             if (logfile != null) logfile.close();
719         }
720         catch (Exception e)
721         {
722             CBUtility.log("error shutting log file " + e.toString());
723         }
724     }
725 */

726     /**
727      * logs if the global debug level equal to or greater than the
728      * passed int value.<p>
729      *
730      * <b>Log Levels</b><br>
731      * <ul>
732      * <li>0 - error logging only
733      * <li>1
734      * <li>2
735      * <li>3
736      * <li>4 - entry level logging of all delete/copy/move operations
737      * <li>5
738      * <li>6
739      * <li>7
740      * <li>8
741      * <li>9 - full BER logging
742      * </ul>
743      *
744      *
745      * @param S the string to log
746      * @param level the debug level at which the string starts
747      * being printed
748      */

749 /*
750     public static void log(String S, int level)
751     {
752         if (debugLevel >= level) log(S);
753     }
754 */

755     /**
756      * Simple logging utility. Writes log data to a file or console,
757      * or ignores it, depending on the value of the logging and logfile
758      * property (defaults set in JXplorer.java, user sets in dxconfig.txt)
759      */

760
761 /*
762      public static void log(String S)
763      {
764         S = (new Date(System.currentTimeMillis())).toString() + ": " + S;
765         switch (loggingStyle)
766         {
767             case NOLOG: break; // do nothing
768
769             case CONSOLEANDFILE: // log file and console...
770             case FILE: try // log file only
771                     {
772                         logfile.write(S + "\n");
773                         logfile.flush();
774                     }
775                     catch (Exception e)
776                     {
777                         CBUtility.log("unable to write to log file\nreverting to console\n" + e + "\n"+S);
778                         loggingStyle = CONSOLE;
779                     }
780                     if (loggingStyle == FILE) break;
781
782             case CONSOLE: // console
783
784             default: System.out.println(S); break; // echo to console
785          }
786     }
787 */

788     public static void initDefaultDisplay(Frame owner)
789     {
790         displayFrame = owner;
791     }
792
793     public static Frame getDefaultDisplay()
794     {
795         return displayFrame;
796     }
797
798
799     /**
800      * utility ftn; prints error message to user, and echos to the log ftn.
801      *
802      * @return returns false for easy chaining.
803      */

804
805     public static boolean error(Component owner, String JavaDoc Msg)
806     {
807         return error(getParentFrame(owner), Msg, null);
808     }
809
810     /**
811      * utility ftn; prints error message to user, and echos to the log ftn.
812      *
813      * @return returns false for easy chaining.
814      */

815
816     public static boolean error(Frame owner, String JavaDoc Msg)
817     {
818         if (displayFrame == null) // no default display registered
819
{
820             log.warning("graphics error: error display not initialised! (root error was: " + Msg + ")");
821             return false;
822         }
823         return error(owner, Msg, null);
824     }
825
826     /**
827      * utility ftn; prints error message to user, and echos to the log ftn.
828      *
829      * @return returns false for easy chaining.
830      */

831
832     public static boolean error(String JavaDoc Msg)
833     {
834         if (displayFrame == null) // no default display registered
835
{
836             log.warning("graphics error: error display not initialised! (error was: " + Msg + ")");
837             return false;
838         }
839         return error(displayFrame, Msg, null);
840     }
841
842     /**
843      * wrapper for the JFrame version of error.
844      *
845      * @param Msg a short one line message to display to the user
846      * @param e the exception to log
847      * @return returns false for easy chaining.
848      */

849
850
851     public static boolean error(String JavaDoc Msg, Exception JavaDoc e)
852     {
853         return error(displayFrame, Msg, e);
854     }
855
856
857     /**
858      * wrapper for the JFrame version of error.
859      *
860      * @param owner the component (from which the parent Frame will be derived)
861      * @param Msg a short one line message to display to the user
862      * @param e the exception to log
863      * @return returns false for easy chaining.
864      */

865
866
867     public static boolean error(Component owner, String JavaDoc Msg, Exception JavaDoc e)
868     {
869         return error(getParentFrame(owner), Msg, e);
870     }
871
872     /**
873      * utility ftn; prints error message and the error to the user,
874      * and echos to the log ftn.
875      *
876      * @param owner the parent Frame (required for dialog box drawing)
877      * @param Msg a short one line message to display to the user
878      * @param e the exception to log
879      * @return returns false for easy chaining.
880      */

881
882
883     public static boolean error(Frame owner, String JavaDoc Msg, Exception JavaDoc e)
884     {
885         if (owner == null) //TE: added this check basically so that I can centre the error window...i.e if there is no owner - there is nothing to centre upon!
886
{
887             if (displayFrame == null) // no default display registered
888
{
889                 log.warning("error display not initialised! (error was: " + Msg + ")");
890                 return false;
891             }
892             else
893             {
894                 owner = displayFrame;
895             }
896         }
897
898         CBErrorWin errWin = new CBErrorWin(owner, Msg, e);
899
900         log.log(Level.WARNING, "error displayed to user: " + Msg, e);
901
902         return false;
903     }
904
905
906     /**
907      * Utility function. Opens a dialog with a confirmation message.
908      *
909      * @param Msg the confirmation message to be displayed.
910      */

911
912     public static void confirm(String JavaDoc Msg)
913     {
914         if (displayFrame == null) // no default display registered
915
{
916             log.warning("error display not initialised! (error was: " + Msg + ")");
917             return;
918         }
919
920         new CBErrorWin(displayFrame, Msg, "Confirmation Message");
921     }
922
923
924     /**
925      * utility ftn; prints warning dialog message to the user,
926      * *without* echoing to the log ftn. Basically wrapper to JOptionPane
927      *
928      * @param caller the GUI component calling (required for dialog box drawing)
929      * @param Msg a short one line message to display to the user
930      * @return returns false for easy chaining.
931      */

932
933     public static boolean warning(Component caller, String JavaDoc Msg, String JavaDoc Title)
934     {
935         JOptionPane.showMessageDialog(caller, Msg,
936                 Title, JOptionPane.WARNING_MESSAGE);
937         return false; // for chaining
938
}
939
940     /**
941      * Short version of warning method - uses default frame, and has the
942      * title 'Warning'.
943      *
944      * @param Msg the warning message to display.
945      */

946     public static boolean warning(String JavaDoc Msg)
947     {
948         if (displayFrame == null) // no default display registered
949
{
950             log.warning("warning display not initialised! (error was: " + Msg + ")");
951             return false;
952         }
953         return warning(displayFrame, Msg, "Warning");
954     }
955
956     /**
957      * prints an enumeration...
958      */

959
960     public static void printEnumeration(Enumeration e)
961     {
962         while (e.hasMoreElements())
963         {
964             Object JavaDoc raw = e.nextElement();
965             String JavaDoc value = (raw == null) ? "*null*" : raw.toString();
966             System.out.println(" " + value);
967         }
968     }
969
970     /**
971      * Iterates through a components parents until it finds the
972      * root frame. Useful for initing JDialogs etc. that require
973      * a root frame to work properly.
974      */

975     public static Frame getParentFrame(Component c)
976     {
977         if (c == null) return null;
978
979         Component parent = c.getParent();
980         while (!(parent instanceof Frame) && (parent != null))
981             parent = parent.getParent();
982
983         return (parent == null) ? null : (Frame) parent;
984     }
985
986     /**
987      * Converts a 'dos' style file path to a unix style file path
988      * by exchanging '\' characters for for '/' characters.
989      */

990
991     public static String JavaDoc convertPathToUnix(String JavaDoc dosPath)
992     {
993         String JavaDoc ret = dosPath.replace('\\', '/');
994         return ret;
995     }
996
997
998     /**
999      * This positions a component to the center of another component.
1000     * If both components are showing on the sceen, it uses absolute
1001     * screen co-ordinates, otherwise if only the positioner component
1002     * is showing, it uses relative co-ordinates (since it is unable to
1003     * obtain screen co-ords). If the components share a reference
1004     * frame, these two actions are equivalent (i.e. if they both have
1005     * the same parent). If nothing is showing, the component is unchanged.
1006     * NOTE: if the X & Y coordinates are off the screen, the component to
1007     * center will be centered in the middle of the screen.
1008     *
1009     * @param centerMe the component to center
1010     * @param positioner the component used as the reference center. If null,
1011     * the component will be centered on the screen
1012     */

1013
1014    public static void center(Component centerMe, Component positioner)
1015    {
1016        if (centerMe == null) return;
1017
1018        if (positioner != null && positioner.isShowing())
1019        {
1020            Rectangle pos = positioner.getBounds(); // relative info.
1021
Point absPos = positioner.getLocationOnScreen(); // absolute info.
1022
int centerX = absPos.x + (pos.width / 2); // center x pos, in screen co-ords
1023
int centerY = absPos.y + (pos.height / 2); // center y pos, in screen co-ords
1024
pos = centerMe.getBounds(); // relative info;
1025

1026            int x = 0;
1027            int y = 0;
1028
1029            if (centerMe.isShowing()) // if centerMe is showing, center it using screen co-ords (no possibility of error)
1030
{
1031                absPos = centerMe.getLocationOnScreen(); // absolute info;
1032
int currentX = absPos.x + (pos.width / 2); // center of centerMe x pos, in screen co-ords
1033
int currentY = absPos.y + (pos.height / 2); // center of centerMe y pos, in screen co-ords
1034

1035                int deltaX = centerX - currentX; // amount to move X
1036
int deltaY = centerY - currentY; // amount to move Y
1037

1038                x = pos.x + deltaX;
1039                y = pos.y + deltaY;
1040            }
1041            else // centerMe isn't showing - can't use screen co-ords, so *assume* both positioner and centerMe have same reference frame
1042
{ // (i.e. components share a common parent...)
1043
x = centerX - (pos.width / 2);
1044                y = centerY - (pos.height / 2);
1045            }
1046
1047            Toolkit toolKit = Toolkit.getDefaultToolkit();
1048
1049            if ((x - 100) < 0 || (x + 100) > toolKit.getScreenSize().width || (y - 100) < 0 || (y + 100) > toolKit.getScreenSize().height) //TE: if off screen (add some padding/a safety margin)...
1050
centerOnScreen(centerMe); //TE: center in middle of screen (bug 2926).
1051
else
1052                centerMe.setLocation(x, y); // move, using local co-ordinates.
1053
}
1054        else
1055        {
1056            centerOnScreen(centerMe);
1057        }
1058    }
1059
1060
1061    /**
1062     * Centers a component on the middle of the screen.
1063     *
1064     * @param centerMe the component to center.
1065     */

1066
1067    private static void centerOnScreen(Component centerMe)
1068    {
1069        Dimension screen = centerMe.getToolkit().getScreenSize();
1070        Dimension object = centerMe.getSize();
1071        centerMe.setLocation((int) (screen.getWidth() - object.getWidth()) / 2, (int) (screen.getHeight() - object.getHeight()) / 2);
1072    }
1073
1074
1075    /**
1076     * @deprecated use CBParse method instead
1077     */

1078    public static String JavaDoc bytes2Hex(byte[] bytes)
1079    {
1080        StringBuffer JavaDoc ret = new StringBuffer JavaDoc(bytes.length * 2);
1081        for (int i = 0; i < bytes.length; i++)
1082        {
1083            ret.append(CBParse.byte2Hex(bytes[i]));
1084        }
1085        return ret.toString();
1086    }
1087
1088
1089    /**
1090     * @deprecated use CBParse method instead
1091     */

1092    public static String JavaDoc string2Hex(String JavaDoc orig)
1093    {
1094        StringBuffer JavaDoc ret = new StringBuffer JavaDoc(orig.length() * 2);
1095        char[] c = orig.toCharArray();
1096        for (int i = 0; i < c.length; i++)
1097        {
1098            ret.append(CBParse.char2Hex(c[i]));
1099        }
1100        return ret.toString();
1101    }
1102
1103    /**
1104     * @deprecated use CBParse method instead
1105     */

1106    static public String JavaDoc byte2Hex(byte b)
1107    {
1108        // Returns hex String representation of byte b
1109
final char hexDigit[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1110        char[] array = {hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f]};
1111        return new String JavaDoc(array);
1112    }
1113
1114    /**
1115     * @deprecated use CBParse method instead
1116     */

1117    static public String JavaDoc char2Hex(char c)
1118    {
1119        // Returns hex String representation of char c
1120
byte hi = (byte) (c >>> 8);
1121        byte lo = (byte) (c & 0xff);
1122        return CBParse.byte2Hex(hi) + CBParse.byte2Hex(lo);
1123    }
1124
1125    /**
1126     * @deprecated use CBParse method instead
1127     */

1128    static public byte hex2Byte(char hex1, char hex2)
1129    {
1130        byte a = CBParse.hexChar2Byte(hex1);
1131        byte b = CBParse.hexChar2Byte(hex2);
1132        return (byte) ((a << 4) + b);
1133    }
1134
1135    /**
1136     * Convert a single character to a byte...
1137     *
1138     * @deprecated use CBParse method instead
1139     */

1140
1141    static public byte hexChar2Byte(char hex)
1142    {
1143        if (hex <= '9')
1144            return ((byte) (hex - 48)); // ('0' -> '9')
1145
else if (hex <= 'F')
1146            return ((byte) (hex - 55)); // ('A' -> 'F')
1147
else
1148            return ((byte) (hex - 87)); // ('a' -> 'f')
1149
}
1150
1151    /**
1152     * From Van Bui - prints out a hex string formatted with
1153     * spaces between each hex word of length wordlength.
1154     *
1155     * @param in input array of bytes to convert
1156     * @param wordlength the length of hex words to print otu.
1157     * @deprecated use CBParse method instead
1158     */

1159    public static String JavaDoc bytes2HexSplit(byte[] in, int wordlength)
1160    {
1161        String JavaDoc hex = CBParse.bytes2Hex(in);
1162        StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
1163
1164        for (int i = 0; i < hex.length(); i++)
1165        {
1166            buff.append(hex.charAt(i));
1167            if ((i + 1) % wordlength == 0)
1168                buff.append(" ");
1169        }
1170
1171        return buff.toString();
1172    }
1173
1174    /**
1175     * From Van Bui - prints out a hex string formatted with
1176     * spaces between each hex word of length wordlength, and
1177     * new lines every linelength.
1178     *
1179     * @param in input array of bytes to convert
1180     * @param wordlength the length of hex words to print otu.
1181     * @param linelength the length of a line to print before inserting
1182     * a line feed.
1183     * @deprecated use CBParse method instead
1184     */

1185
1186    public static String JavaDoc bytes2HexSplit(byte[] in, int wordlength, int linelength)
1187    {
1188        String JavaDoc hex = CBParse.bytes2Hex(in);
1189        StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
1190
1191        for (int i = 0; i < hex.length(); i++)
1192        {
1193            buff.append(hex.charAt(i));
1194            if ((i + 1) % wordlength == 0)
1195                buff.append(" ");
1196            if ((i + 1) % linelength == 0)
1197                buff.append("\n");
1198        }
1199
1200        return buff.toString();
1201    }
1202
1203    /**
1204     * Determines whether a given byte sequence is a valid utf-8
1205     * encoding. While this does not mean that the byte *is* a
1206     * utf-8 encoded string, the chance of a random byte sequence
1207     * happening to be utf8 is roughly (1/2 ** (byte array length)).<p>
1208     * Note that '7 bit ascii' is *always* a valid utf-8 string...<p>
1209     * see rfc 2279
1210     *
1211     * @deprecated use CBParse method instead
1212     */

1213    public static boolean isUTF8(byte[] sequence)
1214    {
1215        boolean debug = false;
1216        if (debug) log.warning("\n\n Starting UTF8 Check\n\n");
1217        int numberBytesInChar;
1218
1219        for (int i = 0; i < sequence.length; i++)
1220        {
1221            byte b = sequence[i];
1222            if (debug) System.out.println("testing byte: " + CBParse.byte2Hex(b));
1223            if (((b >> 6) & 0x03) == 2)
1224            {
1225                if (debug) System.out.println("start byte is invalid utf8 - has 10... start");
1226                return false;
1227            }
1228            byte test = b;
1229            numberBytesInChar = 0;
1230            while ((test & 0x80) > 0)
1231            {
1232                test <<= 1;
1233                numberBytesInChar++;
1234            }
1235
1236            if (numberBytesInChar > 1) // check that extended bytes are also good...
1237
{
1238                for (int j = 1; j < numberBytesInChar; j++)
1239                {
1240                    if (i + j >= sequence.length)
1241                    {
1242                        if (debug) System.out.println("following byte length is invalid - overruns end... ");
1243                        return false; // not a character encoding - probably random bytes
1244
}
1245                    if (debug) System.out.println("testing byte: " + CBParse.byte2Hex(sequence[i + j]));
1246                    if (((sequence[i + j] >> 6) & 0x03) != 2)
1247                    {
1248                        if (debug) System.out.println("following byte is invalid utf8 - does *not* have 10... start");
1249                        return false;
1250                    }
1251                }
1252                i += numberBytesInChar - 1; // increment i to the next utf8 character start position.
1253
}
1254        }
1255
1256        return true;
1257    }
1258
1259    /**
1260     * Determines whether a given byte sequence is a valid utf-8
1261     * encoding, encoding (at least in part) something *other* than
1262     * normal Ascii (i.e.
1263     * it is utf-8 encoding something that is not just 7-bit ascii,
1264     * which in utf-8 is indistinguishable from the original text).<p>
1265     * <p/>
1266     * While this does not mean that the bytes *are* a
1267     * utf-8 encoded string, the chance of a random byte sequence
1268     * (containing bytes with the high-bit set)
1269     * happening to be utf8 is roughly (1/2 ** (byte array length)).<p>
1270     * see rfc 2279
1271     *
1272     * @deprecated use CBParse method instead
1273     */

1274
1275    public static boolean isNonAsciiUTF8(byte[] sequence)
1276    {
1277        log.finest("testing sequence for utf8: " + CBParse.bytes2Hex(sequence));
1278        boolean nonAsciiDetected = false;
1279
1280        int numberBytesInChar;
1281        for (int i = 0; i < sequence.length - 3; i++)
1282        {
1283            byte b = sequence[i];
1284            if (((b >> 6) & 0x03) == 2) return false;
1285            byte test = b;
1286            numberBytesInChar = 0;
1287            while ((test & 0x80) > 0)
1288            {
1289                test <<= 1;
1290                numberBytesInChar++;
1291            }
1292
1293            // check if multi-byte utf8 sequence found
1294
if (numberBytesInChar > 1) // check that extended bytes are also good...
1295
{
1296                nonAsciiDetected = true;
1297                for (int j = 1; j < numberBytesInChar; j++)
1298                {
1299                    if (((sequence[i + j] >> 6) & 0x03) != 2)
1300                        return false;
1301                }
1302                i += numberBytesInChar - 1; // increment i to the next utf8 character start position.
1303
}
1304        }
1305
1306        return nonAsciiDetected;
1307    }
1308
1309
1310    /**
1311     * This uses the implicit 'unicode marker' at the start of a
1312     * Unicode file to determine whether a file is a unicode file.
1313     * At the beginning of every unicode file is a two byte code
1314     * indicating the endien-ness of the file (either FFFE or FEFF).
1315     * If either of these sequences is found, this function returns
1316     * true, otherwise it returns false. <i>Technically</i> this isn't
1317     * a sure test, since a) something else could have this signiture,
1318     * and b) unicode files are not absolutely required to have this
1319     * signiture (but most do).
1320     *
1321     * @deprecated use CBParse method instead
1322     */

1323
1324    public static boolean isUnicode(byte[] sequence)
1325    {
1326        if (sequence.length >= 2)
1327        {
1328            if (sequence[0] == (byte) 0xFF && sequence[1] == (byte) 0xFE) return true;
1329            if (sequence[0] == (byte) 0xFE && sequence[1] == (byte) 0xFF) return true;
1330        }
1331        return false;
1332    }
1333
1334    /*
1335     * Some refugees from com.ca.pki.util.StaticUtil
1336     */

1337
1338    /**
1339     * Show file chooser to get a file location for saving data.
1340     */

1341    public static String JavaDoc chooseFileToSave(Component parent, String JavaDoc title, String JavaDoc[] filter, String JavaDoc fileType)
1342    {
1343        JFileChooser chooser = new JFileChooser(System.getProperty("PKIHOME"));
1344        chooser.setToolTipText(title);
1345        chooser.setDialogTitle(title);
1346        if (filter != null && fileType != null)
1347        {
1348            CBFileFilter filt = new CBFileFilter(filter, fileType);
1349            chooser.setFileFilter(filt);
1350        }
1351        int returnVal = chooser.showSaveDialog(parent);
1352        if (returnVal == JFileChooser.APPROVE_OPTION)
1353        {
1354            if (chooser.getSelectedFile() != null)
1355                return chooser.getSelectedFile().toString();
1356        }
1357        return null;
1358    }
1359
1360    public static boolean okToWriteFile(Frame parent, String JavaDoc fileName)
1361    {
1362        File f = new File(fileName);
1363        if (f.isDirectory())
1364        {
1365            JOptionPane.showMessageDialog(parent, fileName + " is a directory.", "Error!", JOptionPane.ERROR_MESSAGE);
1366            return false;
1367        }
1368        else if (f.exists())
1369        {
1370            int saveAnswer = JOptionPane.showConfirmDialog(parent,
1371                    "File " + fileName + " already exists.\nDo you want to overwrite?",
1372                    "Question", JOptionPane.OK_CANCEL_OPTION);
1373            return (saveAnswer == JOptionPane.OK_OPTION);
1374        }
1375        return true;
1376    }
1377
1378
1379    /**
1380     * This Comparator compares two strings, ignoring case.
1381     *
1382     * @author Trudi.
1383     */

1384
1385    public static class IgnoreCaseStringComparator implements Comparator
1386    {
1387
1388        /**
1389         * This Comparator compares two strings, ignoring case.
1390         *
1391         * @param o1 one of the two items to be compared.
1392         * @param o2 the other of the items to be compared.
1393         * @return the result of the compare (0 if o1 & o2 are equal, -1 if o1 < o2, 1 if o1 > o2).
1394         * NOTE: if o1 is null and o2 is not null, 1 is returned. If o2 is null and o1 is not null, -1 is returned.
1395         * If both o1 and o2 are null, 0 is returned. If an error occurs trying to cast either o1 or o2, 0 is returned.
1396         */

1397
1398        public int compare(Object JavaDoc o1, Object JavaDoc o2)
1399        {
1400            if (o1 == null && o2 != null)
1401                return 1;
1402            else if (o2 == null && o1 != null)
1403                return -1;
1404            else if (o1 == null && o2 == null)
1405                return 0;
1406
1407            try
1408            {
1409                return (o1.toString().toLowerCase()).compareTo(o2.toString().toLowerCase());
1410            }
1411            catch (ClassCastException JavaDoc e)
1412            {
1413                System.out.println("Error sorting values - invalid string in sort." + e);
1414                return 0;
1415            }
1416        }
1417    }
1418
1419    /**
1420     * Searches for a config file. First checks if a property directory has been explicitly set
1421     * with the System property 'jxplorer.config' (which can take either a path, or the
1422     * value 'user.home' to set it to use the user home directory). Then checks the user
1423     * home directory to see if the specific config file already exists there. Then reverts to the default
1424     * location in the user.dir directory the program is run from.
1425     *
1426     * @param configFileName the name of the actual file - e.g. "bookmarks.txt".
1427     * @return
1428     */

1429    public static String JavaDoc getPropertyConfigPath(String JavaDoc configFileName)
1430    {
1431        String JavaDoc pathToConfigFile;
1432
1433        // the potential path to a config file in the user home directory
1434
String JavaDoc userHomeConfigDir = System.getProperty("user.home") + File.separator + "jxplorer";
1435        String JavaDoc userHomeConfigFilePath = userHomeConfigDir + File.separator + configFileName;
1436
1437        // the default config location is to the directory JXplorer is run from.
1438
String JavaDoc defaultConfigFilePath = System.getProperty("user.dir") + File.separator + configFileName;
1439
1440        // see if a config file has been explicitly set
1441
if (System.getProperty("jxplorer.config") != null)
1442        {
1443            pathToConfigFile = System.getProperty("jxplorer.config");
1444
1445            // check if we are being forced to use the user.home directory (we will create the file if it
1446
// doesn't exist)
1447
if (pathToConfigFile.equalsIgnoreCase("home") || pathToConfigFile.equalsIgnoreCase("user.home"))
1448            {
1449                // quick sanity check that there is a 'jxplorer' config directory under user home for us to save to
1450
File configDir = new File(userHomeConfigDir);
1451                if (configDir.exists() == false)
1452                {
1453                    configDir.mkdir(); // - if not, we'll create it.
1454
}
1455
1456                return userHomeConfigFilePath;
1457            }
1458            // otherwise return the parameter - again we will create it if it doesn't exist
1459
if (pathToConfigFile.endsWith(File.separator))
1460                return pathToConfigFile + configFileName;
1461            else
1462                return pathToConfigFile + File.separator + configFileName;
1463        }
1464
1465        // try the user home directory next... if the user home directory config file exists read the config from there
1466
if (new File(userHomeConfigFilePath).exists())
1467        {
1468            return userHomeConfigFilePath;
1469        }
1470
1471        // if there is no config file in the user.home directory, and we haven't been told otherwise, default to
1472
// the directory JXplorer is run from.
1473
return defaultConfigFilePath;
1474    }
1475
1476    /**
1477     * This gets the working log level of a particular logger. You would think Sun would already
1478     * have a method to do this. You would be wrong.
1479     *
1480     * @param log
1481     * @return the active working log level - e.g. whether a particular log call will be called because this,
1482     * or a parent, logger is set to a particular log level.
1483     */

1484    public static Level JavaDoc getTrueLogLevel(Logger JavaDoc log)
1485    {
1486        if (log.getLevel() != null)
1487        {
1488            return log.getLevel();
1489        }
1490
1491        if (log.getParent() != null)
1492            return getTrueLogLevel(log.getParent());
1493
1494        // should never get here...
1495
log.severe("no active log level initialised");
1496        System.err.println("no active log level initialised");
1497
1498        return Level.ALL;
1499    }
1500}
Popular Tags