KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > diff > EncodedReaderFactory


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.diff;
21
22 import java.io.*;
23 import java.lang.reflect.Method JavaDoc;
24 import javax.swing.JEditorPane JavaDoc;
25 import javax.swing.text.BadLocationException JavaDoc;
26 import javax.swing.text.Document JavaDoc;
27 import javax.swing.text.EditorKit JavaDoc;
28 import javax.swing.text.StyledDocument JavaDoc;
29
30 import org.openide.ErrorManager;
31 import org.openide.cookies.EditCookie;
32 import org.openide.filesystems.FileLock;
33
34 import org.openide.filesystems.FileObject;
35 import org.openide.filesystems.FileUtil;
36
37 import org.openide.loaders.DataObject;
38 import org.openide.loaders.DataObjectNotFoundException;
39 import org.openide.text.CloneableEditorSupport;
40 import org.openide.util.Lookup;
41
42 /**
43  * Factory of readers that are encoded according to best known approach how to
44  * get the encoding information.
45  * <p>
46  * This factory should ideally be replaced by some public APIs. This uses just
47  * heuristics combined with a lot of reflection calls to find things out.
48  * This is intended to be only a temporary solution.
49  * <p>
50  * Use on your own risk.
51  *
52  * @author Martin Entlicher
53  */

54 public class EncodedReaderFactory {
55     
56     /** The FileObject attribute that defines the encoding of the FileObject content. */
57     private static final String JavaDoc CHAR_SET_ATTRIBUTE = "Content-Encoding"; // NOI18N
58

59     private static EncodedReaderFactory factory;
60     
61     /** Creates a new instance of EncodedReaderFactory */
62     private EncodedReaderFactory() {
63     }
64     
65     /** Get the default implementation. */
66     public static synchronized EncodedReaderFactory getDefault() {
67         if (factory == null) {
68             factory = new EncodedReaderFactory();
69         }
70         return factory;
71     }
72     
73     /**
74      * Get the reader from file of given MIME type, it tries to find the best encoding itself.
75      */

76     public Reader getReader(File file, String JavaDoc mimeType) throws FileNotFoundException {
77         return getReader(file, mimeType, getEncoding(file));
78     }
79     
80     /**
81      * Get the reader from file of given MIME type, suggest the encoding, if known.
82      */

83     public Reader getReader(File file, String JavaDoc mimeType, String JavaDoc encoding) throws FileNotFoundException {
84         if (encoding != null) {
85             try {
86                 return new InputStreamReader(new FileInputStream(file), encoding);
87             } catch (UnsupportedEncodingException ueex) {
88                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ueex);
89             }
90         }
91         Reader r = null;
92         String JavaDoc name = file.getName();
93         int endingIndex = name.lastIndexOf('.');
94         String JavaDoc ext = (endingIndex >= 0 && endingIndex < (name.length() - 1)) ? name.substring(endingIndex + 1) : "";
95         if (!"java".equalsIgnoreCase(ext)) { // We read the encoding for Java files explicitely
96
try { // If it's not defined, read with default encoding from stream (because of guarded blocks)
97
file = FileUtil.normalizeFile(file);
98                 FileObject fo = FileUtil.toFileObject(file);
99                 if (fo != null) {
100                     r = getReaderFromEditorSupport(fo, fo);
101                 }
102             } catch (IllegalArgumentException JavaDoc iaex) {
103                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, iaex);
104             }
105             if (r == null) {
106                 r = getReaderFromKit(file, null, mimeType);
107             }
108         }
109         if (r == null) {
110             // Fallback, use current encoding
111
r = new InputStreamReader(new FileInputStream(file));
112         }
113         return r;
114     }
115     
116     public Reader getReader(FileObject fo, String JavaDoc encoding) throws FileNotFoundException {
117         return getReader(fo, encoding, fo.getExt());
118     }
119     
120     public Reader getReader(FileObject fo, String JavaDoc encoding, String JavaDoc secondFileExt) throws FileNotFoundException {
121         return getReader(fo, encoding, fo, secondFileExt);
122     }
123     
124     public Reader getReader(FileObject fo, String JavaDoc encoding, FileObject type) throws FileNotFoundException {
125         return getReader(fo, encoding, type, type.getExt());
126     }
127     
128     private Reader getReader(FileObject fo, String JavaDoc encoding, FileObject type, String JavaDoc secondFileExt) throws FileNotFoundException {
129         if (encoding != null) {
130             try {
131                 return new InputStreamReader(fo.getInputStream(), encoding);
132             } catch (UnsupportedEncodingException ueex) {
133                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ueex);
134             }
135         }
136         Reader r = null;
137         String JavaDoc ext = type.getExt();
138         if (!"java".equalsIgnoreCase(ext) || !ext.equals(secondFileExt)) {// We read the encoding for Java files explicitely
139
// If it's not defined, read with default encoding from stream (because of guarded blocks)
140
// But when the extensions of the two files are different (comparing Java files with something else),
141
// we have to use the Document approach for both due to possible different line-endings.
142
r = getReaderFromEditorSupport(fo, type);
143             if (r == null) {
144                 r = getReaderFromKit(null, fo, type.getMIMEType());
145             }
146         }
147         if (r == null) {
148             // Fallback, use current encoding
149
r = new InputStreamReader(fo.getInputStream());
150         }
151         return r;
152     }
153     
154     /** @return The reader or <code>null</code>. */
155     private Reader getReaderFromEditorSupport(FileObject fo, FileObject type) throws FileNotFoundException {
156         //System.out.println("getReaderFromEditorSupport("+fo+")");
157
DataObject dobj;
158         try {
159             dobj = DataObject.find(type);
160         } catch (DataObjectNotFoundException donfex) {
161             return null;
162         }
163         if (!type.equals(dobj.getPrimaryFile())) {
164             return null;
165         }
166         EditCookie edit = (EditCookie) dobj.getCookie(EditCookie.class);
167         CloneableEditorSupport editorSupport = null;
168         if (edit instanceof CloneableEditorSupport) {
169             editorSupport = (CloneableEditorSupport) edit;
170         }
171         //System.out.println(" editorSupport = "+editorSupport);
172
if (editorSupport == null) {
173             return null;
174         }
175         try {
176             Method JavaDoc createKitMethod = getDeclaredMethod(editorSupport.getClass(), "createEditorKit", new Class JavaDoc[] {});
177             createKitMethod.setAccessible(true);
178             EditorKit JavaDoc kit = (EditorKit JavaDoc) createKitMethod.invoke(editorSupport, new Object JavaDoc[] {});
179             //System.out.println(" KIT from cloneable editor support = "+kit);
180
Method JavaDoc createStyledDocumentMethod = getDeclaredMethod(editorSupport.getClass(),
181                     "createStyledDocument", new Class JavaDoc[] { EditorKit JavaDoc.class });
182             createStyledDocumentMethod.setAccessible(true);
183             StyledDocument JavaDoc doc = (StyledDocument JavaDoc) createStyledDocumentMethod.invoke(editorSupport, new Object JavaDoc[] { kit });
184             Method JavaDoc loadFromStreamToKitMethod = getDeclaredMethod(editorSupport.getClass(),
185                     "loadFromStreamToKit", new Class JavaDoc[] { StyledDocument JavaDoc.class, InputStream.class, EditorKit JavaDoc.class });
186             loadFromStreamToKitMethod.setAccessible(true);
187             InputStream in = fo.getInputStream();
188             try {
189                 loadFromStreamToKitMethod.invoke(editorSupport, new Object JavaDoc[] { doc, in, kit });
190             } finally {
191                 try { in.close(); } catch (IOException ioex) {}
192             }
193             String JavaDoc text = doc.getText(0, doc.getLength());
194             doc = null; // Release it, we have the text
195
return new StringReader(text);
196         } catch (Exception JavaDoc ex) {
197             ex.printStackTrace();
198             return null;
199         }
200     }
201     
202     /** @return The writer or <code>null</code>. */
203     private Writer getWriterFromEditorSupport(final FileObject fo, FileLock lock) throws FileNotFoundException {
204         //System.out.println("getWriterFromEditorSupport("+fo+")");
205
DataObject dobj;
206         try {
207             dobj = DataObject.find(fo);
208         } catch (DataObjectNotFoundException donfex) {
209             return null;
210         }
211         if (!fo.equals(dobj.getPrimaryFile())) {
212             return null;
213         }
214         EditCookie edit = (EditCookie) dobj.getCookie(EditCookie.class);
215         final CloneableEditorSupport editorSupport;
216         if (edit instanceof CloneableEditorSupport) {
217             editorSupport = (CloneableEditorSupport) edit;
218         } else {
219             editorSupport = null;
220         }
221         //System.out.println(" editorSupport = "+editorSupport);
222
if (editorSupport == null) {
223             return null;
224         }
225         try {
226             Method JavaDoc createKitMethod = getDeclaredMethod(editorSupport.getClass(), "createEditorKit", new Class JavaDoc[] {});
227             createKitMethod.setAccessible(true);
228             final EditorKit JavaDoc kit = (EditorKit JavaDoc) createKitMethod.invoke(editorSupport, new Object JavaDoc[] {});
229             //System.out.println(" KIT from cloneable editor support = "+kit);
230
Method JavaDoc createStyledDocumentMethod = getDeclaredMethod(editorSupport.getClass(),
231                     "createStyledDocument", new Class JavaDoc[] { EditorKit JavaDoc.class });
232             createStyledDocumentMethod.setAccessible(true);
233             final StyledDocument JavaDoc doc = (StyledDocument JavaDoc) createStyledDocumentMethod.invoke(editorSupport, new Object JavaDoc[] { kit });
234             final Method JavaDoc saveFromKitToStreamMethod = getDeclaredMethod(editorSupport.getClass(),
235                     "saveFromKitToStream", new Class JavaDoc[] { StyledDocument JavaDoc.class, EditorKit JavaDoc.class, OutputStream.class });
236             saveFromKitToStreamMethod.setAccessible(true);
237             
238             return new DocWriter(doc, fo, lock, null, kit, editorSupport, saveFromKitToStreamMethod);
239             
240         } catch (Exception JavaDoc ex) {
241             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
242             return null;
243         }
244     }
245     
246     private static Method JavaDoc getDeclaredMethod(Class JavaDoc<?> objClass, String JavaDoc name, Class JavaDoc[] args) throws NoSuchMethodException JavaDoc, SecurityException JavaDoc {
247         try {
248             return objClass.getDeclaredMethod(name, args);
249         } catch (NoSuchMethodException JavaDoc nsmex) {
250             Class JavaDoc superClass = objClass.getSuperclass();
251             if (superClass != null) {
252                 return getDeclaredMethod(superClass, name, args);
253             } else {
254                 throw nsmex;
255             }
256         }
257     }
258     
259     /** @return The reader or <code>null</code>. */
260     private Reader getReaderFromKit(File file, FileObject fo, String JavaDoc mimeType) throws FileNotFoundException {
261         EditorKit JavaDoc kit = CloneableEditorSupport.getEditorKit(mimeType);
262         if (kit.getContentType().equalsIgnoreCase("text/plain") && "text/x-dtd".equalsIgnoreCase(mimeType)) {
263              // Use XML kit for DTDs if not defined otherwise
264
kit = CloneableEditorSupport.getEditorKit("text/xml");
265         }
266         //System.out.println(" KIT for "+mimeType+" = "+kit);
267
if (kit != null) {
268             Document JavaDoc doc = kit.createDefaultDocument();
269             InputStream stream = null;
270             try {
271                 if (file != null) {
272                     stream = new FileInputStream(file);
273                 } else {
274                     stream = fo.getInputStream();
275                 }
276                 kit.read(stream, doc, 0);
277                 String JavaDoc text = doc.getText(0, doc.getLength());
278                 //System.out.println(" TEXT = "+text);
279
doc = null; // Release it, we have the text
280
return new StringReader(text);
281             } catch (IOException ioex) {
282                 FileNotFoundException fnfex;
283                 if (file != null) {
284                     fnfex = new FileNotFoundException("Can not read file "+file.getAbsolutePath());
285                 } else {
286                     fnfex = new FileNotFoundException("Can not read file "+fo);
287                 }
288                 fnfex.initCause(ioex);
289                 throw fnfex;
290             } catch (BadLocationException JavaDoc blex) { // Something wrong???
291
ErrorManager.getDefault().notify(blex);
292             } finally {
293                 if (stream != null) {
294                     try { stream.close(); } catch (IOException e) {}
295                 }
296             }
297         }
298         return null;
299     }
300     
301     /** @return The writer or <code>null</code>. */
302     private Writer getWriterFromKit(File file, FileObject fo, FileLock lock, String JavaDoc mimeType) throws FileNotFoundException {
303         EditorKit JavaDoc kit = CloneableEditorSupport.getEditorKit(mimeType);
304         if (kit.getContentType().equalsIgnoreCase("text/plain") && "text/x-dtd".equalsIgnoreCase(mimeType)) {
305              // Use XML kit for DTDs if not defined otherwise
306
kit = CloneableEditorSupport.getEditorKit("text/xml");
307         }
308         //System.out.println(" KIT for "+mimeType+" = "+kit);
309
if (kit != null) {
310             Document JavaDoc doc = kit.createDefaultDocument();
311             return new DocWriter(doc, fo, lock, file, kit, null, null);
312         }
313         return null;
314     }
315     
316     /**
317      * Get the writer to file of given MIME type, it tries to find the best encoding itself.
318      */

319     public Writer getWriter(File file, String JavaDoc mimeType) throws FileNotFoundException {
320         return getWriter(file, mimeType, getEncoding(file));
321     }
322     
323     /**
324      * Get the writer to file of given MIME type, suggest the encoding, if known.
325      */

326     public Writer getWriter(File file, String JavaDoc mimeType, String JavaDoc encoding) throws FileNotFoundException {
327         if (encoding != null) {
328             try {
329                 return new OutputStreamWriter(new FileOutputStream(file), encoding);
330             } catch (UnsupportedEncodingException ueex) {
331                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ueex);
332             }
333         }
334         Writer w = null;
335         String JavaDoc name = file.getName();
336         int endingIndex = name.lastIndexOf('.');
337         String JavaDoc ext = (endingIndex >= 0 && endingIndex < (name.length() - 1)) ? name.substring(endingIndex + 1) : "";
338         if (!"java".equalsIgnoreCase(ext)) { // We read the encoding for Java files explicitely
339
try { // If it's not defined, read with default encoding from stream (because of guarded blocks)
340
file = FileUtil.normalizeFile(file);
341                 FileObject fo = FileUtil.toFileObject(file);
342                 if (fo != null) {
343                     FileLock lock;
344                     try {
345                         lock = fo.lock();
346                     } catch (IOException ioex) {
347                         FileNotFoundException fnfex = new FileNotFoundException(ioex.getLocalizedMessage());
348                         fnfex.initCause(ioex);
349                         throw fnfex;
350                     }
351                     w = getWriterFromEditorSupport(fo, lock);
352                 }
353             } catch (IllegalArgumentException JavaDoc iaex) {
354                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, iaex);
355             }
356             if (w == null) {
357                 w = getWriterFromKit(file, null, null, mimeType);
358             }
359         }
360         if (w == null) {
361             // Fallback, use current encoding
362
w = new OutputStreamWriter(new FileOutputStream(file));
363         }
364         return w;
365     }
366     
367     /**
368      * Get the writer to file, suggest the encoding, if known.
369      */

370     public Writer getWriter(FileObject fo, FileLock lock, String JavaDoc encoding) throws IOException {
371         if (lock == null) {
372             lock = fo.lock();
373         }
374         if (encoding != null) {
375             try {
376                 return new OutputStreamWriter(fo.getOutputStream(lock), encoding);
377             } catch (UnsupportedEncodingException ueex) {
378                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ueex);
379             }
380         }
381         Writer w = null;
382         String JavaDoc ext = fo.getExt();
383         if (!"java".equalsIgnoreCase(ext)) { // We read the encoding for Java files explicitely
384
// If it's not defined, read with default encoding from stream (because of guarded blocks)
385
w = getWriterFromEditorSupport(fo, lock);
386             if (w == null) {
387                 w = getWriterFromKit(null, fo, lock, fo.getMIMEType());
388             }
389         }
390         if (w == null) {
391             // Fallback, use current encoding
392
w = new OutputStreamWriter(fo.getOutputStream(lock));
393         }
394         return w;
395     }
396
397     /** Uses heuritisc to detect file encoding or null. */
398     public String JavaDoc getEncoding(FileObject fo) {
399         return getEncoding(FileUtil.toFile(fo));
400     }
401
402     public static String JavaDoc decodeName(File fo) {
403         String JavaDoc ret = fo.getName();
404         if (fo.getParent() != null && fo.getParent().endsWith("CVS" + File.separator + "RevisionCache")) { // NOI18N
405
String JavaDoc name = fo.getName();
406             int hashOffset = name.lastIndexOf("#"); // NOI18N
407
if (hashOffset != 1) {
408                 ret = name.substring(0, hashOffset);
409             }
410         }
411         return ret;
412     }
413
414     public String JavaDoc getEncoding(File file) {
415         String JavaDoc name = decodeName(file).toLowerCase();
416
417         if (name.endsWith(".properties")) {
418             return findPropertiesEncoding();
419         }
420         if (name.endsWith(".form")) {
421             return "utf8";
422         }
423
424         Object JavaDoc encoding = null;
425         file = FileUtil.normalizeFile(file);
426         FileObject fo = FileUtil.toFileObject(file);
427         if (fo != null) {
428             if (name.endsWith(".java")) {
429                 encoding = findJavaEncoding(fo); // is not in cache
430
}
431             if (encoding == null) {
432                 encoding = fo.getAttribute(CHAR_SET_ATTRIBUTE); // XXX is not in cache
433
}
434         }
435
436         if (name.endsWith(".xml") || name.endsWith(".dtd") || name.endsWith(".xsd") || name.endsWith(".xsl")) { // NOI18N
437
InputStream in = null;
438             try {
439                 in = new BufferedInputStream(new FileInputStream(file), 2048);
440                 encoding = XMLEncodingHelper.detectEncoding(in);
441             } catch (IOException e) {
442                 ErrorManager err = ErrorManager.getDefault();
443                 err.annotate(e, "Can not detect encoding for: " + file); // NOI18N
444
err.notify(ErrorManager.INFORMATIONAL, e);
445             } finally {
446                 if (in != null) {
447                     try {
448                         in.close();
449                     } catch (IOException e) {
450                     }
451                 }
452             }
453         }
454         if (encoding != null) {
455             return encoding.toString();
456         } else {
457             return null;
458         }
459     }
460     
461     private static String JavaDoc findJavaEncoding(FileObject fo) {
462         ClassLoader JavaDoc systemClassLoader =
463                 (ClassLoader JavaDoc) Lookup.getDefault().lookup(ClassLoader JavaDoc.class);
464         Method JavaDoc org_netbeans_modules_java_Util_getFileEncoding = null;
465         try {
466             Class JavaDoc<?> c = systemClassLoader.
467                     loadClass("org.netbeans.modules.java.Util"); // NOI18N
468
org_netbeans_modules_java_Util_getFileEncoding =
469                 c.getMethod("getFileEncoding", new Class JavaDoc[] {FileObject.class});
470         } catch (Exception JavaDoc e) {
471             // Ignore
472
}
473         if (org_netbeans_modules_java_Util_getFileEncoding != null) {
474             try {
475                 String JavaDoc encoding = (String JavaDoc) org_netbeans_modules_java_Util_getFileEncoding.
476                     invoke(null, new Object JavaDoc[] {fo});
477                 return encoding;
478             } catch (Exception JavaDoc e) {
479                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
480             }
481         }
482         return null;
483     }
484     
485     private static String JavaDoc findPropertiesEncoding() {
486         return "ISO-8859-1"; // NOI18N
487
}
488     
489     private static class DocWriter extends Writer {
490
491         private Document JavaDoc doc;
492         private FileObject fo;
493         private FileLock foLock;
494         private File file;
495         private EditorKit JavaDoc kit;
496         private CloneableEditorSupport editorSupport;
497         private Method JavaDoc saveFromKitToStreamMethod;
498         private boolean closed;
499
500         public DocWriter(Document JavaDoc doc, FileObject fo, FileLock foLock, File file,
501                          EditorKit JavaDoc kit, CloneableEditorSupport editorSupport,
502                          Method JavaDoc saveFromKitToStreamMethod) {
503             this.doc = doc;
504             this.fo = fo;
505             this.foLock = foLock;
506             this.file = file;
507             this.kit = kit;
508             this.editorSupport = editorSupport;
509             this.saveFromKitToStreamMethod = saveFromKitToStreamMethod;
510         }
511
512         /** Write a single character. */
513         public void write(int c) throws IOException {
514             try {
515                 doc.insertString(doc.getLength(), Character.toString((char) c), null);
516             } catch (BadLocationException JavaDoc blex) {
517                 IOException ioex = new IOException(blex.getLocalizedMessage());
518                 ioex.initCause(blex);
519                 throw ioex;
520             }
521         }
522
523         /**
524          * Write a portion of an array of characters.
525          *
526          * @param cbuf Array of characters
527          * @param off Offset from which to start writing characters
528          * @param len Number of characters to write
529          *
530          * @exception IOException If an I/O error occurs
531          */

532         public void write(char cbuf[], int off, int len) throws IOException {
533             if ((off < 0) || (off > cbuf.length) || (len < 0) ||
534                 ((off + len) > cbuf.length) || ((off + len) < 0)) {
535                 throw new IndexOutOfBoundsException JavaDoc();
536             } else if (len == 0) {
537                 return;
538             }
539             try {
540                 doc.insertString(doc.getLength(), new String JavaDoc(cbuf, off, len), null);
541             } catch (BadLocationException JavaDoc blex) {
542                 IOException ioex = new IOException(blex.getLocalizedMessage());
543                 ioex.initCause(blex);
544                 throw ioex;
545             }
546         }
547
548         /**
549          * Write a string.
550          */

551         public void write(String JavaDoc str) throws IOException {
552             try {
553                 doc.insertString(doc.getLength(), str, null);
554             } catch (BadLocationException JavaDoc blex) {
555                 IOException ioex = new IOException(blex.getLocalizedMessage());
556                 ioex.initCause(blex);
557                 throw ioex;
558             }
559         }
560
561         public void flush() throws IOException {}
562
563         /**
564          * Close the stream, flushing it first. Once a stream has been closed,
565          * further write() or flush() invocations will cause an IOException to be
566          * thrown. Closing a previously-closed stream, however, has no effect.
567          *
568          * @exception IOException If an I/O error occurs
569          */

570         public void close() throws IOException {
571             if (closed) return ;
572             if (saveFromKitToStreamMethod != null) {
573                 OutputStream out = fo.getOutputStream(foLock);
574                 try {
575                     saveFromKitToStreamMethod.invoke(editorSupport, new Object JavaDoc[] { doc, kit, out });
576                 } catch (Exception JavaDoc e) {
577                     IOException ioex = new IOException(e.getLocalizedMessage());
578                     ioex.initCause(e);
579                     throw ioex;
580                 } finally {
581                     try { out.close(); } catch (IOException ioex) {}
582                     foLock.releaseLock();
583                 }
584             } else {
585                 OutputStream out;
586                 if (file != null) {
587                     out = new FileOutputStream(file);
588                 } else {
589                     out = fo.getOutputStream(foLock);
590                 }
591                 try {
592                     kit.write(out, doc, 0, doc.getLength());
593                 } catch (BadLocationException JavaDoc blex) {
594                     IOException ioex = new IOException(blex.getLocalizedMessage());
595                     ioex.initCause(blex);
596                     throw ioex;
597                 } finally {
598                     out.close();
599                 }
600             }
601             closed = true;
602         }
603     }
604 }
605
Popular Tags