KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > MiscUtilities


1 /*
2  * MiscUtilities.java - Various miscallaneous utility functions
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 1999, 2005 Slava Pestov
7  * Portions copyright (C) 2000 Richard S. Hall
8  * Portions copyright (C) 2001 Dirk Moebius
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  */

24
25 package org.gjt.sp.jedit;
26
27 //{{{ Imports
28
import javax.swing.text.Segment JavaDoc;
29 import javax.swing.JMenuItem JavaDoc;
30 import java.io.*;
31 import java.net.MalformedURLException JavaDoc;
32 import java.net.URL JavaDoc;
33 import java.nio.charset.Charset JavaDoc;
34 import java.text.DecimalFormat JavaDoc;
35 import java.util.*;
36 import java.util.regex.Matcher JavaDoc;
37 import java.util.regex.Pattern JavaDoc;
38 import java.util.zip.GZIPInputStream JavaDoc;
39
40 import org.xml.sax.InputSource JavaDoc;
41 import org.xml.sax.helpers.DefaultHandler JavaDoc;
42
43 import org.gjt.sp.jedit.io.*;
44 import org.gjt.sp.util.Log;
45 import org.gjt.sp.util.ProgressObserver;
46 import org.gjt.sp.util.StandardUtilities;
47 import org.gjt.sp.util.IOUtilities;
48 import org.gjt.sp.util.XMLUtilities;
49 import org.gjt.sp.jedit.menu.EnhancedMenuItem;
50 import org.gjt.sp.jedit.bufferio.BufferIORequest;
51 import org.gjt.sp.jedit.buffer.JEditBuffer;
52 //}}}
53

54 /**
55  * Path name manipulation, string manipulation, and more.<p>
56  *
57  * The most frequently used members of this class are:<p>
58  *
59  * <b>Some path name methods:</b><p>
60  * <ul>
61  * <li>{@link #getFileName(String)}</li>
62  * <li>{@link #getParentOfPath(String)}</li>
63  * <li>{@link #constructPath(String,String)}</li>
64  * </ul>
65  * <b>String comparison:</b><p>
66
67  * A {@link #compareStrings(String,String,boolean)} method that unlike
68  * <function>String.compareTo()</function>, correctly recognizes and handles
69  * embedded numbers.<p>
70  *
71  * This class also defines several inner classes for use with the
72  * sorting features of the Java collections API:
73  *
74  * <ul>
75  * <li>{@link MiscUtilities.StringCompare}</li>
76  * <li>{@link MiscUtilities.StringICaseCompare}</li>
77  * <li>{@link MiscUtilities.MenuItemCompare}</li>
78  * </ul>
79  *
80  * For example, you might call:<p>
81  *
82  * <code>Arrays.sort(myListOfStrings,
83  * new MiscUtilities.StringICaseCompare());</code>
84  *
85  * @author Slava Pestov
86  * @author John Gellene (API documentation)
87  * @version $Id: MiscUtilities.java 8687 2007-01-20 10:07:37Z vampire0 $
88  */

89 public class MiscUtilities
90 {
91     /**
92      * This encoding is not supported by Java, yet it is useful.
93      * A UTF-8 file that begins with 0xEFBBBF.
94      */

95     public static final String JavaDoc UTF_8_Y = "UTF-8Y";
96
97     //{{{ Path name methods
98

99     //{{{ canonPath() method
100
/**
101      * Returns the canonical form of the specified path name. Currently
102      * only expands a leading <code>~</code>. <b>For local path names
103      * only.</b>
104      * @param path The path name
105      * @since jEdit 4.0pre2
106      */

107     public static String JavaDoc canonPath(String JavaDoc path)
108     {
109         if(path.length() == 0)
110             return path;
111
112         if(path.startsWith("file://"))
113             path = path.substring("file://".length());
114         else if(path.startsWith("file:"))
115             path = path.substring("file:".length());
116         else if(isURL(path))
117             return path;
118
119         if(File.separatorChar == '\\')
120         {
121                 // get rid of mixed paths on Windows
122
path = path.replace('/','\\');
123                 // also get rid of trailing spaces on Windows
124
int trim = path.length();
125                 while(path.charAt(trim - 1) == ' ')
126                     trim--;
127
128                 if (path.charAt(trim - 1) == '\\')
129                     while (trim > 1 && path.charAt(trim - 2) == '\\')
130                     {
131                         trim--;
132                     }
133                 path = path.substring(0,trim);
134         }
135         else if(OperatingSystem.isMacOS())
136         {
137             // do the same on OS X
138
path = path.replace(':','/');
139         }
140
141         if(path.startsWith('~' + File.separator))
142         {
143             path = path.substring(2);
144             String JavaDoc home = System.getProperty("user.home");
145
146             if(home.endsWith(File.separator))
147                 return home + path;
148             else
149                 return home + File.separator + path;
150         }
151         else if(path.equals("~"))
152             return System.getProperty("user.home");
153         else
154             return path;
155     } //}}}
156

157     //{{{ expandVariables() method
158
static final String JavaDoc varPatternString = "(\\$([a-zA-Z0-9_]+))";
159     static final String JavaDoc varPatternString2 = "(\\$\\{([^}]+)\\})";
160     static final Pattern JavaDoc varPattern = Pattern.compile(varPatternString);
161     static final Pattern JavaDoc varPattern2 = Pattern.compile(varPatternString2);
162
163     /** Accepts a string from the user which may contain variables of various syntaxes.
164      * The goal is to support the following:
165      * $varname
166      * ${varname}
167      * And expand each of these by looking at the system environment variables for possible
168      * expansions.
169      * @return a string which is either the unchanged input string, or one with expanded variables.
170      * @since 4.3pre7
171      * @author ezust
172      */

173     public static String JavaDoc expandVariables(String JavaDoc arg)
174     {
175         Pattern JavaDoc p = varPattern;
176         Matcher JavaDoc m = p.matcher(arg);
177         if (!m.find())
178         {
179             p = varPattern2;
180             m = p.matcher(arg);
181             if (!m.find()) // no variables to substitute
182
return arg;
183         }
184         String JavaDoc varName = m.group(2);
185         String JavaDoc expansion = System.getenv(varName);
186         if (expansion == null)
187         { // try everything uppercase?
188
varName = varName.toUpperCase();
189             String JavaDoc uparg = arg.toUpperCase();
190             m = p.matcher(uparg);
191             expansion = System.getenv(varName);
192         }
193         if (expansion != null)
194         {
195             expansion = expansion.replace("\\", "\\\\");
196             return m.replaceFirst(expansion);
197         }
198         return arg;
199     } //}}}
200

201     //{{{ resolveSymlinks() method
202
/**
203      * Resolves any symbolic links in the path name specified
204      * using <code>File.getCanonicalPath()</code>. <b>For local path
205      * names only.</b>
206      * @since jEdit 4.2pre1
207      */

208     public static String JavaDoc resolveSymlinks(String JavaDoc path)
209     {
210         if(isURL(path))
211             return path;
212
213         // 2 aug 2003: OS/2 Java has a broken getCanonicalPath()
214
if(OperatingSystem.isOS2())
215             return path;
216         // 18 nov 2003: calling this on a drive letter on Windows causes
217
// drive access
218
if(OperatingSystem.isDOSDerived())
219             {
220                 if(path.length() == 2 || path.length() == 3)
221                     {
222                         if(path.charAt(1) == ':')
223                             return path;
224                     }
225             }
226         try
227             {
228                 return new File(path).getCanonicalPath();
229             }
230         catch(IOException io)
231             {
232                 return path;
233             }
234     } //}}}
235

236     //{{{ isAbsolutePath() method
237
/**
238      * Returns if the specified path name is an absolute path or URL.
239      * @since jEdit 4.1pre11
240      */

241     public static boolean isAbsolutePath(String JavaDoc path)
242     {
243         if(isURL(path))
244             return true;
245         else if(path.startsWith("~/") || path.startsWith("~" + File.separator) || path.equals("~"))
246             return true;
247         else if(OperatingSystem.isDOSDerived())
248             {
249                 if(path.length() == 2 && path.charAt(1) == ':')
250                     return true;
251                 if(path.length() > 2 && path.charAt(1) == ':'
252                     && (path.charAt(2) == '\\'
253                         || path.charAt(2) == '/'))
254                     return true;
255                 if(path.startsWith("\\\\")
256                     || path.startsWith("//"))
257                     return true;
258             }
259         // not sure if this is correct for OpenVMS.
260
else if(OperatingSystem.isUnix()
261                 || OperatingSystem.isVMS())
262             {
263                 // nice and simple
264
if(path.length() > 0 && path.charAt(0) == '/')
265                     return true;
266             }
267
268         return false;
269     } //}}}
270

271     //{{{ constructPath() method
272
/**
273      * Constructs an absolute path name from a directory and another
274      * path name. This method is VFS-aware.
275      * @param parent The directory
276      * @param path The path name
277      */

278     public static String JavaDoc constructPath(String JavaDoc parent, String JavaDoc path)
279     {
280         if(isAbsolutePath(path))
281             return canonPath(path);
282
283         // have to handle this case specially on windows.
284
// insert \ between, eg A: and myfile.txt.
285
if(OperatingSystem.isDOSDerived())
286             {
287                 if(path.length() == 2 && path.charAt(1) == ':')
288                     return path;
289                 else if(path.length() > 2 && path.charAt(1) == ':'
290                         && path.charAt(2) != '\\')
291                     {
292                         path = path.substring(0,2) + '\\'
293                             + path.substring(2);
294                         return canonPath(path);
295                     }
296             }
297
298         String JavaDoc dd = ".." + File.separator;
299         String JavaDoc d = '.' + File.separator;
300
301         if(parent == null)
302             parent = System.getProperty("user.dir");
303
304         for(;;)
305             {
306                 if(path.equals("."))
307                     return parent;
308                 else if(path.equals(".."))
309                     return getParentOfPath(parent);
310                 else if(path.startsWith(dd) || path.startsWith("../"))
311                     {
312                         parent = getParentOfPath(parent);
313                         path = path.substring(3);
314                     }
315                 else if(path.startsWith(d) || path.startsWith("./"))
316                     path = path.substring(2);
317                 else
318                     break;
319             }
320
321         if(OperatingSystem.isDOSDerived()
322             && !isURL(parent)
323         && path.charAt(0) == '\\')
324             parent = parent.substring(0,2);
325
326         VFS vfs = VFSManager.getVFSForPath(parent);
327
328         return canonPath(vfs.constructPath(parent,path));
329     } //}}}
330

331     //{{{ constructPath() method
332
/**
333      * Constructs an absolute path name from three path components.
334      * This method is VFS-aware.
335      * @param parent The parent directory
336      * @param path1 The first path
337      * @param path2 The second path
338      */

339     public static String JavaDoc constructPath(String JavaDoc parent,
340                     String JavaDoc path1, String JavaDoc path2)
341     {
342         return constructPath(constructPath(parent,path1),path2);
343     } //}}}
344

345     //{{{ concatPath() method
346
/**
347      * Like {@link #constructPath}, except <code>path</code> will be
348      * appended to <code>parent</code> even if it is absolute.
349      * <b>For local path names only.</b>.
350      *
351      * @param path
352      * @param parent
353      */

354     public static String JavaDoc concatPath(String JavaDoc parent, String JavaDoc path)
355     {
356         parent = canonPath(parent);
357         path = canonPath(path);
358
359         // Make all child paths relative.
360
if (path.startsWith(File.separator))
361             path = path.substring(1);
362         else if ((path.length() >= 3) && (path.charAt(1) == ':'))
363             path = path.replace(':', File.separatorChar);
364
365         if (parent == null)
366             parent = System.getProperty("user.dir");
367
368         if (parent.endsWith(File.separator))
369             return parent + path;
370         else
371             return parent + File.separator + path;
372     } //}}}
373

374     //{{{ getFirstSeparatorIndex() method
375
/**
376      * Return the first index of either / or the OS-specific file
377      * separator.
378      * @param path The path
379      * @since jEdit 4.3pre3
380      */

381     public static int getFirstSeparatorIndex(String JavaDoc path)
382     {
383         int start = getPathStart(path);
384         int index = path.indexOf('/',start);
385         if(index == -1)
386             index = path.indexOf(File.separatorChar,start);
387         return index;
388     } //}}}
389

390     //{{{ getLastSeparatorIndex() method
391
/**
392      * Return the last index of either / or the OS-specific file
393      * separator.
394      * @param path The path
395      * @since jEdit 4.3pre3
396      */

397     public static int getLastSeparatorIndex(String JavaDoc path)
398     {
399         int start = getPathStart(path);
400         if(start != 0)
401             path = path.substring(start);
402         int index = Math.max(path.lastIndexOf('/'),
403                              path.lastIndexOf(File.separatorChar));
404         if(index == -1)
405             return index;
406         else
407             return index + start;
408     } //}}}
409

410     //{{{ getFileExtension() method
411
/**
412      * Returns the extension of the specified filename, or an empty
413      * string if there is none.
414      * @param path The path
415      */

416     public static String JavaDoc getFileExtension(String JavaDoc path)
417     {
418         int fsIndex = getLastSeparatorIndex(path);
419         int index = path.indexOf('.',fsIndex);
420         if(index == -1)
421             return "";
422         else
423             return path.substring(index);
424     } //}}}
425

426     //{{{ getFileName() method
427
/**
428      * Returns the last component of the specified path.
429      * This method is VFS-aware.
430      * @param path The path name
431      */

432     public static String JavaDoc getFileName(String JavaDoc path)
433     {
434         return VFSManager.getVFSForPath(path).getFileName(path);
435     } //}}}
436

437     //{{{ getFileNameNoExtension() method
438
/**
439      * Returns the last component of the specified path name without the
440      * trailing extension (if there is one).
441      * @param path The path name
442      * @since jEdit 4.0pre8
443      */

444     public static String JavaDoc getFileNameNoExtension(String JavaDoc path)
445     {
446         String JavaDoc name = getFileName(path);
447         int index = name.indexOf('.');
448         if(index == -1)
449             return name;
450         else
451             return name.substring(0,index);
452     } //}}}
453

454     //{{{ getFileParent() method
455
/**
456      * @deprecated Call getParentOfPath() instead
457      */

458     @Deprecated JavaDoc
459     public static String JavaDoc getFileParent(String JavaDoc path)
460     {
461         return getParentOfPath(path);
462     } //}}}
463

464     //{{{ getParentOfPath() method
465
/**
466      * Returns the parent of the specified path. This method is VFS-aware.
467      * @param path The path name
468      * @since jEdit 2.6pre5
469      */

470     public static String JavaDoc getParentOfPath(String JavaDoc path)
471     {
472         return VFSManager.getVFSForPath(path).getParentOfPath(path);
473     } //}}}
474

475     //{{{ getFileProtocol() method
476
/**
477      * @deprecated Call getProtocolOfURL() instead
478      */

479     @Deprecated JavaDoc
480     public static String JavaDoc getFileProtocol(String JavaDoc url)
481     {
482         return getProtocolOfURL(url);
483     } //}}}
484

485     //{{{ getProtocolOfURL() method
486
/**
487      * Returns the protocol specified by a URL.
488      * @param url The URL
489      * @since jEdit 2.6pre5
490      */

491     public static String JavaDoc getProtocolOfURL(String JavaDoc url)
492     {
493         return url.substring(0,url.indexOf(':'));
494     } //}}}
495

496     //{{{ isURL() method
497
/**
498      * Checks if the specified string is a URL.
499      * @param str The string to check
500      * @return True if the string is a URL, false otherwise
501      */

502     public static boolean isURL(String JavaDoc str)
503     {
504         int fsIndex = getLastSeparatorIndex(str);
505         if(fsIndex == 0) // /etc/passwd
506
return false;
507         else if(fsIndex == 2) // C:\AUTOEXEC.BAT
508
return false;
509
510         int cIndex = str.indexOf(':');
511         if(cIndex <= 1) // D:\WINDOWS, or doesn't contain : at all
512
return false;
513
514         String JavaDoc protocol = str.substring(0,cIndex);
515         VFS vfs = VFSManager.getVFSForProtocol(protocol);
516         if(vfs != null && !(vfs instanceof UrlVFS))
517             return true;
518
519         try
520             {
521                 new URL JavaDoc(str);
522                 return true;
523             }
524         catch(MalformedURLException JavaDoc mf)
525             {
526                 return false;
527             }
528     } //}}}
529

530     //{{{ saveBackup() method
531
/**
532      * Saves a backup (optionally numbered) of a file.
533      * @param file A local file
534      * @param backups The number of backups. Must be >= 1. If > 1, backup
535      * files will be numbered.
536      * @param backupPrefix The backup file name prefix
537      * @param backupSuffix The backup file name suffix
538      * @param backupDirectory The directory where to save backups; if null,
539      * they will be saved in the same directory as the file itself.
540      * @since jEdit 4.0pre1
541      */

542     public static void saveBackup(File file, int backups,
543                                   String JavaDoc backupPrefix, String JavaDoc backupSuffix,
544                                   String JavaDoc backupDirectory)
545     {
546         saveBackup(file,backups,backupPrefix,backupSuffix,backupDirectory,0);
547     } //}}}
548

549     //{{{ saveBackup() method
550
/**
551      * Saves a backup (optionally numbered) of a file.
552      * @param file A local file
553      * @param backups The number of backups. Must be >= 1. If > 1, backup
554      * files will be numbered.
555      * @param backupPrefix The backup file name prefix
556      * @param backupSuffix The backup file name suffix
557      * @param backupDirectory The directory where to save backups; if null,
558      * they will be saved in the same directory as the file itself.
559      * @param backupTimeDistance The minimum time in minutes when a backup
560      * version 1 shall be moved into version 2; if 0, backups are always
561      * moved.
562      * @since jEdit 4.2pre5
563      */

564     public static void saveBackup(File file, int backups,
565                    String JavaDoc backupPrefix, String JavaDoc backupSuffix,
566                    String JavaDoc backupDirectory, int backupTimeDistance)
567     {
568         if(backupPrefix == null)
569             backupPrefix = "";
570         if(backupSuffix == null)
571             backupSuffix = "";
572
573         String JavaDoc name = file.getName();
574
575         // If backups is 1, create ~ file
576
if(backups == 1)
577             {
578                 File backupFile = new File(backupDirectory,
579                                            backupPrefix + name + backupSuffix);
580                 long modTime = backupFile.lastModified();
581                 /* if backup file was created less than
582                  * 'backupTimeDistance' ago, we do not
583                  * create the backup */

584                 if(System.currentTimeMillis() - modTime
585                    >= backupTimeDistance)
586                     {
587                         backupFile.delete();
588                         if (!file.renameTo(backupFile))
589                             IOUtilities.moveFile(file, backupFile);
590                     }
591             }
592         // If backups > 1, move old ~n~ files, create ~1~ file
593
else
594             {
595                 /* delete a backup created using above method */
596                 new File(backupDirectory,
597                          backupPrefix + name + backupSuffix
598                          + backups + backupSuffix).delete();
599
600                 File firstBackup = new File(backupDirectory,
601                                             backupPrefix + name + backupSuffix
602                                             + "1" + backupSuffix);
603                 long modTime = firstBackup.lastModified();
604                 /* if backup file was created less than
605                  * 'backupTimeDistance' ago, we do not
606                  * create the backup */

607                 if(System.currentTimeMillis() - modTime
608                    >= backupTimeDistance)
609                     {
610                         for(int i = backups - 1; i > 0; i--)
611                             {
612                                 File backup = new File(backupDirectory,
613                                                        backupPrefix + name
614                                                        + backupSuffix + i
615                                                        + backupSuffix);
616
617                                 backup.renameTo(
618                                                 new File(backupDirectory,
619                                                          backupPrefix + name
620                                                          + backupSuffix + (i+1)
621                                                          + backupSuffix));
622                             }
623
624                         File backupFile = new File(backupDirectory,
625                                                    backupPrefix + name + backupSuffix
626                                                    + "1" + backupSuffix);
627                         if (!file.renameTo(backupFile))
628                             IOUtilities.moveFile(file, backupFile);
629                     }
630             }
631     } //}}}
632

633     //{{{ moveFile() method
634
/**
635      * Moves the source file to the destination.
636      *
637      * If the destination cannot be created or is a read-only file, the
638      * method returns <code>false</code>. Otherwise, the contents of the
639      * source are copied to the destination, the source is deleted,
640      * and <code>true</code> is returned.
641      *
642      * @param source The source file to move.
643      * @param dest The destination where to move the file.
644      * @return true on success, false otherwise.
645      *
646      * @since jEdit 4.3pre1
647      * @deprecated use {@link org.gjt.sp.util.IOUtilities#moveFile(java.io.File, java.io.File)}
648      */

649     @Deprecated JavaDoc
650     public static boolean moveFile(File source, File dest)
651     {
652         return IOUtilities.moveFile(source, dest);
653     } //}}}
654

655     //{{{ copyStream() method
656
/**
657      * Copy an input stream to an output stream.
658      *
659      * @param bufferSize the size of the buffer
660      * @param progress the progress observer it could be null
661      * @param in the input stream
662      * @param out the output stream
663      * @param canStop if true, the copy can be stopped by interrupting the thread
664      * @return <code>true</code> if the copy was done, <code>false</code> if it was interrupted
665      * @throws IOException IOException If an I/O error occurs
666      * @since jEdit 4.3pre3
667      * @deprecated use {@link IOUtilities#copyStream(int, org.gjt.sp.util.ProgressObserver, java.io.InputStream, java.io.OutputStream, boolean)}
668      */

669     @Deprecated JavaDoc
670     public static boolean copyStream(int bufferSize, ProgressObserver progress,
671                                      InputStream JavaDoc in, OutputStream out, boolean canStop)
672         throws IOException
673     {
674         return IOUtilities.copyStream(bufferSize, progress, in, out, canStop);
675     } //}}}
676

677     //{{{ copyStream() method
678
/**
679      * Copy an input stream to an output stream with a buffer of 4096 bytes.
680      *
681      * @param progress the progress observer it could be null
682      * @param in the input stream
683      * @param out the output stream
684      * @param canStop if true, the copy can be stopped by interrupting the thread
685      * @return <code>true</code> if the copy was done, <code>false</code> if it was interrupted
686      * @throws IOException IOException If an I/O error occurs
687      * @since jEdit 4.3pre3
688      * @deprecated use {@link IOUtilities#copyStream(org.gjt.sp.util.ProgressObserver, java.io.InputStream, java.io.OutputStream, boolean)}
689      */

690     @Deprecated JavaDoc
691     public static boolean copyStream(ProgressObserver progress, InputStream JavaDoc in, OutputStream out, boolean canStop)
692         throws IOException
693     {
694         return IOUtilities.copyStream(4096,progress, in, out, canStop);
695     } //}}}
696

697     //{{{ isBinaryFile() method
698
/**
699     * Check if a Reader is binary.
700     * To check if a file is binary, we will check the first characters 100
701     * (jEdit property vfs.binaryCheck.length)
702     * If more than 1 (jEdit property vfs.binaryCheck.count), the
703     * file is declared binary.
704     * This is not 100% because sometimes the autodetection could fail.
705     * This method will not close your reader. You have to do it yourself
706     *
707     * @param reader the reader
708     * @return <code>true</code> if the Reader was detected as binary
709     * @throws IOException IOException If an I/O error occurs
710     * @since jEdit 4.3pre5
711     */

712     public static boolean isBinary(Reader reader)
713     throws IOException
714     {
715         int nbChars = jEdit.getIntegerProperty("vfs.binaryCheck.length",100);
716         int authorized = jEdit.getIntegerProperty("vfs.binaryCheck.count",1);
717         for (long i = 0L;i < nbChars;i++)
718         {
719             int c = reader.read();
720             if (c == -1)
721                 return false;
722             if (c == 0)
723             {
724                 authorized--;
725                 if (authorized == 0)
726                     return true;
727             }
728         }
729         return false;
730     } //}}}
731

732     //{{{ isBackup() method
733
/**
734      * Check if the filename is a backup file.
735      * @param filename the filename to check
736      * @return true if this is a backup file.
737      * @since jEdit 4.3pre5
738      */

739     public static boolean isBackup( String JavaDoc filename ) {
740         if (filename.startsWith("#")) return true;
741         if (filename.endsWith("~")) return true;
742         if (filename.endsWith(".bak")) return true;
743         return false;
744     } //}}}
745

746
747     //{{{ autodetect() method
748
/**
749      * Tries to detect if the stream is gzipped, and if it has an encoding
750      * specified with an XML PI.
751      *
752      * @param in the input stream reader that must be autodetected
753      * @param buffer a buffer. It can be null if you only want to autodetect the encoding of a file
754      * @return a reader using the detected encoding
755      * @throws IOException io exception during read
756      * @since jEdit 4.3pre5
757      */

758     public static Reader autodetect(InputStream JavaDoc in, Buffer buffer) throws IOException
759     {
760         in = new BufferedInputStream(in);
761
762         String JavaDoc encoding;
763         if (buffer == null)
764             encoding = System.getProperty("file.encoding");
765         else
766             encoding = buffer.getStringProperty(JEditBuffer.ENCODING);
767
768         if(!in.markSupported())
769             Log.log(Log.WARNING,MiscUtilities.class,"Mark not supported: " + in);
770         else if(buffer == null || buffer.getBooleanProperty(Buffer.ENCODING_AUTODETECT))
771         {
772             in.mark(BufferIORequest.XML_PI_LENGTH);
773             int b1 = in.read();
774             int b2 = in.read();
775             int b3 = in.read();
776
777             if(b1 == BufferIORequest.GZIP_MAGIC_1 && b2 == BufferIORequest.GZIP_MAGIC_2)
778             {
779                 in.reset();
780                 in = new GZIPInputStream JavaDoc(in);
781                 if (buffer != null)
782                     buffer.setBooleanProperty(Buffer.GZIPPED,true);
783                 // auto-detect encoding within the gzip stream.
784
return autodetect(in, buffer);
785             }
786             else if (b1 == BufferIORequest.UNICODE_MAGIC_1
787                 && b2 == BufferIORequest.UNICODE_MAGIC_2)
788             {
789                 in.reset();
790                 in.read();
791                 in.read();
792                 encoding = "UTF-16BE";
793                 if (buffer != null)
794                     buffer.setProperty(JEditBuffer.ENCODING,encoding);
795             }
796             else if (b1 == BufferIORequest.UNICODE_MAGIC_2
797                 && b2 == BufferIORequest.UNICODE_MAGIC_1)
798             {
799                 in.reset();
800                 in.read();
801                 in.read();
802                 encoding = "UTF-16LE";
803                 if (buffer != null)
804                     buffer.setProperty(JEditBuffer.ENCODING,encoding);
805             }
806             else if(b1 == BufferIORequest.UTF8_MAGIC_1 && b2 == BufferIORequest.UTF8_MAGIC_2
807                 && b3 == BufferIORequest.UTF8_MAGIC_3)
808             {
809                 // do not reset the stream and just treat it
810
// like a normal UTF-8 file.
811
if (buffer != null)
812                     buffer.setProperty(JEditBuffer.ENCODING, MiscUtilities.UTF_8_Y);
813
814                 encoding = "UTF-8";
815             }
816             else
817             {
818                 in.reset();
819
820                 byte[] _xmlPI = new byte[BufferIORequest.XML_PI_LENGTH];
821                 int offset = 0;
822                 int count;
823                 while((count = in.read(_xmlPI,offset,
824                     BufferIORequest.XML_PI_LENGTH - offset)) != -1)
825                 {
826                     offset += count;
827                     if(offset == BufferIORequest.XML_PI_LENGTH)
828                         break;
829                 }
830
831                 String JavaDoc xmlEncoding = getXMLEncoding(new String JavaDoc(
832                     _xmlPI,0,offset,"ASCII"));
833                 if(xmlEncoding != null)
834                 {
835                     encoding = xmlEncoding;
836                     if (buffer != null)
837                         buffer.setProperty(JEditBuffer.ENCODING,encoding);
838                 }
839
840                 if(encoding.equals(MiscUtilities.UTF_8_Y))
841                     encoding = "UTF-8";
842
843                 in.reset();
844             }
845         }
846
847         return new InputStreamReader(in,encoding);
848     } //}}}
849

850     //{{{ getXMLEncoding() method
851
/**
852      * Extract XML encoding name from PI.
853      */

854     private static String JavaDoc getXMLEncoding(String JavaDoc xmlPI)
855     {
856         if(!xmlPI.startsWith("<?xml"))
857             return null;
858
859         int index = xmlPI.indexOf("encoding=");
860         if(index == -1 || index + 9 == xmlPI.length())
861             return null;
862
863         char ch = xmlPI.charAt(index + 9);
864         int endIndex = xmlPI.indexOf(ch,index + 10);
865         if(endIndex == -1)
866             return null;
867
868         String JavaDoc encoding = xmlPI.substring(index + 10,endIndex);
869
870         if(Charset.isSupported(encoding))
871             return encoding;
872         else
873         {
874             Log.log(Log.WARNING,MiscUtilities.class,"XML PI specifies "
875                 + "unsupported encoding: " + encoding);
876             return null;
877         }
878     } //}}}
879

880     //{{{ closeQuietly() method
881
/**
882      * Method that will close an {@link InputStream} ignoring it if it is null and ignoring exceptions.
883      *
884      * @param in the InputStream to close.
885      * @since jEdit 4.3pre3
886      * @deprecated use {@link IOUtilities#closeQuietly(java.io.InputStream)}
887      */

888     @Deprecated JavaDoc
889     public static void closeQuietly(InputStream JavaDoc in)
890     {
891         IOUtilities.closeQuietly(in);
892     } //}}}
893

894     //{{{ copyStream() method
895
/**
896      * Method that will close an {@link OutputStream} ignoring it if it is null and ignoring exceptions.
897      *
898      * @param out the OutputStream to close.
899      * @since jEdit 4.3pre3
900      * @deprecated use {@link IOUtilities#closeQuietly(java.io.OutputStream)}
901      */

902     @Deprecated JavaDoc
903     public static void closeQuietly(OutputStream out)
904     {
905         IOUtilities.closeQuietly(out);
906     } //}}}
907

908     //{{{ fileToClass() method
909
/**
910      * Converts a file name to a class name. All slash characters are
911      * replaced with periods and the trailing '.class' is removed.
912      * @param name The file name
913      */

914     public static String JavaDoc fileToClass(String JavaDoc name)
915     {
916         char[] clsName = name.toCharArray();
917         for(int i = clsName.length - 6; i >= 0; i--)
918             if(clsName[i] == '/')
919                 clsName[i] = '.';
920         return new String JavaDoc(clsName,0,clsName.length - 6);
921     } //}}}
922

923     //{{{ classToFile() method
924
/**
925      * Converts a class name to a file name. All periods are replaced
926      * with slashes and the '.class' extension is added.
927      * @param name The class name
928      */

929     public static String JavaDoc classToFile(String JavaDoc name)
930     {
931         return name.replace('.','/').concat(".class");
932     } //}}}
933

934     //{{{ pathsEqual() method
935
/**
936      * @param p1 A path name
937      * @param p2 A path name
938      * @return True if both paths are equal, ignoring trailing slashes, as
939      * well as case insensitivity on Windows.
940      * @since jEdit 4.3pre2
941      */

942     public static boolean pathsEqual(String JavaDoc p1, String JavaDoc p2)
943     {
944         VFS v1 = VFSManager.getVFSForPath(p1);
945         VFS v2 = VFSManager.getVFSForPath(p2);
946
947         if(v1 != v2)
948             return false;
949
950         if(p1.endsWith("/") || p1.endsWith(File.separator))
951             p1 = p1.substring(0,p1.length() - 1);
952
953         if(p2.endsWith("/") || p2.endsWith(File.separator))
954             p2 = p2.substring(0,p2.length() - 1);
955
956         if((v1.getCapabilities() & VFS.CASE_INSENSITIVE_CAP) != 0)
957             return p1.equalsIgnoreCase(p2);
958         else
959             return p1.equals(p2);
960     } //}}}
961

962     //}}}
963

964     //{{{ Text methods
965

966     //{{{ getLeadingWhiteSpace() method
967
/**
968      * Returns the number of leading white space characters in the
969      * specified string.
970      * @param str The string
971      * @deprecated use {@link StandardUtilities#getLeadingWhiteSpace(String)}
972      */

973     @Deprecated JavaDoc
974     public static int getLeadingWhiteSpace(String JavaDoc str)
975     {
976         return StandardUtilities.getLeadingWhiteSpace(str);
977     } //}}}
978

979     //{{{ getTrailingWhiteSpace() method
980
/**
981      * Returns the number of trailing whitespace characters in the
982      * specified string.
983      * @param str The string
984      * @since jEdit 2.5pre5
985      * @deprecated use {@link StandardUtilities#getTrailingWhiteSpace(String)}
986      */

987     @Deprecated JavaDoc
988     public static int getTrailingWhiteSpace(String JavaDoc str)
989     {
990         return StandardUtilities.getTrailingWhiteSpace(str);
991     } //}}}
992

993     //{{{ getLeadingWhiteSpaceWidth() method
994
/**
995      * Returns the width of the leading white space in the specified
996      * string.
997      * @param str The string
998      * @param tabSize The tab size
999      * @deprecated use {@link StandardUtilities#getLeadingWhiteSpace(String)}
1000     */

1001    @Deprecated JavaDoc
1002    public static int getLeadingWhiteSpaceWidth(String JavaDoc str, int tabSize)
1003    {
1004        return StandardUtilities.getLeadingWhiteSpaceWidth(str, tabSize);
1005    } //}}}
1006

1007    //{{{ getVirtualWidth() method
1008
/**
1009     * Returns the virtual column number (taking tabs into account) of the
1010     * specified offset in the segment.
1011     *
1012     * @param seg The segment
1013     * @param tabSize The tab size
1014     * @since jEdit 4.1pre1
1015     * @deprecated use {@link StandardUtilities#getVirtualWidth(javax.swing.text.Segment, int)}
1016     */

1017    @Deprecated JavaDoc
1018    public static int getVirtualWidth(Segment JavaDoc seg, int tabSize)
1019    {
1020        return StandardUtilities.getVirtualWidth(seg, tabSize);
1021    } //}}}
1022

1023    //{{{ getOffsetOfVirtualColumn() method
1024
/**
1025     * Returns the array offset of a virtual column number (taking tabs
1026     * into account) in the segment.
1027     *
1028     * @param seg The segment
1029     * @param tabSize The tab size
1030     * @param column The virtual column number
1031     * @param totalVirtualWidth If this array is non-null, the total
1032     * virtual width will be stored in its first location if this method
1033     * returns -1.
1034     *
1035     * @return -1 if the column is out of bounds
1036     *
1037     * @since jEdit 4.1pre1
1038     * @deprecated use {@link StandardUtilities#getVirtualWidth(javax.swing.text.Segment, int)}
1039     */

1040    @Deprecated JavaDoc
1041    public static int getOffsetOfVirtualColumn(Segment JavaDoc seg, int tabSize,
1042                        int column, int[] totalVirtualWidth)
1043    {
1044        return StandardUtilities.getOffsetOfVirtualColumn(seg, tabSize, column, totalVirtualWidth);
1045    } //}}}
1046

1047    //{{{ createWhiteSpace() method
1048
/**
1049     * Creates a string of white space with the specified length.<p>
1050     *
1051     * To get a whitespace string tuned to the current buffer's
1052     * settings, call this method as follows:
1053     *
1054     * <pre>myWhitespace = MiscUtilities.createWhiteSpace(myLength,
1055     * (buffer.getBooleanProperty("noTabs") ? 0
1056     * : buffer.getTabSize()));</pre>
1057     *
1058     * @param len The length
1059     * @param tabSize The tab size, or 0 if tabs are not to be used
1060     * @deprecated use {@link StandardUtilities#createWhiteSpace(int, int)}
1061     */

1062    @Deprecated JavaDoc
1063    public static String JavaDoc createWhiteSpace(int len, int tabSize)
1064    {
1065        return StandardUtilities.createWhiteSpace(len,tabSize,0);
1066    } //}}}
1067

1068    //{{{ createWhiteSpace() method
1069
/**
1070     * Creates a string of white space with the specified length.<p>
1071     *
1072     * To get a whitespace string tuned to the current buffer's
1073     * settings, call this method as follows:
1074     *
1075     * <pre>myWhitespace = MiscUtilities.createWhiteSpace(myLength,
1076     * (buffer.getBooleanProperty("noTabs") ? 0
1077     * : buffer.getTabSize()));</pre>
1078     *
1079     * @param len The length
1080     * @param tabSize The tab size, or 0 if tabs are not to be used
1081     * @param start The start offset, for tab alignment
1082     * @since jEdit 4.2pre1
1083     * @deprecated use {@link StandardUtilities#createWhiteSpace(int, int, int)}
1084     */

1085    @Deprecated JavaDoc
1086    public static String JavaDoc createWhiteSpace(int len, int tabSize, int start)
1087    {
1088        return StandardUtilities.createWhiteSpace(len, tabSize, start);
1089    } //}}}
1090

1091    //{{{ globToRE() method
1092
/**
1093     * Converts a Unix-style glob to a regular expression.<p>
1094     *
1095     * ? becomes ., * becomes .*, {aa,bb} becomes (aa|bb).
1096     * @param glob The glob pattern
1097     * @deprecated Use {@link StandardUtilities#globToRE(String)}.
1098     */

1099    @Deprecated JavaDoc
1100    public static String JavaDoc globToRE(String JavaDoc glob)
1101    {
1102        return StandardUtilities.globToRE(glob);
1103    } //}}}
1104

1105    //{{{ escapesToChars() method
1106
/**
1107     * Converts "\n" and "\t" escapes in the specified string to
1108     * newlines and tabs.
1109     * @param str The string
1110     * @since jEdit 2.3pre1
1111     */

1112    public static String JavaDoc escapesToChars(String JavaDoc str)
1113    {
1114        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1115        for(int i = 0; i < str.length(); i++)
1116        {
1117            char c = str.charAt(i);
1118            switch(c)
1119            {
1120            case '\\':
1121                if(i == str.length() - 1)
1122                {
1123                    buf.append('\\');
1124                    break;
1125                }
1126                c = str.charAt(++i);
1127                switch(c)
1128                {
1129                case 'n':
1130                    buf.append('\n');
1131                    break;
1132                case 't':
1133                    buf.append('\t');
1134                    break;
1135                default:
1136                    buf.append(c);
1137                    break;
1138                }
1139                break;
1140            default:
1141                buf.append(c);
1142            }
1143        }
1144        return buf.toString();
1145    } //}}}
1146

1147    //{{{ charsToEscapes() method
1148
/**
1149     * Escapes newlines, tabs, backslashes, and quotes in the specified
1150     * string.
1151     * @param str The string
1152     * @since jEdit 2.3pre1
1153     */

1154    public static String JavaDoc charsToEscapes(String JavaDoc str)
1155    {
1156        return charsToEscapes(str,"\n\t\\\"'");
1157    } //}}}
1158

1159    //{{{ charsToEscapes() method
1160
/**
1161     * Escapes the specified characters in the specified string.
1162     * @param str The string
1163     * @param toEscape Any characters that require escaping
1164     * @since jEdit 4.1pre3
1165     */

1166    public static String JavaDoc charsToEscapes(String JavaDoc str, String JavaDoc toEscape)
1167    {
1168        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1169        for(int i = 0; i < str.length(); i++)
1170        {
1171            char c = str.charAt(i);
1172            if(toEscape.indexOf(c) != -1)
1173            {
1174                if(c == '\n')
1175                    buf.append("\\n");
1176                else if(c == '\t')
1177                    buf.append("\\t");
1178                else
1179                {
1180                    buf.append('\\');
1181                    buf.append(c);
1182                }
1183            }
1184            else
1185                buf.append(c);
1186        }
1187        return buf.toString();
1188    } //}}}
1189

1190    //{{{ compareVersions() method
1191
/**
1192     * @deprecated Call <code>compareStrings()</code> instead
1193     */

1194    @Deprecated JavaDoc
1195    public static int compareVersions(String JavaDoc v1, String JavaDoc v2)
1196    {
1197        return StandardUtilities.compareStrings(v1,v2,false);
1198    } //}}}
1199

1200    //{{{ compareStrings() method
1201
/**
1202     * Compares two strings.<p>
1203     *
1204     * Unlike <function>String.compareTo()</function>,
1205     * this method correctly recognizes and handles embedded numbers.
1206     * For example, it places "My file 2" before "My file 10".<p>
1207     *
1208     * @param str1 The first string
1209     * @param str2 The second string
1210     * @param ignoreCase If true, case will be ignored
1211     * @return negative If str1 &lt; str2, 0 if both are the same,
1212     * positive if str1 &gt; str2
1213     * @since jEdit 4.0pre1
1214     * @deprecated use {@link StandardUtilities#compareStrings(String, String, boolean)}
1215     */

1216    @Deprecated JavaDoc
1217    public static int compareStrings(String JavaDoc str1, String JavaDoc str2, boolean ignoreCase)
1218    {
1219        return StandardUtilities.compareStrings(str1, str2, ignoreCase);
1220    } //}}}
1221

1222    //{{{ stringsEqual() method
1223
/**
1224     * @deprecated Call <code>objectsEqual()</code> instead.
1225     */

1226    @Deprecated JavaDoc
1227    public static boolean stringsEqual(String JavaDoc s1, String JavaDoc s2)
1228    {
1229        return StandardUtilities.objectsEqual(s1,s2);
1230    } //}}}
1231

1232    //{{{ objectsEqual() method
1233
/**
1234     * Returns if two strings are equal. This correctly handles null pointers,
1235     * as opposed to calling <code>o1.equals(o2)</code>.
1236     * @since jEdit 4.2pre1
1237     * @deprecated use {@link StandardUtilities#objectsEqual(Object, Object)}
1238     */

1239    @Deprecated JavaDoc
1240    public static boolean objectsEqual(Object JavaDoc o1, Object JavaDoc o2)
1241    {
1242        return StandardUtilities.objectsEqual(o1, o2);
1243    } //}}}
1244

1245    //{{{ charsToEntities() method
1246
/**
1247     * Converts &lt;, &gt;, &amp; in the string to their HTML entity
1248     * equivalents.
1249     * @param str The string
1250     * @since jEdit 4.2pre1
1251     * @deprecated Use {@link org.gjt.sp.util.XMLUtilities#charsToEntities(String, boolean)}.
1252     */

1253    @Deprecated JavaDoc
1254    public static String JavaDoc charsToEntities(String JavaDoc str)
1255    {
1256        return XMLUtilities.charsToEntities(str,false);
1257    } //}}}
1258

1259    //{{{ formatFileSize() method
1260
public static final DecimalFormat JavaDoc KB_FORMAT = new DecimalFormat JavaDoc("#.# KB");
1261    public static final DecimalFormat JavaDoc MB_FORMAT = new DecimalFormat JavaDoc("#.# MB");
1262
1263    /**
1264     * Formats the given file size into a nice string (123 bytes, 10.6 KB,
1265     * 1.2 MB).
1266     * @param length The size
1267     * @since jEdit 4.2pre1
1268     */

1269    public static String JavaDoc formatFileSize(long length)
1270    {
1271        if(length < 1024)
1272            return length + " bytes";
1273        else if(length < 1024 << 10)
1274            return KB_FORMAT.format((double)length / 1024);
1275        else
1276            return MB_FORMAT.format((double)length / 1024 / 1024);
1277    } //}}}
1278

1279    //{{{ getLongestPrefix() method
1280
/**
1281     * Returns the longest common prefix in the given set of strings.
1282     * @param str The strings
1283     * @param ignoreCase If true, case insensitive
1284     * @since jEdit 4.2pre2
1285     */

1286    public static String JavaDoc getLongestPrefix(List str, boolean ignoreCase)
1287    {
1288        if(str.size() == 0)
1289            return "";
1290
1291        int prefixLength = 0;
1292
1293loop: for(;;)
1294        {
1295            String JavaDoc s = str.get(0).toString();
1296            if(prefixLength >= s.length())
1297                break loop;
1298            char ch = s.charAt(prefixLength);
1299            for(int i = 1; i < str.size(); i++)
1300            {
1301                s = str.get(i).toString();
1302                if(prefixLength >= s.length())
1303                    break loop;
1304                if(!compareChars(s.charAt(prefixLength),ch,ignoreCase))
1305                    break loop;
1306            }
1307            prefixLength++;
1308        }
1309
1310        return str.get(0).toString().substring(0,prefixLength);
1311    } //}}}
1312

1313    //{{{ getLongestPrefix() method
1314
/**
1315     * Returns the longest common prefix in the given set of strings.
1316     * @param str The strings
1317     * @param ignoreCase If true, case insensitive
1318     * @since jEdit 4.2pre2
1319     */

1320    public static String JavaDoc getLongestPrefix(String JavaDoc[] str, boolean ignoreCase)
1321    {
1322        return getLongestPrefix((Object JavaDoc[])str,ignoreCase);
1323    } //}}}
1324

1325    //{{{ getLongestPrefix() method
1326
/**
1327     * Returns the longest common prefix in the given set of strings.
1328     * @param str The strings (calls <code>toString()</code> on each object)
1329     * @param ignoreCase If true, case insensitive
1330     * @since jEdit 4.2pre6
1331     */

1332    public static String JavaDoc getLongestPrefix(Object JavaDoc[] str, boolean ignoreCase)
1333    {
1334        if(str.length == 0)
1335            return "";
1336
1337        int prefixLength = 0;
1338
1339        String JavaDoc first = str[0].toString();
1340
1341loop: for(;;)
1342        {
1343            if(prefixLength >= first.length())
1344                break loop;
1345            char ch = first.charAt(prefixLength);
1346            for(int i = 1; i < str.length; i++)
1347            {
1348                String JavaDoc s = str[i].toString();
1349                if(prefixLength >= s.length())
1350                    break loop;
1351                if(!compareChars(s.charAt(prefixLength),ch,ignoreCase))
1352                    break loop;
1353            }
1354            prefixLength++;
1355        }
1356
1357        return first.substring(0,prefixLength);
1358    } //}}}
1359

1360    //}}}
1361

1362    //{{{ Sorting methods
1363

1364    //{{{ quicksort() method
1365
/**
1366     * Sorts the specified array. Equivalent to calling
1367     * <code>Arrays.sort()</code>.
1368     * @param obj The array
1369     * @param compare Compares the objects
1370     * @since jEdit 4.0pre4
1371     * @deprecated use <code>Arrays.sort()</code>
1372     */

1373    @Deprecated JavaDoc
1374    public static void quicksort(Object JavaDoc[] obj, Comparator compare)
1375    {
1376        Arrays.sort(obj,compare);
1377    } //}}}
1378

1379    //{{{ quicksort() method
1380
/**
1381     * Sorts the specified vector.
1382     * @param vector The vector
1383     * @param compare Compares the objects
1384     * @since jEdit 4.0pre4
1385     * @deprecated <code>Collections.sort()</code>
1386     */

1387    @Deprecated JavaDoc
1388    public static void quicksort(Vector vector, Comparator compare)
1389    {
1390        Collections.sort(vector,compare);
1391    } //}}}
1392

1393    //{{{ quicksort() method
1394
/**
1395     * Sorts the specified list.
1396     * @param list The list
1397     * @param compare Compares the objects
1398     * @since jEdit 4.0pre4
1399     * @deprecated <code>Collections.sort()</code>
1400     */

1401    @Deprecated JavaDoc
1402    public static void quicksort(List list, Comparator compare)
1403    {
1404        Collections.sort(list,compare);
1405    } //}}}
1406

1407    //{{{ quicksort() method
1408
/**
1409     * Sorts the specified array. Equivalent to calling
1410     * <code>Arrays.sort()</code>.
1411     * @param obj The array
1412     * @param compare Compares the objects
1413     * @deprecated use <code>Arrays.sort()</code>
1414     */

1415    @Deprecated JavaDoc
1416    public static void quicksort(Object JavaDoc[] obj, Compare compare)
1417    {
1418        Arrays.sort(obj,compare);
1419    } //}}}
1420

1421    //{{{ quicksort() method
1422
/**
1423     * Sorts the specified vector.
1424     * @param vector The vector
1425     * @param compare Compares the objects
1426     * @deprecated <code>Collections.sort()</code>
1427     */

1428    @Deprecated JavaDoc
1429    public static void quicksort(Vector vector, Compare compare)
1430    {
1431        Collections.sort(vector,compare);
1432    } //}}}
1433

1434    //{{{ Compare interface
1435
/**
1436     * An interface for comparing objects. This is a hold-over from
1437     * they days when jEdit had its own sorting API due to JDK 1.1
1438     * compatibility requirements. Use <code>java.util.Comparable</code>
1439     * instead.
1440     * @deprecated
1441     */

1442    @Deprecated JavaDoc
1443    public interface Compare extends Comparator
1444    {
1445        int compare(Object JavaDoc obj1, Object JavaDoc obj2);
1446    } //}}}
1447

1448    //{{{ StringCompare class
1449
/**
1450     * Compares strings.
1451     * @deprecated use {@link StandardUtilities.StringCompare}
1452     */

1453    @Deprecated JavaDoc
1454    public static class StringCompare implements Compare
1455    {
1456        public int compare(Object JavaDoc obj1, Object JavaDoc obj2)
1457        {
1458            return StandardUtilities.compareStrings(obj1.toString(),
1459                obj2.toString(),false);
1460        }
1461    } //}}}
1462

1463    //{{{ StringICaseCompare class
1464
/**
1465     * Compares strings ignoring case.
1466     */

1467    public static class StringICaseCompare implements Comparator<Object JavaDoc>
1468    {
1469        public int compare(Object JavaDoc obj1, Object JavaDoc obj2)
1470        {
1471            return StandardUtilities.compareStrings(obj1.toString(), obj2.toString(), true);
1472        }
1473    } //}}}
1474

1475    //{{{ MenuItemCompare class
1476
/**
1477     * Compares menu item labels.
1478     */

1479    public static class MenuItemCompare implements Compare
1480    {
1481        public int compare(Object JavaDoc obj1, Object JavaDoc obj2)
1482        {
1483            boolean obj1E, obj2E;
1484            obj1E = obj1 instanceof EnhancedMenuItem;
1485            obj2E = obj2 instanceof EnhancedMenuItem;
1486            if(obj1E && !obj2E)
1487                return 1;
1488            else if(obj2E && !obj1E)
1489                return -1;
1490            else
1491                return StandardUtilities.compareStrings(((JMenuItem JavaDoc)obj1).getText(),
1492                    ((JMenuItem JavaDoc)obj2).getText(),true);
1493        }
1494    } //}}}
1495

1496    //}}}
1497

1498    //{{{ buildToVersion() method
1499
/**
1500     * Converts an internal version number (build) into a
1501     * `human-readable' form.
1502     * @param build The build
1503     */

1504    public static String JavaDoc buildToVersion(String JavaDoc build)
1505    {
1506        if(build.length() != 11)
1507            return "<unknown version: " + build + ">";
1508        // First 2 chars are the major version number
1509
int major = Integer.parseInt(build.substring(0,2));
1510        // Second 2 are the minor number
1511
int minor = Integer.parseInt(build.substring(3,5));
1512        // Then the pre-release status
1513
int beta = Integer.parseInt(build.substring(6,8));
1514        // Finally the bug fix release
1515
int bugfix = Integer.parseInt(build.substring(9,11));
1516
1517        return major + "." + minor
1518            + (beta != 99 ? "pre" + beta :
1519            (bugfix != 0 ? "." + bugfix : "final"));
1520    } //}}}
1521

1522    //{{{ isToolsJarAvailable() method
1523
/**
1524     * If on JDK 1.2 or higher, make sure that tools.jar is available.
1525     * This method should be called by plugins requiring the classes
1526     * in this library.
1527     * <p>
1528     * tools.jar is searched for in the following places:
1529     * <ol>
1530     * <li>the classpath that was used when jEdit was started,
1531     * <li>jEdit's jars folder in the user's home,
1532     * <li>jEdit's system jars folder,
1533     * <li><i>java.home</i>/lib/. In this case, tools.jar is added to
1534     * jEdit's list of known jars using jEdit.addPluginJAR(),
1535     * so that it gets loaded through JARClassLoader.
1536     * </ol><p>
1537     *
1538     * On older JDK's this method does not perform any checks, and returns
1539     * <code>true</code> (even though there is no tools.jar).
1540     *
1541     * @return <code>false</code> if and only if on JDK 1.2 and tools.jar
1542     * could not be found. In this case it prints some warnings on Log,
1543     * too, about the places where it was searched for.
1544     * @since jEdit 3.2.2
1545     */

1546    public static boolean isToolsJarAvailable()
1547    {
1548        Log.log(Log.DEBUG, MiscUtilities.class,"Searching for tools.jar...");
1549
1550        Vector paths = new Vector();
1551
1552        //{{{ 1. Check whether tools.jar is in the system classpath:
1553
paths.addElement("System classpath: "
1554            + System.getProperty("java.class.path"));
1555
1556        try
1557        {
1558            // Either class sun.tools.javac.Main or
1559
// com.sun.tools.javac.Main must be there:
1560
try
1561            {
1562                Class.forName("sun.tools.javac.Main");
1563            }
1564            catch(ClassNotFoundException JavaDoc e1)
1565            {
1566                Class.forName("com.sun.tools.javac.Main");
1567            }
1568            Log.log(Log.DEBUG, MiscUtilities.class,
1569                "- is in classpath. Fine.");
1570            return true;
1571        }
1572        catch(ClassNotFoundException JavaDoc e)
1573        {
1574            //Log.log(Log.DEBUG, MiscUtilities.class,
1575
// "- is not in system classpath.");
1576
} //}}}
1577

1578        //{{{ 2. Check whether it is in the jEdit user settings jars folder:
1579
String JavaDoc settingsDir = jEdit.getSettingsDirectory();
1580        if(settingsDir != null)
1581        {
1582            String JavaDoc toolsPath = constructPath(settingsDir, "jars",
1583                "tools.jar");
1584            paths.addElement(toolsPath);
1585            if(new File(toolsPath).exists())
1586            {
1587                Log.log(Log.DEBUG, MiscUtilities.class,
1588                    "- is in the user's jars folder. Fine.");
1589                // jEdit will load it automatically
1590
return true;
1591            }
1592        } //}}}
1593

1594        //{{{ 3. Check whether it is in jEdit's system jars folder:
1595
String JavaDoc jEditDir = jEdit.getJEditHome();
1596        if(jEditDir != null)
1597        {
1598            String JavaDoc toolsPath = constructPath(jEditDir, "jars", "tools.jar");
1599            paths.addElement(toolsPath);
1600            if(new File(toolsPath).exists())
1601            {
1602                Log.log(Log.DEBUG, MiscUtilities.class,
1603                    "- is in jEdit's system jars folder. Fine.");
1604                // jEdit will load it automatically
1605
return true;
1606            }
1607        } //}}}
1608

1609        //{{{ 4. Check whether it is in <java.home>/lib:
1610
String JavaDoc toolsPath = System.getProperty("java.home");
1611        if(toolsPath.toLowerCase().endsWith(File.separator + "jre"))
1612            toolsPath = toolsPath.substring(0, toolsPath.length() - 4);
1613        toolsPath = constructPath(toolsPath, "lib", "tools.jar");
1614        paths.addElement(toolsPath);
1615
1616        if(!(new File(toolsPath).exists()))
1617        {
1618            Log.log(Log.WARNING, MiscUtilities.class,
1619                "Could not find tools.jar.\n"
1620                + "I checked the following locations:\n"
1621                + paths.toString());
1622            return false;
1623        } //}}}
1624

1625        //{{{ Load it, if not yet done:
1626
PluginJAR jar = jEdit.getPluginJAR(toolsPath);
1627        if(jar == null)
1628        {
1629            Log.log(Log.DEBUG, MiscUtilities.class,
1630                "- adding " + toolsPath + " to jEdit plugins.");
1631            jEdit.addPluginJAR(toolsPath);
1632        }
1633        else
1634            Log.log(Log.DEBUG, MiscUtilities.class,
1635                "- has been loaded before.");
1636        //}}}
1637

1638        return true;
1639    } //}}}
1640

1641    //{{{ parsePermissions() method
1642
/**
1643     * Parse a Unix-style permission string (rwxrwxrwx).
1644     * @param s The string (must be 9 characters long).
1645     * @since jEdit 4.1pre8
1646     */

1647    public static int parsePermissions(String JavaDoc s)
1648    {
1649        int permissions = 0;
1650
1651        if(s.length() == 9)
1652        {
1653            if(s.charAt(0) == 'r')
1654                permissions += 0400;
1655            if(s.charAt(1) == 'w')
1656                permissions += 0200;
1657            if(s.charAt(2) == 'x')
1658                permissions += 0100;
1659            else if(s.charAt(2) == 's')
1660                permissions += 04100;
1661            else if(s.charAt(2) == 'S')
1662                permissions += 04000;
1663            if(s.charAt(3) == 'r')
1664                permissions += 040;
1665            if(s.charAt(4) == 'w')
1666                permissions += 020;
1667            if(s.charAt(5) == 'x')
1668                permissions += 010;
1669            else if(s.charAt(5) == 's')
1670                permissions += 02010;
1671            else if(s.charAt(5) == 'S')
1672                permissions += 02000;
1673            if(s.charAt(6) == 'r')
1674                permissions += 04;
1675            if(s.charAt(7) == 'w')
1676                permissions += 02;
1677            if(s.charAt(8) == 'x')
1678                permissions += 01;
1679            else if(s.charAt(8) == 't')
1680                permissions += 01001;
1681            else if(s.charAt(8) == 'T')
1682                permissions += 01000;
1683        }
1684
1685        return permissions;
1686    } //}}}
1687

1688    //{{{ getEncodings() method
1689
/**
1690     * Returns a list of supported character encodings.
1691     * @since jEdit 4.2pre5
1692     * @deprecated See #getEncodings( boolean )
1693     */

1694    @Deprecated JavaDoc
1695    public static String JavaDoc[] getEncodings()
1696    {
1697        return getEncodings(false);
1698    } //}}}
1699

1700    //{{{ getEncodings() method
1701
/**
1702     * Returns a list of supported character encodings.
1703     * @since jEdit 4.3pre5
1704     * @param getSelected Whether to return just the selected encodings or all.
1705     */

1706    public static String JavaDoc[] getEncodings(boolean getSelected)
1707    {
1708        List returnValue = new ArrayList();
1709
1710        Map map = Charset.availableCharsets();
1711        Iterator iter = map.keySet().iterator();
1712
1713        if ((getSelected && !jEdit.getBooleanProperty("encoding.opt-out."+UTF_8_Y,false)) ||
1714            !getSelected)
1715        {
1716            returnValue.add(UTF_8_Y);
1717        }
1718
1719        while(iter.hasNext())
1720        {
1721            String JavaDoc encoding = (String JavaDoc)iter.next();
1722            if ((getSelected && !jEdit.getBooleanProperty("encoding.opt-out."+encoding,false)) ||
1723                !getSelected)
1724            {
1725                returnValue.add(encoding);
1726            }
1727        }
1728
1729        return (String JavaDoc[])returnValue.toArray(
1730            new String JavaDoc[returnValue.size()]);
1731    } //}}}
1732

1733    //{{{ throwableToString() method
1734
/**
1735     * Returns a string containing the stack trace of the given throwable.
1736     * @since jEdit 4.2pre6
1737     */

1738    public static String JavaDoc throwableToString(Throwable JavaDoc t)
1739    {
1740        StringWriter s = new StringWriter();
1741        t.printStackTrace(new PrintWriter(s));
1742        return s.toString();
1743    } //}}}
1744

1745    //{{{ parseXML() method
1746
/**
1747     * Convenience method for parsing an XML file.
1748     *
1749     * @return Whether any error occured during parsing.
1750     * @since jEdit 4.3pre5
1751     * @deprecated Use {@link XMLUtilities#parseXML(InputStream,DefaultHandler)}.
1752     */

1753    @Deprecated JavaDoc
1754    public static boolean parseXML(InputStream JavaDoc in, DefaultHandler JavaDoc handler)
1755        throws IOException
1756    {
1757        return XMLUtilities.parseXML(in, handler);
1758    } //}}}
1759

1760    //{{{ resolveEntity() method
1761
/**
1762     * Tries to find the given systemId in the context of the given
1763     * class.
1764     *
1765     * @deprecated Use {@link XMLUtilities#findEntity(String,String,Class)}.
1766     */

1767    @Deprecated JavaDoc
1768    public static InputSource JavaDoc findEntity(String JavaDoc systemId, String JavaDoc test, Class JavaDoc where)
1769    {
1770        return XMLUtilities.findEntity(systemId, test, where);
1771    } //}}}
1772

1773    //{{{ Private members
1774
private MiscUtilities() {}
1775
1776    //{{{ compareChars()
1777
/** should this be public? */
1778    private static boolean compareChars(char ch1, char ch2, boolean ignoreCase)
1779    {
1780        if(ignoreCase)
1781            return Character.toUpperCase(ch1) == Character.toUpperCase(ch2);
1782        else
1783            return ch1 == ch2;
1784    } //}}}
1785

1786    //{{{ getPathStart()
1787
private static int getPathStart(String JavaDoc path)
1788    {
1789        int start = 0;
1790        if(path.startsWith("/"))
1791            return 1;
1792        else if(OperatingSystem.isDOSDerived()
1793            && path.length() >= 3
1794            && path.charAt(1) == ':'
1795            && (path.charAt(2) == '/'
1796            || path.charAt(2) == '\\'))
1797            return 3;
1798        else
1799            return 0;
1800    } //}}}
1801

1802    //}}}
1803
}
1804
Popular Tags