KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > Util


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java;
21
22 import javax.swing.text.Document JavaDoc;
23 import javax.swing.text.BadLocationException JavaDoc;
24 import javax.swing.text.StyledDocument JavaDoc;
25 import org.openide.filesystems.FileObject;
26 import org.openide.filesystems.FileUtil;
27 import org.openide.loaders.DataObject;
28 import org.openide.loaders.ExtensionList;
29 import org.openide.text.IndentEngine;
30 import org.netbeans.modules.java.JavaEditor.GuardedReader;
31 import java.util.ResourceBundle JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.Hashtable JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.LinkedList JavaDoc;
37 import org.openide.cookies.SaveCookie;
38 import org.openide.ErrorManager;
39
40 import org.openide.text.NbDocument;
41 import org.openide.text.PositionRef;
42 import org.netbeans.modules.java.settings.JavaSettings;
43 import java.io.*;
44 import org.openide.util.SharedClassObject;
45 import java.lang.ref.WeakReference JavaDoc;
46 import java.lang.ref.ReferenceQueue JavaDoc;
47 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
48
49 import org.openide.src.SourceException;
50 import org.openide.util.NbBundle;
51
52 /** Miscellaneous utilities for Java data loader.
53 *
54 * @author Petr Hamernik, Ales Novak
55 */

56 public final class Util extends Object JavaDoc {
57     // ===================== i18n utilities ===========================
58

59     /**
60      * Instance of error manager used for annotating exceptions.
61      */

62     private static ErrorManager errorManager;
63     
64     static final String JavaDoc ATTR_FILE_ENCODING = "Content-Encoding"; // NOI18N
65

66     /** Computes the localized string for the key.
67     * @param key The key of the string.
68     * @return the localized string.
69     */

70     static String JavaDoc getString(String JavaDoc key) {
71         return NbBundle.getMessage(Util.class, key);
72     }
73     
74     static ErrorManager getErrorManager() {
75         if (errorManager != null)
76             return errorManager;
77         ErrorManager main = ErrorManager.getDefault();
78         if (main == null) {
79             System.err.println("WARNING: can't lookup error manager"); // NOI18N
80
return null;
81         }
82         return errorManager = main;
83     }
84     
85     static void annotateThrowable(Throwable JavaDoc t, Throwable JavaDoc nested) {
86         getErrorManager().annotate(t, nested);
87     }
88     
89     static void annotateThrowable(Throwable JavaDoc t, String JavaDoc localizedMessage,
90         boolean user) {
91         if (user) {
92             getErrorManager().annotate(t, ErrorManager.USER, null,
93                 localizedMessage, null, null);
94         } else {
95             getErrorManager().annotate(t, ErrorManager.EXCEPTION, null,
96                 localizedMessage, null, null);
97         }
98     }
99
100     // ===================== loader utilities ===========================
101

102     static FileObject findBrother(FileObject f, String JavaDoc extension) {
103         return FileUtil.findBrother(f, extension);
104     }
105
106     private static FileObject findSibling(FileObject base, String JavaDoc name, Enumeration JavaDoc extlist) {
107         FileObject ret;
108         while (extlist.hasMoreElements()) {
109             String JavaDoc ext = (String JavaDoc)extlist.nextElement();
110             if (ext == null)
111                 continue;
112             ret = base.getFileObject(name, ext);
113             if (ret != null)
114                 return ret;
115         }
116         return null;
117     }
118
119     /** Notifies about an exception
120     *
121     * @param msg is ignored
122     */

123     private static void notifyException(Throwable JavaDoc t, String JavaDoc msg) {
124         getErrorManager().notify(t);
125     }
126
127
128     // ===================== Indentation util ==============================
129

130     /** Finds the appropriate indentation writer for the java sources.
131     * @param doc The document where it will be inserted in
132     * @param offset The position in the document
133     * @param writer The encapsulated writer
134     */

135     static Writer findIndentWriter(Document JavaDoc doc, int offset, Writer writer) {
136         IndentEngine engine = IndentEngine.find(doc); // NOI18N
137
return engine.createWriter(doc, offset, writer);
138     }
139
140     // ===================== Advanced Task suppport =========================
141

142     /** Invokes the runnable using NbDocument.runAtomic.
143     * If BadLocationException occured inside, it will be thrown
144     * the new SourceException.
145     *
146     */

147     static void runAtomic(StyledDocument JavaDoc doc, ExceptionRunnable run) throws SourceException {
148         RunnableSupport support = new RunnableSupport(run);
149         NbDocument.runAtomic(doc, support);
150         support.throwException();
151     }
152     
153     /** This interface is used like runnable, but its method run
154     * could throw BadLocationException.
155     * @exception
156     */

157     interface ExceptionRunnable {
158         public void run() throws Exception JavaDoc;
159     }
160
161     /** Encapsulation class for the ExceptionRunnable interface.
162     * It implements Runnable, so it can be used everywhere is Runnable
163     * accepted.
164     */

165     private static class RunnableSupport implements Runnable JavaDoc {
166         /** Exception which occured in the e*/
167         private Exception JavaDoc e;
168
169         /** Encapsulated runnable */
170         private ExceptionRunnable runnable;
171
172         /** Creates new class */
173         public RunnableSupport(ExceptionRunnable runnable) {
174             this.runnable = runnable;
175             e = null;
176         }
177
178         /** @return true if exception occured. */
179         public boolean hasException() {
180             return e != null;
181         }
182
183         /** @return the exception or null if no exception has occured. */
184         public Exception JavaDoc getException() {
185             return e;
186         }
187
188         /** If a bad position exception occured during running
189         * the given ExceptionRunnable, it will be thrown new SourceException
190         * with the same message. Otherwise throws nothing.
191         */

192         public void throwException() throws SourceException {
193             if (e != null) {
194                 if (e instanceof SourceException) {
195                     // already in the correct format
196
throw (SourceException)e;
197                 }
198                 
199                 SourceException wrapper = new SourceException(e.getMessage());
200                 // special translation for BadLocationException:
201
if (e instanceof BadLocationException JavaDoc) {
202                     // provide unified message about attempt to modify a guarded block:
203
ErrorManager.getDefault().annotate(
204                         wrapper, ErrorManager.USER,
205                         e.getMessage(),
206                         e.getLocalizedMessage(),
207                         e, null
208                     );
209                 } else {
210                     ErrorManager.getDefault().annotate(
211                         wrapper, e
212                     );
213                 }
214                 throw wrapper;
215             }
216         }
217
218         /** Implementation of the Runnable interface. It calls the encapsulated
219         * runnable passed in the constructor and catch the exceptions.
220         */

221         public void run() {
222             try {
223                 runnable.run();
224             }
225             catch (Exception JavaDoc e) {
226                 this.e = e;
227             }
228         }
229     }
230     
231     /**
232      * Retrieves file's encoding. If the file does not specify any encoding,
233      * null is returned. Note: an empty string is also a legal value, which also
234      * means platform-default encoding.
235      * @deprecated Disclaimer: this method is <B>not an API method</B>. It may not
236      * be available in future releases.
237      * @param someFile file object to retrieve encoding for
238      * @return encoding string, or null if no explicit encoding is given.
239      */

240     public static String JavaDoc getFileEncoding0(FileObject someFile) {
241         return (String JavaDoc)someFile.getAttribute(ATTR_FILE_ENCODING);
242     }
243     
244     /**
245      * Retrieves file's encoding. Returns the default encoding for java files,
246      * if the file's specific encoding is not set.
247      * @deprecated Disclaimer: this method is <B>not an API method</B>. It may not
248      * be available in future releases.
249      * @param someFile file object to retrieve encoding for
250      * @return encoding string, or null if no explicit encoding is given in file's
251      * or IDE's settings.
252      */

253     public static String JavaDoc getFileEncoding(FileObject someFile) {
254         String JavaDoc enc = getFileEncoding0(someFile);
255         if (enc == null) {
256             enc = JavaSettings.getDefault().getDefaultEncoding();
257         }
258         if ("".equals(enc))
259             return null;
260         else
261             return enc;
262     }
263     
264     /**
265      * Retrieves file's encoding. Returns the default encoding for java files,
266      * if the file's specific encoding is not set.
267      * This implementation stores the encoding information into file's extended
268      * attributes (so it won't work on JARs).
269      * @deprecated Disclaimer: this method is <B>not an API method</B>. It may not
270      * be available in future releases.
271      * @param someFile file object to set encoding for
272      * @param enc encoding string. Null means revert to the default encoding.
273      */

274     public static void setFileEncoding(FileObject someFile, String JavaDoc enc) throws IOException {
275         someFile.setAttribute(ATTR_FILE_ENCODING, enc);
276     }
277     
278     static void throwException(String JavaDoc desc, String JavaDoc bundleKey) throws SourceException {
279     throw (SourceException)getErrorManager().annotate(
280         new SourceException(desc),
281         getString(bundleKey)
282     );
283     }
284     
285     static SourceException wrapException(Exception JavaDoc ex) {
286     SourceException x = new SourceException("Exception wrapper"); // NOI18N
287
annotateThrowable(x, ex);
288     return x;
289     }
290
291     public static char[] readContents(Reader r) throws IOException {
292         int read = 0;
293         int total = 0;
294         int offset;
295         char[] buffer;
296         List buflist = new LinkedList JavaDoc();
297
298         do {
299             buffer = new char[2048];
300             offset = 0;
301             while (offset < buffer.length) {
302                 read = r.read(buffer, offset, buffer.length - offset);
303                 if (read == -1) break;
304                 offset += read;
305             }
306             if (offset > 0) buflist.add(buffer);
307             total += offset;
308         } while (read >= 0);
309         r.close();
310
311         buffer = new char[total];
312         Iterator JavaDoc it = buflist.iterator();
313         int offset2 = 0;
314         while (it.hasNext()) {
315             char[] buf = (char[])it.next();
316             int size = (it.hasNext()) ? buf.length : total - offset2;
317             System.arraycopy(buf, 0, buffer, offset2, size);
318             offset2 += size;
319         }
320         return buffer;
321     }
322     
323     private static String JavaDoc getDocumentText(FileObject fo, boolean save) throws IOException {
324         DataObject obj = DataObject.find(fo);
325         JavaEditor editor = null;
326
327         if (obj instanceof JavaDataObject)
328             editor = ((JavaDataObject) obj).getJavaEditor();
329
330     final Document JavaDoc doc;
331         if ((editor != null) && (doc = editor.getDocument()) != null) {
332             // loading from the memory (Document)
333
final String JavaDoc[] str = new String JavaDoc[1];
334             // safely take the text from the document
335
Runnable JavaDoc run = new Runnable JavaDoc() {
336                                public void run() {
337                                    try {
338                                        str[0] = doc.getText(0, doc.getLength());
339                                    }
340                                    catch (BadLocationException JavaDoc e) {
341                                        // impossible
342
}
343                                }
344                            };
345             if (save) {
346                 SaveCookie cookie = (SaveCookie) obj.getCookie(SaveCookie.class);
347                 if (cookie != null) {
348                     cookie.save();
349                 }
350             }
351             JavaMetamodel.getDefaultRepository().beginTrans(false);
352             try {
353                 doc.render(run);
354             } finally {
355                 JavaMetamodel.getDefaultRepository().endTrans();
356             }
357             return str[0];
358         } else {
359             return null;
360         }
361     }
362     
363     /** Returns contents of fileobject fo. If the object is opened in the editor,
364       the function returns current contents of the edited document. In that case,
365       if <b>save</b> is true, the editor content is saved.
366       If the file is not opened in a JavaEditor, it is read from the disk and
367       guarded sections are filtered out.
368       @return contents of the file/editor document; guarded section markers are filtered out.
369     */

370     public static char[] getContent(FileObject fo, boolean save, boolean filter, String JavaDoc encoding) throws IOException {
371         String JavaDoc text = getDocumentText(fo, save);
372         if (text == null) {
373             // loading from the file
374
InputStream is = new BufferedInputStream(fo.getInputStream());
375             Reader reader;
376             if (filter) {
377                 reader = new GuardedReader(is, true, encoding);
378             } else {
379                 if (encoding == null) {
380                     reader = new InputStreamReader(is);
381                 } else {
382                     reader = new InputStreamReader(is, encoding);
383                 }
384             }
385             return readContents(reader);
386         } else {
387             return text.toCharArray();
388         }
389     }
390     
391     public static InputStream createInputStream(FileObject fo, boolean save, boolean store) throws IOException {
392         return createInputStream(fo, save,store, null);
393     }
394
395     /** Creates new input stream from the file object.
396     * Finds the java data object, checks if the document is loaded and
397     * and create the stream either from the file object either from the document.
398     * @param fo fileobject with the source
399     * @param store if there is required the building and storing the elements
400     * hierarchy
401     * @exception IOException if any i/o problem occured during reading
402       @deprecated ParserInputStream that is being created by this function does not
403         fit well in I18N environments.
404     */

405     public static InputStream createInputStream(FileObject fo, boolean save, boolean store, String JavaDoc encoding) throws IOException {
406         String JavaDoc text = getDocumentText(fo, save);
407         
408         if (text == null) {
409             // loading from the file
410
InputStream is = new BufferedInputStream(fo.getInputStream());
411             if (store) {
412                 //PENDING - improve performance
413
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
414                 OutputStreamWriter outWriter = new OutputStreamWriter(byteStream);
415                 GuardedReader reader = new GuardedReader(is, true);
416                 try {
417                     int c;
418                     while ((c = reader.read()) != -1) {
419                         outWriter.write(c);
420                     }
421                 }
422                 finally {
423                     outWriter.close();
424                     is.close();
425                 }
426                 is = new ByteArrayInputStream(byteStream.toByteArray());
427             }
428             return new ParserInputStream(is);
429         } else {
430             return new ParserInputStream(text, encoding);
431         }
432     }
433     
434     /** The input stream which holds all data which are read in the StringBuffer.
435      * @deprecated The class doesn't process character data in the stream and
436      * is not very usable in I18N environments.
437      */

438     static class ParserInputStream extends InputStream {
439         
440         /** The underlaying stream. */
441         private InputStream stream;
442         
443         /** Whole text */
444         private String JavaDoc text;
445         
446         /** The string buffer which collect the data. */
447         private StringBuffer JavaDoc buffer;
448         
449         /** This flag determines if there is used the text field or buffer field.
450          * The constructor set it
451          */

452         private boolean mode;
453         
454         /** The counter of read chars */
455         private int counter;
456         
457         /** Offset of the begins of the lines (e.g. offset of [line,col] is lines[line] + col - 1
458          */

459         private int[] lines = new int[200];
460         
461         /** Current line counter - it is used for filling the lines array in the read method
462          */

463         int lineCounter = 2;
464         
465         /** Length of the current line
466          */

467         int currentLineLength = 0;
468         
469         /** Creates the stream from the text.
470          */

471         ParserInputStream(String JavaDoc text) {
472             this(text, null);
473         }
474         
475         ParserInputStream(String JavaDoc text, String JavaDoc encoding) {
476             this.text = text;
477             counter = 0;
478             mode = false;
479             ByteArrayOutputStream outstm = new ByteArrayOutputStream(text.length());
480             Writer wr = null;
481             
482             if (encoding != null) {
483                 try {
484                     wr = new OutputStreamWriter(outstm, encoding);
485                 } catch (UnsupportedEncodingException ex) {
486                 }
487             }
488             if (wr == null) {
489                 wr = new OutputStreamWriter(outstm);
490             }
491             
492             try {
493                 wr.write(text);
494                 wr.close();
495             } catch (IOException ex) {
496             }
497             this.stream = new ByteArrayInputStream(outstm.toByteArray());
498         }
499         
500         /** Creates the stream from the another stream. */
501         ParserInputStream(InputStream stream) {
502             this.stream = stream;
503             buffer = new StringBuffer JavaDoc();
504             mode = true;
505         }
506         
507         /** Gets the part of the text which was already read.
508          * @param begin the begin index
509          * @param end the end index
510          */

511         public String JavaDoc getString(int begin, int end) {
512             return mode ? buffer.substring(begin, end) : text.substring(begin, end);
513         }
514         
515         /** Gets the part of the text which was already read.
516          * End is last position which was already read.
517          * @param begin the begin index
518          */

519         public String JavaDoc getString(int begin) {
520             if (mode) {
521                 return buffer.substring(begin);
522             }
523             else {
524                 int end = Math.min(counter - 1, text.length());
525                 return text.substring(begin, end);
526             }
527         }
528         
529         /** Read one character from the stream. */
530         public int read() throws IOException {
531             int x = stream.read();
532             if (mode && (x != -1)) {
533                 buffer.append((char)x);
534                 counter++;
535             }
536             
537             // counting line's length
538
if (x == (int)'\n') {
539                 if (lineCounter == lines.length - 1) {
540                     int[] newLines = new int[lineCounter + lineCounter];
541                     System.arraycopy(lines, 0, newLines, 0, lines.length);
542                     lines = newLines;
543                 }
544                 lines[lineCounter] = lines[lineCounter - 1] + currentLineLength + 1;
545                 lineCounter++;
546                 currentLineLength = 0;
547             }
548             else {
549                 currentLineLength++;
550             }
551             
552             return x;
553         }
554         
555         /** Closes the stream */
556         public void close() throws IOException {
557             stream.close();
558         }
559         
560         /** Compute offset in the stream from line and column.
561          * @return the offset
562          */

563         int getOffset(int line, int column) {
564             return lines[line] + column - 1;
565         }
566         
567     }
568 }
569
Popular Tags