KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > Utilities


1 /*
2  * Utilities.java
3  *
4  * Copyright (C) 1998-2004 Peter Graves
5  * $Id: Utilities.java,v 1.37 2004/09/17 18:14:05 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import gnu.regexp.RE;
25 import gnu.regexp.REMatch;
26 import gnu.regexp.UncheckedRE;
27 import java.awt.Color JavaDoc;
28 import java.awt.Component JavaDoc;
29 import java.awt.Graphics JavaDoc;
30 import java.awt.event.KeyEvent JavaDoc;
31 import java.io.BufferedInputStream JavaDoc;
32 import java.io.BufferedOutputStream JavaDoc;
33 import java.io.BufferedReader JavaDoc;
34 import java.io.FileOutputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.InputStream JavaDoc;
37 import java.io.InputStreamReader JavaDoc;
38 import java.io.OutputStream JavaDoc;
39 import java.io.UnsupportedEncodingException JavaDoc;
40 import java.lang.reflect.InvocationTargetException JavaDoc;
41 import java.lang.reflect.Method JavaDoc;
42 import java.net.URL JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.List JavaDoc;
45 import java.util.Properties JavaDoc;
46 import java.util.StringTokenizer JavaDoc;
47 import java.util.zip.GZIPInputStream JavaDoc;
48 import java.util.zip.ZipInputStream JavaDoc;
49 import javax.swing.BorderFactory JavaDoc;
50 import javax.swing.BoxLayout JavaDoc;
51 import javax.swing.ImageIcon JavaDoc;
52 import javax.swing.JPanel JavaDoc;
53 import javax.swing.KeyStroke JavaDoc;
54 import javax.swing.border.Border JavaDoc;
55 import javax.swing.border.TitledBorder JavaDoc;
56 import org.xml.sax.XMLReader JavaDoc;
57 import org.xml.sax.helpers.XMLReaderFactory JavaDoc;
58
59 public final class Utilities implements Constants
60 {
61     // Returns false if the string contains any upper case letters, true
62
// otherwise. "abc123" and "123" are lower case.
63
public static boolean isLowerCase(String JavaDoc s)
64     {
65         for (int i = s.length()-1; i >= 0; i--) {
66             if (Character.isUpperCase(s.charAt(i)))
67                 return false;
68         }
69         return true;
70     }
71
72     // For a string to be upper case, it must have at least one upper case
73
// letter, and no lower case letters. "ABC123" is upper case, but "123" is
74
// not.
75
public static boolean isUpperCase(String JavaDoc s)
76     {
77         boolean containsLetter = false;
78         for (int i = s.length()-1; i >= 0; i--) {
79             char c = s.charAt(i);
80             if (Character.isLetter(c)) {
81                 if (!Character.isUpperCase(c))
82                     return false;
83                 containsLetter = true;
84             }
85         }
86         // We didn't encounter any letters that weren't upper case.
87
return containsLetter;
88     }
89
90     public static boolean isWhitespace(String JavaDoc s)
91     {
92         for (int i = s.length()-1; i >= 0; i--) {
93             if (!Character.isWhitespace(s.charAt(i)))
94                 return false;
95         }
96         return true;
97     }
98
99     public static int countLines(String JavaDoc s)
100     {
101         int count = 0;
102         for (int i = s.length(); i-- > 0;)
103             if (s.charAt(i) == '\n')
104                 ++count;
105         return count;
106     }
107
108     public static boolean isDelimited(Buffer buffer, Position pos, int length)
109     {
110         if (buffer != null)
111             return isDelimited(buffer.getMode(), pos, length);
112         else
113             return isDelimited(pos, length);
114     }
115
116     public static boolean isDelimited(Mode mode, Position pos, int length)
117     {
118         if (mode == null)
119             return isDelimited(pos, length);
120         final int before = pos.getOffset() - 1;
121         if (before >= 0 && mode.isIdentifierPart(pos.getLine().charAt(before)))
122             return false;
123         final int after = pos.getOffset() + length;
124         if (after < pos.getLineLength() && mode.isIdentifierPart(pos.getLine().charAt(after)))
125             return false;
126         return true;
127     }
128
129     public static boolean isDelimited(Position pos, int length)
130     {
131         final int before = pos.getOffset() - 1;
132         if (before >= 0 && Character.isJavaIdentifierPart(pos.getLine().charAt(before)))
133             return false;
134         final int after = pos.getOffset() + length;
135         if (after < pos.getLineLength() && Character.isJavaIdentifierPart(pos.getLine().charAt(after)))
136             return false;
137         return true;
138     }
139
140     public static boolean isDelimited(String JavaDoc s, int index, int length)
141     {
142         final int before = index - 1;
143         if (before >= 0 && Character.isJavaIdentifierPart(s.charAt(before)))
144             return false;
145         final int after = index + length;
146         if (after < s.length() && Character.isJavaIdentifierPart(s.charAt(after)))
147             return false;
148         return true;
149     }
150
151     public static boolean isDelimited(String JavaDoc s, int index, int length,
152                                       Mode mode)
153     {
154         if (mode == null)
155             return isDelimited(s, index, length);
156         final int before = index - 1;
157         if (before >= 0 && mode.isIdentifierPart(s.charAt(before)))
158             return false;
159         final int after = index + length;
160         if (after < s.length() && mode.isIdentifierPart(s.charAt(after)))
161             return false;
162         return true;
163     }
164
165     public static boolean isDelimited(Mode mode, String JavaDoc s,
166                                       int startIndex, int endIndex)
167     {
168         if (mode == null)
169             mode = JavaMode.getMode();
170         final int before = startIndex - 1;
171         if (before >= 0 && mode.isIdentifierPart(s.charAt(before)))
172             return false;
173         if (endIndex < s.length() && mode.isIdentifierPart(s.charAt(endIndex)))
174             return false;
175         return true;
176     }
177
178     // Returns extension including leading '.'
179
public static String JavaDoc getExtension(String JavaDoc filename)
180     {
181         int indexOfLastDot = filename.lastIndexOf('.');
182         if (indexOfLastDot < 0)
183             return null;
184         int indexOfLastFileSeparatorChar = filename.lastIndexOf(LocalFile.getSeparatorChar());
185         if (indexOfLastDot < indexOfLastFileSeparatorChar)
186             return null; // Last dot was in path prefix.
187
else
188             return filename.substring(indexOfLastDot);
189     }
190
191     // Returns extension including leading '.'
192
public static String JavaDoc getExtension(File file)
193     {
194         // Only consider last component of filename.
195
String JavaDoc name = file.getName();
196         int index = name.lastIndexOf('.');
197         if (index < 0)
198             return null;
199         else
200             return name.substring(index);
201     }
202
203     public static final File getTempFile()
204     {
205         return getTempFile(Directories.getTempDirectory());
206     }
207
208     public static final File getTempFile(File dir)
209     {
210         return getTempFile(dir, "");
211     }
212
213     public static final File getTempFile(String JavaDoc dir)
214     {
215         return getTempFile(File.getInstance(dir), "");
216     }
217
218     // Implementation.
219
// Guarantee that getTempFile() will generate unique filenames even if
220
// it's called twice with the same value of System.currentTimeMillis().
221
private static int tempFileCount = 0;
222
223     public static synchronized File getTempFile(File dir, String JavaDoc extension)
224     {
225         if (dir == null)
226             return null;
227
228         if (extension == null) {
229             extension = "";
230         } else if (extension.length() > 0) {
231             if (extension.charAt(0) != '.')
232                 extension = ".".concat(extension);
233         }
234
235         long date = System.currentTimeMillis();
236
237         for (int i = 0; i < 100; i++) {
238             File file = File.getInstance(dir,
239                 String.valueOf(date + tempFileCount).concat(extension));
240             ++tempFileCount;
241             if (!file.exists())
242                 return file;
243         }
244
245         return null;
246     }
247
248     public static boolean isDirectoryWritable(File dir)
249     {
250         boolean isWritable = false;
251         File file = getTempFile(dir);
252         if (file != null) {
253             try {
254                 // getOutputStream() will throw FileNotFoundException if
255
// directory is not writable.
256
FileOutputStream JavaDoc out = file.getOutputStream();
257                 out.close();
258                 if (file.isFile()) {
259                     isWritable = true;
260                     file.delete();
261                 }
262             }
263             catch (IOException JavaDoc e) {}
264         }
265         return isWritable;
266     }
267
268     public static String JavaDoc detab(String JavaDoc s, int tabWidth, int startCol)
269     {
270         if (tabWidth <= 0)
271             return s;
272         int limit = s.length();
273         int i;
274         for (i = 0; i < limit; i++) {
275             if (s.charAt(i) == '\t')
276                 break;
277         }
278         if (i == limit)
279             return s; // No tab characters in string.
280

281         // If we get here, we're looking at the first tab character in the string.
282

283         // Copy the first part of the string to a char array.
284
char[] charArray = new char[limit * tabWidth];
285         s.getChars(0, i, charArray, 0);
286         int col = startCol + i;
287         // Handle the first tab character.
288
do {
289             charArray[col - startCol] = ' ';
290             ++col;
291         } while ((col % tabWidth) != 0);
292         // SKip past the tab char in the input string.
293
++i;
294         // Process the rest of the string.
295
while (i < limit) {
296             char c = s.charAt(i++);
297             if (c == '\t') {
298                 for (int j = tabWidth - col % tabWidth - 1; j >= 0; j--) {
299                     charArray[col - startCol] = ' ';
300                     ++col;
301                 }
302             } else {
303                 charArray[col - startCol] = c;
304                 ++col;
305             }
306         }
307         return charArray == null ? s : new String JavaDoc(charArray, 0, col - startCol);
308     }
309
310     public static final String JavaDoc detab(String JavaDoc s, int tabWidth)
311     {
312         return detab(s, tabWidth, 0);
313     }
314
315     public static String JavaDoc entab(String JavaDoc s, int tabWidth, int startCol)
316     {
317         if (tabWidth <= 0)
318             return s;
319         int limit = s.length();
320         if (limit < tabWidth)
321             return s;
322         s = detab(s, tabWidth, startCol); // Clean start.
323

324         // The length may have changed when we detabbed the string.
325
limit = s.length();
326
327         FastStringBuffer sb = new FastStringBuffer(limit);
328         int i = 0;
329         while (i < limit) {
330             char c = s.charAt(i);
331             if (c == ' ') {
332                 int nextTabStop = ((startCol + i) / tabWidth + 1) * tabWidth;
333                 if (nextTabStop < startCol + limit && nextTabStop - (startCol + i) > 1) {
334                     boolean replace = true;
335                     int j = i + 1;
336                     while (j < nextTabStop - startCol) {
337                         if (s.charAt(j++) != ' ') {
338                             replace = false;
339                             break;
340                         }
341                     }
342                     if (replace) {
343                         sb.append('\t');
344                         i = j;
345                         continue;
346                     }
347                 }
348             }
349             sb.append(c);
350             i++;
351         }
352         return sb.toString();
353     }
354
355     public static final String JavaDoc entab(String JavaDoc s, int tabWidth)
356     {
357         return entab(s, tabWidth, 0);
358     }
359
360     public static String JavaDoc makeTabsVisible(String JavaDoc s, int tabWidth)
361     {
362         if (tabWidth <= 0)
363             return s;
364         int limit = s.length();
365         if (limit == 0)
366             return s;
367         final char tabChar = '^';
368         FastStringBuffer sb = new FastStringBuffer(limit);
369         int col = 0;
370         for (int i = 0; i < limit; i++) {
371             char c = s.charAt(i);
372             if (c == '\t') {
373                 sb.append(tabChar);
374                 ++col;
375                 while ((col % tabWidth) != 0) {
376                     sb.append(' ');
377                     ++col;
378                 }
379             } else {
380                 sb.append(c);
381                 ++col;
382             }
383         }
384         return sb.toString();
385     }
386
387     public static String JavaDoc wrap(String JavaDoc s, int wrapCol, int tabWidth)
388     {
389         FastStringBuffer sb = new FastStringBuffer();
390         int i = 0;
391         final int limit = s.length();
392         int startOffs = 0;
393         while (i < limit) {
394             int col = 0;
395             int breakOffs = 0;
396             startOffs = i;
397             boolean inUrl = false;
398             while (i < limit) {
399                 char c = s.charAt(i++);
400                 if (c == '\n') {
401                     sb.append(trimTrailing(s.substring(startOffs, i)));
402                     startOffs = i;
403                     break;
404                 }
405                 if (c == '\t')
406                     col += tabWidth - col % tabWidth;
407                 else
408                     ++col;
409                 if (!inUrl && col > wrapCol) {
410                     // Need to break.
411
if (breakOffs <= startOffs)
412                         breakOffs = i;
413                     sb.append(trimTrailing(s.substring(startOffs, breakOffs)));
414                     sb.append('\n');
415                     i = breakOffs;
416                     // Skip whitespace.
417
while (i < limit && s.charAt(i) == ' ')
418                         ++i;
419                     break;
420                 }
421                 if (c == ' ' || c == '\t') {
422                     // We've already incremented i to point past the whitespace char.
423
breakOffs = i;
424                     inUrl = false;
425                 } else if (c == 'h' && lookingAt(s, i, "ttp://", false)) {
426                     inUrl = true;
427                     i += 6;
428                 } else if (c == 'h' && lookingAt(s, i, "ttps://", false)) {
429                     inUrl = true;
430                     i += 7;
431                 } else if (c == 'f' && lookingAt(s, i, "tp://", false)) {
432                     inUrl = true;
433                     i += 5;
434                 }
435             }
436         }
437         if (i > startOffs)
438             sb.append(trimTrailing(s.substring(startOffs, i)));
439         return sb.toString();
440     }
441
442     public static int getDetabbedLength(String JavaDoc s, int tabWidth)
443     {
444         final int limit = s.length();
445         int detabbedLength = 0;
446         for (int i = 0; i < limit; i++) {
447             if (s.charAt(i) == '\t')
448                 detabbedLength += tabWidth - detabbedLength % tabWidth;
449             else
450                 ++detabbedLength;
451         }
452         return detabbedLength;
453     }
454
455     // Trims leading space characters only, not all whitespace.
456
public static String JavaDoc trimLeading(String JavaDoc s)
457     {
458         final int length = s.length();
459         int i = 0;
460         while (i < length) {
461             if (s.charAt(i) != ' ')
462                 break;
463             ++i;
464         }
465         return s.substring(i);
466     }
467
468     // Trims trailing space characters only, not all whitespace.
469
public static String JavaDoc trimTrailing(String JavaDoc s)
470     {
471         int length = s.length();
472         if (length == 0 || s.charAt(length-1) != ' ')
473             return s;
474         do {
475             --length;
476         } while (length > 0 && s.charAt(length-1) == ' ');
477         return s.substring(0, length);
478     }
479
480     // Returns true if the string to be inserted looks like a block of lines.
481
public static boolean isLinePaste(String JavaDoc s)
482     {
483         final char c = s.charAt(s.length()-1);
484         return c == '\r' || c == '\n';
485     }
486
487     public static int getIntegerProperty(Properties JavaDoc props, String JavaDoc key, int defaultValue)
488     {
489         try {
490             String JavaDoc s = props.getProperty(key);
491             if (s != null)
492                 return Integer.parseInt(s);
493         }
494         catch (NumberFormatException JavaDoc e) {}
495         return defaultValue;
496     }
497
498     /**
499      * Extracts the name of an include file, enclosed in quotes or angle
500      * brackets, from a #include line in a C or C++ source file.
501      *
502      * @param line the #include line
503      * @return the name of the file, enclosed in quotes or angle
504      * brackets as the case may be, or <code>null</code> if
505      * the line in question is not a valid #include line.
506      * @since 0.16.2
507      */

508     public static String JavaDoc extractInclude(String JavaDoc line)
509     {
510         String JavaDoc s = line.trim();
511         if (s.length() < 12) // "#include <a>"
512
return null;
513         if (s.charAt(0) != '#')
514             return null;
515         REMatch match = includeRE.getMatch(s);
516         if (match == null)
517             return null;
518         s = s.substring(match.getEndIndex()).trim();
519         if (s.length() < 2)
520             return null;
521         char c = s.charAt(0);
522         int lastIndex = -1;
523         if (c == '"')
524             lastIndex = s.indexOf('"', 1);
525         else if (c == '<')
526             lastIndex = s.indexOf('>', 1);
527         if (lastIndex < 0)
528             return null;
529         return s.substring(0, lastIndex+1);
530     }
531
532     private static final RE includeRE = new UncheckedRE("#[ \t]*include[ \t]");
533
534     /**
535      * Finds an include file (C or C++).
536      * <p>
537      * If the filename is enclosed in quotes, we look for it in the current
538      * directory first.
539      *
540      * @param s the name of the file, enclosed in quotes or
541      * angle brackets as the case may be
542      * @param path the include path
543      * @param currentDirectory the current directory
544      * @return the file, or <code>null</code> if not found
545      * @since 0.16.2
546      */

547     public static File findInclude(String JavaDoc s, String JavaDoc path,
548         File currentDirectory)
549     {
550         char c = s.charAt(0);
551         final String JavaDoc fileName = s.substring(1, s.length()-1);
552         if (c == '"') {
553             // The filename is enclosed in quotes. Look in the current
554
// directory first.
555
File file = File.getInstance(currentDirectory, fileName);
556             if (file != null && file.isLocal() && file.isFile())
557                 return file;
558         }
559         return Utilities.findFileInPath(fileName, path, currentDirectory);
560     }
561
562     // We pass in currentDirectory in order to support relative paths.
563
public static File findFileInPath(String JavaDoc filename, String JavaDoc path,
564         File currentDirectory)
565     {
566         if (path != null) {
567             int index;
568             do {
569                 index = path.indexOf(LocalFile.getPathSeparatorChar());
570                 String JavaDoc dirname;
571                 if (index < 0) {
572                     dirname = path;
573                 } else {
574                     dirname = path.substring(0, index);
575                     path = path.substring(index + 1);
576                 }
577                 File dir;
578                 if (currentDirectory != null && currentDirectory.isLocal())
579                     dir = File.getInstance(currentDirectory, dirname);
580                 else
581                     dir = File.getInstance(dirname);
582                 if (dir != null) {
583                     File file = File.getInstance(dir, filename);
584                     if (file != null && file.isLocal() && file.isFile())
585                         return file;
586                 }
587             } while (index >= 0);
588         }
589         return null;
590     }
591
592     // Returns a list of strings.
593
public static List JavaDoc getDirectoriesInPath(String JavaDoc path)
594     {
595         ArrayList JavaDoc list = new ArrayList JavaDoc();
596         if (path != null) {
597             final char sep = LocalFile.getPathSeparatorChar();
598             int begin = 0;
599             int end;
600             do {
601                 end = path.indexOf(sep, begin);
602                 String JavaDoc dir;
603                 if (end < 0) {
604                     dir = path.substring(begin);
605                 } else {
606                     dir = path.substring(begin, end);
607                     begin = end + 1;
608                 }
609                 if (dir.length() != 0)
610                     list.add(dir);
611             } while (end >= 0);
612         }
613         return list;
614     }
615
616     // Looks for specified file in the source path and (if applicable) the
617
// include path.
618
public static File findFile(Editor editor, String JavaDoc filename)
619     {
620         final Buffer buffer = editor.getBuffer();
621         final File currentDirectory =
622             buffer != null ? buffer.getCurrentDirectory() : null;
623
624         // Look for .h files in the include path.
625
if (filename.toLowerCase().endsWith(".h")) {
626             String JavaDoc includePath;
627             if (buffer != null)
628                 includePath = buffer.getStringProperty(Property.INCLUDE_PATH);
629             else
630                 includePath = Editor.preferences().getStringProperty(Property.INCLUDE_PATH);
631             if (includePath != null) {
632                 File file = findFileInPath(filename, includePath, currentDirectory);
633                 if (file != null)
634                     return file;
635             }
636         }
637
638         // Try the source path.
639
String JavaDoc sourcePath;
640         if (buffer != null)
641             sourcePath = buffer.getStringProperty(Property.SOURCE_PATH);
642         else
643             sourcePath = Editor.preferences().getStringProperty(Property.SOURCE_PATH);
644         if (sourcePath != null) {
645             File file = findFileInPath(filename, sourcePath, currentDirectory);
646             if (file != null)
647                 return file;
648         }
649
650         // Try the source path of the default mode for the file we're looking
651
// for.
652
Mode mode = Editor.getModeList().getModeForFileName(filename);
653         if (mode != null) {
654             sourcePath = mode.getStringProperty(Property.SOURCE_PATH);
655             if (sourcePath != null) {
656                 File file = findFileInPath(filename, sourcePath, currentDirectory);
657                 if (file != null)
658                     return file;
659             }
660         }
661
662         // Try global source path.
663
sourcePath = Editor.preferences().getStringProperty(Property.SOURCE_PATH);
664         if (sourcePath != null) {
665             File file = findFileInPath(filename, sourcePath, currentDirectory);
666             if (file != null)
667                 return file;
668         }
669
670         return null;
671     }
672
673     // If parent directory exists, returns true; otherwise displays standard
674
// error dialog using context as title and returns false.
675
public static boolean checkParentDirectory(File file, String JavaDoc context)
676     {
677         File parent = file.getParentFile();
678         if (parent != null && parent.isDirectory())
679             return true;
680         FastStringBuffer sb = new FastStringBuffer("Invalid path \"");
681         sb.append(file.netPath());
682         sb.append('"');
683         MessageDialog.showMessageDialog(sb.toString(), context);
684         return false;
685     }
686
687     public static boolean isFilenameAbsolute(String JavaDoc filename)
688     {
689         final int length = filename.length();
690         if (length > 0) {
691             char c0 = filename.charAt(0);
692             if (c0 == '\\' || c0 == '/')
693                 return true;
694             if (length > 2) {
695                 if (Platform.isPlatformWindows()) {
696                     // Check for drive letter.
697
char c1 = filename.charAt(1);
698                     if (c1 == ':') {
699                         if (c0 >= 'a' && c0 <= 'z')
700                             return true;
701                         if (c0 >= 'A' && c0 <= 'Z')
702                             return true;
703                     }
704                 } else if (Platform.isPlatformUnix()) {
705                     if (filename.equals("~") || filename.startsWith("~/"))
706                         return true;
707                 }
708                 if (File.hasRemotePrefix(filename))
709                     return true;
710                 if (File.hasLocalPrefix(filename))
711                     return true;
712             }
713         }
714         return false;
715     }
716
717     // Helper for getFileType.
718
private static String JavaDoc getStringFromUnicodeBytes(byte[] bytes, int start,
719         int length, boolean isLittleEndian)
720     {
721         FastStringBuffer sb = new FastStringBuffer(length);
722         int i = start;
723         int limit = start + length;
724         while (i < limit - 1) {
725             byte b1 = bytes[i++];
726             byte b2 = bytes[i++];
727             if (isLittleEndian)
728                 sb.append((char) ((b2 << 16) + b1));
729             else
730                 sb.append((char) ((b1 << 16) + b2));
731         }
732         return sb.toString();
733     }
734
735     // Returns FILETYPE_UNKNOWN if file is null or does not exist.
736
public static int getFileType(File file)
737     {
738         if (file == null)
739             return FILETYPE_UNKNOWN;
740         int fileType = FILETYPE_UNKNOWN;
741         try {
742             InputStream JavaDoc in = file.getInputStream();
743             byte[] bytes = new byte[4096];
744             int bytesRead = in.read(bytes);
745             in.close();
746             boolean isUnicode = false;
747             boolean isLittleEndian = false;
748             if (bytesRead >= 2) {
749                 if (bytes[0] == (byte)0xfe && bytes[1] == (byte)0xff) {
750                     isUnicode = true;
751                     isLittleEndian = false;
752                 } else if (bytes[0] == (byte)0xff && bytes[1] == (byte)0xfe)
753                     isUnicode = true;
754             }
755             if (!isUnicode) {
756                 for (int i = 0; i < bytesRead; i++) {
757                     if (bytes[i] == 0) {
758                         fileType = FILETYPE_BINARY;
759                         break;
760                     }
761                 }
762             }
763             if (fileType == FILETYPE_BINARY) {
764                 if (bytesRead > 2) {
765                     if (bytes[0] == (byte) 0xd0 && bytes[1] == (byte) 0xcf)
766                         fileType = FILETYPE_WORD;
767                     else if (bytes[0] == (byte) 0xff && bytes[1] == (byte) 0xd8)
768                         fileType = FILETYPE_JPEG;
769                     else if (bytes[0] == (byte) 'P' && bytes[1] == 'K') {
770                         // Looks like a zip file.
771
try {
772                             ZipInputStream JavaDoc istream =
773                                 new ZipInputStream JavaDoc(file.getInputStream());
774                             fileType = FILETYPE_ZIP;
775                             istream.close();
776                         }
777                         catch (Exception JavaDoc e) {}
778                     } else {
779                         try {
780                             GZIPInputStream JavaDoc istream =
781                                 new GZIPInputStream JavaDoc(file.getInputStream());
782                             fileType = FILETYPE_GZIP;
783                             istream.close();
784                         }
785                         catch (IOException JavaDoc e) {}
786                     }
787                 }
788             } else {
789                 // Not binary.
790
fileType = FILETYPE_TEXT;
791                 String JavaDoc s;
792                 if (isUnicode)
793                     s = getStringFromUnicodeBytes(bytes, 2, bytesRead,
794                                                   isLittleEndian);
795                 else
796                     s = new String JavaDoc(bytes, 0, bytesRead);
797                 if (s.length() >= 3) {
798                     if (s.charAt(0) == '#' && s.charAt(1) == '!') {
799                         // Only consider the first line.
800
int index = s.indexOf('\n');
801                         if (index >= 0)
802                             s = s.substring(0, index);
803                         index = s.indexOf('\r');
804                         if (index >= 0)
805                             s = s.substring(0, index);
806                         if (s.indexOf("/bin/sh") >=0 ||
807                             s.indexOf("/bin/bash") >= 0 ||
808                             s.indexOf("/bin/tcsh") >= 0)
809                             fileType = FILETYPE_SHELLSCRIPT;
810                         else if (s.indexOf("/bin/perl") >= 0)
811                             fileType = FILETYPE_PERL;
812                     } else if (s.startsWith("<?xml")) {
813                         fileType = FILETYPE_XML;
814                     } else if (s.startsWith("<?php")) {
815                         fileType = FILETYPE_PHP;
816                     } else if (s.startsWith("<?") &&
817                         Character.isWhitespace(s.charAt(2))) {
818                         fileType = FILETYPE_PHP;
819                     }
820                 }
821             }
822         }
823         catch (Exception JavaDoc e) {}
824         return fileType;
825     }
826
827     public static boolean deleteRename(File source, File destination)
828     {
829         if (!source.isFile()) {
830             Log.warn("deleteRename source file " + source + " does not exist");
831             return false;
832         }
833         // The delete/rename operation sometimes fails on NT at first, but then
834
// succeeds later, so we do some retries here if necessary.
835
for (int i = 0; i < 5; i++) {
836             if (destination.exists())
837                 destination.delete();
838             if (source.renameTo(destination))
839                 return true;
840             Log.warn("deleteRename renameTo failed i = " + i);
841             System.gc();
842             try {
843                 Thread.sleep(100);
844             }
845             catch (InterruptedException JavaDoc ex) {}
846         }
847         // Last resort.
848
// We might not have delete rights in the destination directory. Try to
849
// overwrite the destination file in place.
850
Log.warn("deleteRename calling overwriteFile");
851         if (overwriteFile(source, destination)) {
852             source.delete();
853             return true;
854         }
855         Log.warn("deleteRename returning false");
856         return false;
857     }
858
859     public static boolean copyFile(File source, File destination)
860     {
861         if (!source.isFile()) {
862             Log.error("copyFile error - source is not a file: " + source);
863             return false;
864         }
865         if (destination.isDirectory()) {
866             Log.error("copyFile error - destination is a directory: " + destination);
867             return false;
868         }
869         if (destination.isFile() && !destination.canWrite()) {
870             Log.error("copyFile error - destination is read only: " + destination);
871             return false;
872         }
873         boolean error = false;
874         File tempFile = getTempFile(destination.getParent());
875         final long length = source.length();
876         long bytesCopied = 0;
877         InputStream JavaDoc in = null;
878         OutputStream JavaDoc out = null;
879         // Copy source to tempFile.
880
try {
881             in = source.getInputStream();
882             out = tempFile.getOutputStream();
883             final int bufsize = length < 32768 ? (int) length : 32768;
884             byte[] buffer = new byte[bufsize];
885             while (bytesCopied < length) {
886                 int bytesRead = in.read(buffer, 0, bufsize);
887                 if (bytesRead > 0) {
888                     out.write(buffer, 0, bytesRead);
889                     bytesCopied += bytesRead;
890                 } else
891                     break;
892             }
893         }
894         catch (IOException JavaDoc e) {
895             error = true;
896         }
897         try {
898             if (in != null)
899                 in.close();
900             if (out != null) {
901                 out.flush();
902                 out.close();
903             }
904         }
905         catch (IOException JavaDoc e) {
906             Log.error(e);
907             error = true;
908         }
909         if (error) {
910             Log.error("copyFile error");
911             tempFile.delete();
912             return false;
913         }
914         if (bytesCopied != length) {
915             Log.error("copyFile error - bytesCopied != length");
916             tempFile.delete();
917             return false;
918         }
919         if (destination.exists()) {
920             destination.delete();
921             if (destination.exists()) {
922                 // Unable to delete existing destination file.
923
Log.error("copyFile error - unable to delete existing destination file: " + destination);
924                 tempFile.delete();
925                 return false;
926             }
927         }
928         if (!tempFile.renameTo(destination)) {
929             Log.error("copyFile error - unable to rename temporary file");
930             Log.error("tempFile = " + tempFile.netPath());
931             Log.error("destination = " + destination.netPath());
932             tempFile.delete();
933             return false;
934         }
935         if (Platform.isPlatformUnix())
936             destination.setPermissions(source.getPermissions());
937         destination.setLastModified(source.lastModified());
938         return true; // Success!
939
}
940
941     private static boolean overwriteFile(File source, File destination)
942     {
943         if (!source.isFile())
944             return false;
945         boolean error = false;
946         long length = source.length();
947         long totalBytes = 0;
948         BufferedInputStream JavaDoc in = null;
949         BufferedOutputStream JavaDoc out = null;
950         try {
951             in = new BufferedInputStream JavaDoc(source.getInputStream());
952             out = new BufferedOutputStream JavaDoc(destination.getOutputStream());
953             final int bufsize = 4096;
954             byte[] buffer = new byte[bufsize];
955             while (totalBytes < length) {
956                 int numBytes = in.read(buffer, 0, bufsize);
957                 if (numBytes > 0) {
958                     out.write(buffer, 0, numBytes);
959                     totalBytes += numBytes;
960                 } else
961                     break;
962             }
963         }
964         catch (IOException JavaDoc e) {
965             Log.error(e);
966             error = true;
967         }
968
969         try {
970             if (in != null)
971                 in.close();
972             if (out != null) {
973                 out.flush();
974                 out.close();
975             }
976         }
977         catch (IOException JavaDoc e) {
978             Log.error(e);
979             error = true;
980         }
981         if (error)
982             return false;
983         if (totalBytes != length)
984             return false;
985         return true;
986     }
987
988     public static boolean makeBackup(File file, boolean keepOriginal)
989     {
990         return makeBackup(file, file.getName(), keepOriginal);
991     }
992
993     public static boolean makeBackup(File file, String JavaDoc name,
994         boolean keepOriginal)
995     {
996         // No need to back it up if it doesn't exist.
997
if (!file.isFile())
998             return true;
999         File backupDir = null;
1000        String JavaDoc backupDirectory =
1001            Editor.preferences().getStringProperty(Property.BACKUP_DIRECTORY);
1002        if (backupDirectory != null) {
1003            backupDir = File.getInstance(backupDirectory);
1004        } else {
1005            // Use default location.
1006
backupDir = File.getInstance(Directories.getUserHomeDirectory(),
1007                                         "backup");
1008        }
1009        if (backupDir == null)
1010            return false;
1011        if (!backupDir.isDirectory() && !backupDir.mkdirs()) {
1012            Log.error("can't create backup directory ".concat(backupDir.canonicalPath()));
1013            return false;
1014        }
1015        File backupFile = File.getInstance(backupDir, name);
1016        if (!keepOriginal) {
1017            if (backupFile.isFile() && !backupFile.delete())
1018                Log.error("can't delete old backupFile file ".concat(backupFile.toString()));
1019            if (file.renameTo(backupFile))
1020                return true;
1021        }
1022        if (copyFile(file, backupFile))
1023            return true;
1024        // If copyFile() failed because the existing backup file is not
1025
// writable, delete that file and try again.
1026
if (backupFile.isFile() && !backupFile.canWrite()) {
1027            Log.debug("deleting old backup file " + backupFile);
1028            backupFile.delete();
1029            Log.debug("retrying copyFile...");
1030            if (copyFile(file, backupFile))
1031                return true;
1032        }
1033        Log.error("makeBackup copyFile failed, returning false");
1034        return false;
1035    }
1036
1037    public static Color JavaDoc getColor(String JavaDoc s)
1038    {
1039        Color JavaDoc color = null;
1040        s = s.trim();
1041        if (s.equals("black"))
1042            color = Color.black;
1043        else if (s.equals("white"))
1044            color = Color.white;
1045        else if (s.equals("yellow"))
1046            color = Color.yellow;
1047        else if (s.equals("blue"))
1048            color = Color.blue;
1049        else if (s.equals("red"))
1050            color = Color.red;
1051        else if (s.equals("gray"))
1052            color = Color.gray;
1053        else if (s.equals("green"))
1054            color = Color.green;
1055        else {
1056            try {
1057                // The string must consist of three numbers for the R, G, B
1058
// components.
1059
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s);
1060                if (st.countTokens() == 3) {
1061                    int r = Integer.parseInt(st.nextToken());
1062                    int g = Integer.parseInt(st.nextToken());
1063                    int b = Integer.parseInt(st.nextToken());
1064                    color = new Color JavaDoc(r, g, b);
1065                }
1066            }
1067            catch (Exception JavaDoc e) {
1068                Log.error(e);
1069            }
1070        }
1071        return color;
1072    }
1073
1074    // BUG! Not really correct!
1075
private static final String JavaDoc filenameChars =
1076        "#-./0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ\\_abcdefghijklmnopqrstuvwxyz~";
1077
1078    public static boolean isFilenameChar(char c)
1079    {
1080        return (filenameChars.indexOf(c) >= 0);
1081    }
1082
1083    public static boolean isProcessAlive(Process JavaDoc process)
1084    {
1085        if (process == null)
1086            return false;
1087        try {
1088            process.exitValue();
1089            // If process is alive, we won't reach here.
1090
return false;
1091        }
1092        catch (IllegalThreadStateException JavaDoc e) {
1093            // If this exception is thrown, the process is still alive.
1094
return true;
1095        }
1096    }
1097
1098    public static void kill(int pid)
1099    {
1100        if (Platform.isPlatformUnix()) {
1101            try {
1102                String JavaDoc[] cmdarray = { "/bin/sh", "-c", "kill -9 " + pid };
1103                Process JavaDoc p = Runtime.getRuntime().exec(cmdarray);
1104                p.waitFor();
1105            }
1106            catch (Throwable JavaDoc t) {
1107                Log.error(t);
1108            }
1109        }
1110    }
1111
1112    private static int haveJpty = -1;
1113
1114    public static boolean haveJpty()
1115    {
1116        if (haveJpty == -1)
1117            haveJpty = have("jpty") ? 1 : 0;
1118        return haveJpty == 1;
1119    }
1120
1121    private static int haveLs = -1;
1122
1123    public static boolean haveLs()
1124    {
1125        if (haveLs == -1)
1126            haveLs = have("ls") ? 1 : 0;
1127        return haveLs == 1;
1128    }
1129
1130    public static boolean have(final String JavaDoc s)
1131    {
1132        try {
1133            final Process JavaDoc p = Runtime.getRuntime().exec(s);
1134            if (p != null) {
1135                Thread JavaDoc t = new Thread JavaDoc("Utilities.have(\"" + s + "\") destroy") {
1136                    public void run()
1137                    {
1138                        try {
1139                            final BufferedReader JavaDoc reader =
1140                                new BufferedReader JavaDoc(new InputStreamReader JavaDoc(p.getInputStream()));
1141                            while (reader.readLine() != null)
1142                                ;
1143                            p.getInputStream().close();
1144                            p.getOutputStream().close();
1145                            p.getErrorStream().close();
1146                        }
1147                        catch (IOException JavaDoc e) {
1148                            Log.error(e);
1149                        }
1150                        p.destroy();
1151                        try {
1152                            p.waitFor();
1153                        }
1154                        catch (InterruptedException JavaDoc e) {
1155                            Log.error(e);
1156                        }
1157                    }
1158                };
1159                t.setDaemon(true);
1160                t.setPriority(Thread.MIN_PRIORITY);
1161                t.start();
1162                return true;
1163            }
1164        }
1165        catch (Throwable JavaDoc t) {}
1166        return false;
1167    }
1168
1169    private static String JavaDoc userHome;
1170
1171    public static final void setUserHome(String JavaDoc s)
1172    {
1173        Debug.bugIfNot(userHome == null); // We only want to do this once!
1174
userHome = s;
1175    }
1176
1177    public static String JavaDoc getUserHome()
1178    {
1179        if (userHome == null) {
1180            if (Platform.isPlatformWindows()) {
1181                String JavaDoc[] cmdarray = {"bash", "-c", "echo $HOME"};
1182                String JavaDoc output = exec(cmdarray);
1183                if (output != null) {
1184                    output = output.trim();
1185                    if (output.length() > 0) {
1186                        if (output.indexOf('/') >= 0)
1187                            userHome = uncygnify(output);
1188                        else
1189                            userHome = output;
1190                    }
1191                }
1192            }
1193            if (userHome == null) {
1194                userHome = System.getProperty("user.home");
1195                // Expand links.
1196
File home = File.getInstance(userHome);
1197                if (home != null)
1198                    userHome = home.canonicalPath();
1199            }
1200        }
1201        return userHome;
1202    }
1203
1204    public static String JavaDoc cygnify(String JavaDoc s)
1205    {
1206        String JavaDoc[] cmdArray = {"cygpath", "-u", s};
1207        String JavaDoc converted = Utilities.exec(cmdArray);
1208        return converted != null ? converted : s;
1209    }
1210
1211    public static String JavaDoc uncygnify(String JavaDoc s)
1212    {
1213        String JavaDoc[] cmdArray = {"cygpath", "-w", s};
1214        String JavaDoc converted = Utilities.exec(cmdArray);
1215        return converted != null ? converted : s;
1216    }
1217
1218    public static String JavaDoc exec(String JavaDoc[] cmdarray)
1219    {
1220        try {
1221            Process JavaDoc process = Runtime.getRuntime().exec(cmdarray);
1222            BufferedReader JavaDoc reader =
1223                new BufferedReader JavaDoc(new InputStreamReader JavaDoc(process.getInputStream()));
1224            FastStringBuffer sb = new FastStringBuffer();
1225            String JavaDoc s;
1226            while ((s = reader.readLine()) != null) {
1227                if (s.length() > 0) {
1228                    if (sb.length() > 0)
1229                        sb.append('\n');
1230                    sb.append(s);
1231                }
1232            }
1233            process.getInputStream().close();
1234            process.getOutputStream().close();
1235            process.getErrorStream().close();
1236            process.waitFor();
1237            return sb.toString();
1238        }
1239        catch (Throwable JavaDoc t) {
1240            Log.error(t);
1241            return null;
1242        }
1243    }
1244
1245    public static ImageIcon JavaDoc getIconFromFile(String JavaDoc iconFile)
1246    {
1247        URL JavaDoc url = Editor.class.getResource("images/".concat(iconFile));
1248        if (url == null)
1249            return null;
1250        return new ImageIcon JavaDoc(url);
1251    }
1252
1253    // Parses integer from string. Parsing stops when we encounter a non-digit.
1254
public static int parseInt(String JavaDoc s) throws NumberFormatException JavaDoc
1255    {
1256        final int limit = s.length();
1257        int i;
1258        for (i = 0; i < limit; i++) {
1259            if (!Character.isDigit(s.charAt(i)))
1260                break;
1261        }
1262        if (i == 0) // No digit found.
1263
throw new NumberFormatException JavaDoc();
1264        return Integer.parseInt(s.substring(0, i));
1265    }
1266
1267    public static String JavaDoc rightJustify(int n, int fieldWidth)
1268    {
1269        String JavaDoc s = String.valueOf(n);
1270        int pad = fieldWidth - s.length();
1271        if (pad <= 0)
1272            return s;
1273        FastStringBuffer sb = new FastStringBuffer(spaces(pad));
1274        sb.append(s);
1275        return sb.toString();
1276    }
1277
1278    public static String JavaDoc rightJustify(String JavaDoc s, int fieldWidth)
1279    {
1280        int pad = fieldWidth - s.length();
1281        if (pad <= 0)
1282            return s;
1283        FastStringBuffer sb = new FastStringBuffer(spaces(pad));
1284        sb.append(s);
1285        return sb.toString();
1286    }
1287
1288    public static final boolean lookingAt(String JavaDoc s, int i, String JavaDoc pattern,
1289        boolean ignoreCase)
1290    {
1291        return s.regionMatches(ignoreCase, i, pattern, 0, pattern.length());
1292    }
1293
1294    public static boolean isOneOf(String JavaDoc s, String JavaDoc[] strings)
1295    {
1296        if (s != null) {
1297            for (int i = strings.length-1; i >= 0; i--)
1298                if (s.equals(strings[i]))
1299                    return true;
1300        }
1301        return false;
1302    }
1303
1304    private static final String JavaDoc SPACES;
1305    private static final int SPACES_LENGTH = 256;
1306
1307    static {
1308        char[] chars = new char[SPACES_LENGTH];
1309        for (int i = 0; i < SPACES_LENGTH; i++)
1310            chars[i] = ' ';
1311        SPACES = new String JavaDoc(chars);
1312    }
1313
1314    public static String JavaDoc spaces(int count)
1315    {
1316        if (count <= 0)
1317            return "";
1318        else if (count <= SPACES_LENGTH)
1319            return SPACES.substring(0, count);
1320        else {
1321            FastStringBuffer sb = new FastStringBuffer(count);
1322            for (int i = 0; i < count; i++)
1323                sb.append(' ');
1324            return sb.toString();
1325        }
1326    }
1327
1328    public static final String JavaDoc getCharsetFromContentType(String JavaDoc contentType)
1329    {
1330        if (contentType == null)
1331            return null;
1332        int index = contentType.toLowerCase().indexOf("charset=");
1333        if (index < 0)
1334            return null;
1335        String JavaDoc s = contentType.substring(index + 8);
1336        FastStringBuffer sb = new FastStringBuffer();
1337        boolean inQuote = false;
1338        for (int i = 0; i < s.length(); i++) {
1339            char c = s.charAt(i);
1340            if (i == 0 && c == '"') {
1341                inQuote = true;
1342                continue;
1343            }
1344            if (inQuote && c == '"')
1345                break; // Reached end of quoted string.
1346
if (!inQuote && c == ';')
1347                break; // Reached end of parameter value.
1348
sb.append(c); // Normal character.
1349
}
1350        return sb.toString();
1351    }
1352
1353    public static final String JavaDoc getEncodingFromCharset(String JavaDoc charset)
1354    {
1355        if (charset == null)
1356            return "iso-8859-1";
1357        String JavaDoc lower = charset.toLowerCase();
1358        if (lower.equals("unknown-8bit") ||
1359            lower.equals("x-unknown") ||
1360            lower.equals("us-ascii") ||
1361            lower.equals("default_charset") ||
1362            lower.equals("latin-iso8859-1"))
1363            return "iso-8859-1";
1364        return charset;
1365    }
1366
1367    public static boolean isSupportedEncoding(String JavaDoc encoding)
1368    {
1369        if (encoding != null) {
1370            try {
1371                "test".getBytes(encoding);
1372                return true;
1373            }
1374            catch (UnsupportedEncodingException JavaDoc e) {}
1375        }
1376        return false;
1377    }
1378
1379    // Extracts XML or HTML tag name (e.g. "a" or "/a") from string.
1380
public static String JavaDoc getTagName(String JavaDoc s)
1381    {
1382        Debug.assertTrue(s != null);
1383        Debug.assertTrue(s.length() > 0);
1384        Debug.assertTrue(s.charAt(0) == '<');
1385        int length = s.length();
1386        int start = 1;
1387        for (int i = start; i < length; i++) {
1388            switch (s.charAt(i)) {
1389                case ' ':
1390                case '>':
1391                case '\t':
1392                case '\n':
1393                case '\r':
1394                    return s.substring(start, i);
1395            }
1396        }
1397        return s;
1398    }
1399
1400    // Does not handle embedded single-quoted strings.
1401
public static List JavaDoc tokenize(String JavaDoc s)
1402    {
1403        ArrayList JavaDoc list = new ArrayList JavaDoc();
1404        if (s != null) {
1405            FastStringBuffer sb = new FastStringBuffer();
1406            boolean inQuote = false;
1407            final int limit = s.length();
1408            for (int i = 0; i < limit; i++) {
1409                char c = s.charAt(i);
1410                switch (c) {
1411                    case ' ':
1412                        if (inQuote)
1413                            sb.append(c);
1414                        else if (sb.length() > 0) {
1415                            list.add(sb.toString());
1416                            sb.setLength(0);
1417                        }
1418                        break;
1419                    case '"':
1420                        if (inQuote) {
1421                            if (sb.length() > 0) {
1422                                list.add(sb.toString());
1423                                sb.setLength(0);
1424                            }
1425                            inQuote = false;
1426                        } else
1427                            inQuote = true;
1428                        break;
1429                    default:
1430                        sb.append(c);
1431                        break;
1432                }
1433            }
1434            if (sb.length() > 0)
1435                list.add(sb.toString());
1436        }
1437        return list;
1438    }
1439
1440    public static String JavaDoc getFirstIdentifier(String JavaDoc s, Mode mode)
1441    {
1442        FastStringBuffer sb = new FastStringBuffer();
1443        int length = s.length();
1444        if (length > 0) {
1445            char c = s.charAt(0);
1446            if (mode.isIdentifierStart(c)) {
1447                sb.append(c);
1448                for (int i = 1; i < length; i++) {
1449                    c = s.charAt(i);
1450                    if (mode.isIdentifierPart(c))
1451                        sb.append(c);
1452                    else
1453                        break;
1454                }
1455            }
1456        }
1457        return sb.toString();
1458    }
1459
1460    public static KeyStroke JavaDoc getKeyStroke(String JavaDoc keyText)
1461    {
1462        if (keyText == null)
1463            return null;
1464        keyText = keyText.trim();
1465        if (keyText.length() == 0)
1466            return null;
1467        if (keyText.startsWith("'")) {
1468            if (keyText.length() != 3)
1469                return null;
1470            if (keyText.charAt(2) != '\'')
1471                return null;
1472            return KeyStroke.getKeyStroke(keyText.charAt(1));
1473        }
1474        int modifiers = 0;
1475        while (true) {
1476            if (keyText.startsWith("Ctrl ") || keyText.startsWith("Ctrl\t")) {
1477                modifiers |= CTRL_MASK;
1478                keyText = keyText.substring(5).trim();
1479                continue;
1480            }
1481            if (keyText.startsWith("Shift ") || keyText.startsWith("Shift\t")) {
1482                modifiers |= SHIFT_MASK;
1483                keyText = keyText.substring(6).trim();
1484                continue;
1485            }
1486            if (keyText.startsWith("Alt ") || keyText.startsWith("Alt\t")){
1487                modifiers |= ALT_MASK;
1488                keyText = keyText.substring(4).trim();
1489                continue;
1490            }
1491            if (keyText.startsWith("Meta ") || keyText.startsWith("Meta\t")){
1492                modifiers |= META_MASK;
1493                keyText = keyText.substring(5).trim();
1494                continue;
1495            }
1496            // No more modifiers. What's left is the key name.
1497
break;
1498        }
1499        if (modifiers == 0 && keyText.length() == 1) {
1500            char c = keyText.charAt(0);
1501            return KeyStroke.getKeyStroke(c);
1502        }
1503        if (modifiers == SHIFT_MASK && keyText.length() == 1) {
1504            char c = keyText.charAt(0);
1505            char lower = Character.toLowerCase(c);
1506            char upper = Character.toUpperCase(c);
1507            if (lower != upper)
1508                return KeyStroke.getKeyStroke(upper);
1509        }
1510        int keyCode = getKeyCode(keyText);
1511        if (keyCode == 0)
1512            return null;
1513        return KeyStroke.getKeyStroke(keyCode, modifiers);
1514    }
1515
1516    public static final String JavaDoc getKeyText(KeyStroke JavaDoc keyStroke)
1517    {
1518        return getKeyText(keyStroke.getKeyChar(), keyStroke.getKeyCode(), keyStroke.getModifiers());
1519    }
1520
1521    public static String JavaDoc getKeyText(char keyChar, int keyCode, int modifiers)
1522    {
1523        FastStringBuffer sb = new FastStringBuffer();
1524        if (keyChar != 0 && keyChar != 0xffff) {
1525            // Mapping is defined by character.
1526
if (keyChar >= 'A' && keyChar <= 'Z') {
1527                sb.append("Shift ");
1528                sb.append(keyChar);
1529            } else {
1530                sb.append('\'');
1531                sb.append(keyChar);
1532                sb.append('\'');
1533            }
1534        } else {
1535            // Mapping is defined by key code and modifiers.
1536
if ((modifiers & CTRL_MASK) != 0)
1537                sb.append("Ctrl ");
1538            if ((modifiers & SHIFT_MASK) != 0)
1539                sb.append("Shift ");
1540            if ((modifiers & ALT_MASK) != 0)
1541                sb.append("Alt ");
1542            if ((modifiers & META_MASK) != 0)
1543                sb.append("Meta ");
1544            sb.append(getKeyName(keyCode));
1545        }
1546        return sb.toString();
1547    }
1548
1549    private static String JavaDoc[] keyNames = {
1550        "Enter",
1551        "Backspace",
1552        "Tab",
1553        "Escape",
1554        "Space",
1555        "Page Up",
1556        "Page Down",
1557        "Home",
1558        "End",
1559        "Delete",
1560        "Left",
1561        "Right",
1562        "Up",
1563        "Down",
1564        "NumPad Left",
1565        "NumPad Right",
1566        "NumPad Up",
1567        "NumPad Down",
1568        "NumPad *",
1569        "NumPad +",
1570        "NumPad -",
1571        "NumPad Insert",
1572        "Mouse-1",
1573        "Double Mouse-1",
1574        "Mouse-2",
1575        "Double Mouse-2",
1576        "Mouse-3",
1577        "Double Mouse-3"
1578    };
1579
1580    private static int[] keyCodes = {
1581        KeyEvent.VK_ENTER,
1582        KeyEvent.VK_BACK_SPACE,
1583        KeyEvent.VK_TAB,
1584        KeyEvent.VK_ESCAPE,
1585        KeyEvent.VK_SPACE,
1586        KeyEvent.VK_PAGE_UP,
1587        KeyEvent.VK_PAGE_DOWN,
1588        KeyEvent.VK_HOME,
1589        KeyEvent.VK_END,
1590        KeyEvent.VK_DELETE,
1591        KeyEvent.VK_LEFT,
1592        KeyEvent.VK_RIGHT,
1593        KeyEvent.VK_UP,
1594        KeyEvent.VK_DOWN,
1595        KeyEvent.VK_KP_LEFT,
1596        KeyEvent.VK_KP_RIGHT,
1597        KeyEvent.VK_KP_UP,
1598        KeyEvent.VK_KP_DOWN,
1599        0x6a,
1600        0x6b,
1601        0x6d,
1602        0x9b,
1603        VK_MOUSE_1,
1604        VK_DOUBLE_MOUSE_1,
1605        VK_MOUSE_2,
1606        VK_DOUBLE_MOUSE_2,
1607        VK_MOUSE_3,
1608        VK_DOUBLE_MOUSE_3
1609    };
1610
1611    private static int getKeyCode(String JavaDoc keyName)
1612    {
1613        if (keyName.length() == 0)
1614            return 0;
1615        if (keyName.length() == 1)
1616            return (int) keyName.charAt(0);
1617        if (keyName.startsWith("0x")) {
1618            try {
1619                return Integer.parseInt(keyName.substring(2), 16);
1620            }
1621            catch (NumberFormatException JavaDoc e) {
1622                Log.error(e);
1623            }
1624            return 0;
1625        }
1626        for (int i = 0; i < keyNames.length; i++) {
1627            if (keyName.equals(keyNames[i]))
1628                return keyCodes[i];
1629        }
1630        if (keyName.charAt(0) == 'F') {
1631            try {
1632                int n = Integer.parseInt(keyName.substring(1));
1633                return KeyEvent.VK_F1 + n - 1;
1634            }
1635            catch (NumberFormatException JavaDoc e) {
1636                Log.error(e);
1637            }
1638        }
1639        return 0;
1640    }
1641
1642    private static String JavaDoc getKeyName(int keyCode)
1643    {
1644        if (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_9 || keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z)
1645            return String.valueOf((char) keyCode);
1646        if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12)
1647            return "F" + Integer.toString(keyCode - KeyEvent.VK_F1 + 1);
1648        if (",./;=[\\]".indexOf(keyCode) >= 0)
1649            return String.valueOf((char) keyCode);
1650        for (int i = 0; i < keyCodes.length; i++){
1651            if (keyCode == keyCodes[i])
1652                return keyNames[i];
1653        }
1654        return "0x" + Integer.toString(keyCode, 16);
1655    }
1656
1657    public static String JavaDoc propertyToXml(String JavaDoc name, String JavaDoc value)
1658    {
1659        FastStringBuffer sb = new FastStringBuffer("<property name=\"");
1660        sb.append(name);
1661        sb.append("\" value=\"");
1662        sb.append(value);
1663        sb.append("\"/>");
1664        return sb.toString();
1665    }
1666
1667    public static JPanel JavaDoc createPanel(String JavaDoc title)
1668    {
1669        JPanel JavaDoc panel = new JPanel JavaDoc();
1670        panel.setLayout(new BoxLayout JavaDoc(panel, BoxLayout.Y_AXIS));
1671        Border JavaDoc border =
1672            new TitledBorder JavaDoc(BorderFactory.createEtchedBorder(), title) {
1673            public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y,
1674                                    int width, int height)
1675            {
1676                Display.setRenderingHints(g);
1677                super.paintBorder(c, g, x, y, width, height);
1678            }
1679        };
1680        panel.setBorder(border);
1681        return panel;
1682    }
1683
1684    private static String JavaDoc defaultXMLReaderImpl;
1685    static {
1686        if (Platform.isJava14()) {
1687            // Sun/Blackdown 1.4.x.
1688
defaultXMLReaderImpl =
1689                "org.apache.crimson.parser.XMLReaderImpl";
1690        } else {
1691            // 1.5
1692
defaultXMLReaderImpl =
1693                "com.sun.org.apache.xerces.internal.parsers.SAXParser";
1694        }
1695    }
1696
1697    public static synchronized XMLReader JavaDoc getDefaultXMLReader()
1698    {
1699        if (defaultXMLReaderImpl != null) {
1700            try {
1701                return XMLReaderFactory.createXMLReader(defaultXMLReaderImpl);
1702            }
1703            catch (Exception JavaDoc e) {
1704                // Not available (IBM 1.4.0/1.4.1).
1705
Log.debug(defaultXMLReaderImpl + " is not available");
1706                // Don't use this code path again!
1707
defaultXMLReaderImpl = null;
1708                // Fall through...
1709
}
1710        }
1711        try {
1712            // This should work with IBM 1.4.0/1.4.1.
1713
return XMLReaderFactory.createXMLReader();
1714        }
1715        catch (Throwable JavaDoc t) {
1716            // We've got a real problem...
1717
Log.error(t);
1718            return null;
1719        }
1720    }
1721}
1722
Popular Tags