1 19 20 package org.netbeans.modules.diff; 21 22 import java.io.*; 23 import java.lang.reflect.Method ; 24 import javax.swing.JEditorPane ; 25 import javax.swing.text.BadLocationException ; 26 import javax.swing.text.Document ; 27 import javax.swing.text.EditorKit ; 28 import javax.swing.text.StyledDocument ; 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 54 public class EncodedReaderFactory { 55 56 57 private static final String CHAR_SET_ATTRIBUTE = "Content-Encoding"; 59 private static EncodedReaderFactory factory; 60 61 62 private EncodedReaderFactory() { 63 } 64 65 66 public static synchronized EncodedReaderFactory getDefault() { 67 if (factory == null) { 68 factory = new EncodedReaderFactory(); 69 } 70 return factory; 71 } 72 73 76 public Reader getReader(File file, String mimeType) throws FileNotFoundException { 77 return getReader(file, mimeType, getEncoding(file)); 78 } 79 80 83 public Reader getReader(File file, String mimeType, String 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 name = file.getName(); 93 int endingIndex = name.lastIndexOf('.'); 94 String ext = (endingIndex >= 0 && endingIndex < (name.length() - 1)) ? name.substring(endingIndex + 1) : ""; 95 if (!"java".equalsIgnoreCase(ext)) { try { file = FileUtil.normalizeFile(file); 98 FileObject fo = FileUtil.toFileObject(file); 99 if (fo != null) { 100 r = getReaderFromEditorSupport(fo, fo); 101 } 102 } catch (IllegalArgumentException 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 r = new InputStreamReader(new FileInputStream(file)); 112 } 113 return r; 114 } 115 116 public Reader getReader(FileObject fo, String encoding) throws FileNotFoundException { 117 return getReader(fo, encoding, fo.getExt()); 118 } 119 120 public Reader getReader(FileObject fo, String encoding, String secondFileExt) throws FileNotFoundException { 121 return getReader(fo, encoding, fo, secondFileExt); 122 } 123 124 public Reader getReader(FileObject fo, String encoding, FileObject type) throws FileNotFoundException { 125 return getReader(fo, encoding, type, type.getExt()); 126 } 127 128 private Reader getReader(FileObject fo, String encoding, FileObject type, String 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 ext = type.getExt(); 138 if (!"java".equalsIgnoreCase(ext) || !ext.equals(secondFileExt)) { r = getReaderFromEditorSupport(fo, type); 143 if (r == null) { 144 r = getReaderFromKit(null, fo, type.getMIMEType()); 145 } 146 } 147 if (r == null) { 148 r = new InputStreamReader(fo.getInputStream()); 150 } 151 return r; 152 } 153 154 155 private Reader getReaderFromEditorSupport(FileObject fo, FileObject type) throws FileNotFoundException { 156 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 if (editorSupport == null) { 173 return null; 174 } 175 try { 176 Method createKitMethod = getDeclaredMethod(editorSupport.getClass(), "createEditorKit", new Class [] {}); 177 createKitMethod.setAccessible(true); 178 EditorKit kit = (EditorKit ) createKitMethod.invoke(editorSupport, new Object [] {}); 179 Method createStyledDocumentMethod = getDeclaredMethod(editorSupport.getClass(), 181 "createStyledDocument", new Class [] { EditorKit .class }); 182 createStyledDocumentMethod.setAccessible(true); 183 StyledDocument doc = (StyledDocument ) createStyledDocumentMethod.invoke(editorSupport, new Object [] { kit }); 184 Method loadFromStreamToKitMethod = getDeclaredMethod(editorSupport.getClass(), 185 "loadFromStreamToKit", new Class [] { StyledDocument .class, InputStream.class, EditorKit .class }); 186 loadFromStreamToKitMethod.setAccessible(true); 187 InputStream in = fo.getInputStream(); 188 try { 189 loadFromStreamToKitMethod.invoke(editorSupport, new Object [] { doc, in, kit }); 190 } finally { 191 try { in.close(); } catch (IOException ioex) {} 192 } 193 String text = doc.getText(0, doc.getLength()); 194 doc = null; return new StringReader(text); 196 } catch (Exception ex) { 197 ex.printStackTrace(); 198 return null; 199 } 200 } 201 202 203 private Writer getWriterFromEditorSupport(final FileObject fo, FileLock lock) throws FileNotFoundException { 204 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 if (editorSupport == null) { 223 return null; 224 } 225 try { 226 Method createKitMethod = getDeclaredMethod(editorSupport.getClass(), "createEditorKit", new Class [] {}); 227 createKitMethod.setAccessible(true); 228 final EditorKit kit = (EditorKit ) createKitMethod.invoke(editorSupport, new Object [] {}); 229 Method createStyledDocumentMethod = getDeclaredMethod(editorSupport.getClass(), 231 "createStyledDocument", new Class [] { EditorKit .class }); 232 createStyledDocumentMethod.setAccessible(true); 233 final StyledDocument doc = (StyledDocument ) createStyledDocumentMethod.invoke(editorSupport, new Object [] { kit }); 234 final Method saveFromKitToStreamMethod = getDeclaredMethod(editorSupport.getClass(), 235 "saveFromKitToStream", new Class [] { StyledDocument .class, EditorKit .class, OutputStream.class }); 236 saveFromKitToStreamMethod.setAccessible(true); 237 238 return new DocWriter(doc, fo, lock, null, kit, editorSupport, saveFromKitToStreamMethod); 239 240 } catch (Exception ex) { 241 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 242 return null; 243 } 244 } 245 246 private static Method getDeclaredMethod(Class <?> objClass, String name, Class [] args) throws NoSuchMethodException , SecurityException { 247 try { 248 return objClass.getDeclaredMethod(name, args); 249 } catch (NoSuchMethodException nsmex) { 250 Class superClass = objClass.getSuperclass(); 251 if (superClass != null) { 252 return getDeclaredMethod(superClass, name, args); 253 } else { 254 throw nsmex; 255 } 256 } 257 } 258 259 260 private Reader getReaderFromKit(File file, FileObject fo, String mimeType) throws FileNotFoundException { 261 EditorKit kit = CloneableEditorSupport.getEditorKit(mimeType); 262 if (kit.getContentType().equalsIgnoreCase("text/plain") && "text/x-dtd".equalsIgnoreCase(mimeType)) { 263 kit = CloneableEditorSupport.getEditorKit("text/xml"); 265 } 266 if (kit != null) { 268 Document 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 text = doc.getText(0, doc.getLength()); 278 doc = null; 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 blex) { 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 302 private Writer getWriterFromKit(File file, FileObject fo, FileLock lock, String mimeType) throws FileNotFoundException { 303 EditorKit kit = CloneableEditorSupport.getEditorKit(mimeType); 304 if (kit.getContentType().equalsIgnoreCase("text/plain") && "text/x-dtd".equalsIgnoreCase(mimeType)) { 305 kit = CloneableEditorSupport.getEditorKit("text/xml"); 307 } 308 if (kit != null) { 310 Document doc = kit.createDefaultDocument(); 311 return new DocWriter(doc, fo, lock, file, kit, null, null); 312 } 313 return null; 314 } 315 316 319 public Writer getWriter(File file, String mimeType) throws FileNotFoundException { 320 return getWriter(file, mimeType, getEncoding(file)); 321 } 322 323 326 public Writer getWriter(File file, String mimeType, String 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 name = file.getName(); 336 int endingIndex = name.lastIndexOf('.'); 337 String ext = (endingIndex >= 0 && endingIndex < (name.length() - 1)) ? name.substring(endingIndex + 1) : ""; 338 if (!"java".equalsIgnoreCase(ext)) { try { 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 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 w = new OutputStreamWriter(new FileOutputStream(file)); 363 } 364 return w; 365 } 366 367 370 public Writer getWriter(FileObject fo, FileLock lock, String 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 ext = fo.getExt(); 383 if (!"java".equalsIgnoreCase(ext)) { w = getWriterFromEditorSupport(fo, lock); 386 if (w == null) { 387 w = getWriterFromKit(null, fo, lock, fo.getMIMEType()); 388 } 389 } 390 if (w == null) { 391 w = new OutputStreamWriter(fo.getOutputStream(lock)); 393 } 394 return w; 395 } 396 397 398 public String getEncoding(FileObject fo) { 399 return getEncoding(FileUtil.toFile(fo)); 400 } 401 402 public static String decodeName(File fo) { 403 String ret = fo.getName(); 404 if (fo.getParent() != null && fo.getParent().endsWith("CVS" + File.separator + "RevisionCache")) { String name = fo.getName(); 406 int hashOffset = name.lastIndexOf("#"); if (hashOffset != 1) { 408 ret = name.substring(0, hashOffset); 409 } 410 } 411 return ret; 412 } 413 414 public String getEncoding(File file) { 415 String 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 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); } 431 if (encoding == null) { 432 encoding = fo.getAttribute(CHAR_SET_ATTRIBUTE); } 434 } 435 436 if (name.endsWith(".xml") || name.endsWith(".dtd") || name.endsWith(".xsd") || name.endsWith(".xsl")) { 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); 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 findJavaEncoding(FileObject fo) { 462 ClassLoader systemClassLoader = 463 (ClassLoader ) Lookup.getDefault().lookup(ClassLoader .class); 464 Method org_netbeans_modules_java_Util_getFileEncoding = null; 465 try { 466 Class <?> c = systemClassLoader. 467 loadClass("org.netbeans.modules.java.Util"); org_netbeans_modules_java_Util_getFileEncoding = 469 c.getMethod("getFileEncoding", new Class [] {FileObject.class}); 470 } catch (Exception e) { 471 } 473 if (org_netbeans_modules_java_Util_getFileEncoding != null) { 474 try { 475 String encoding = (String ) org_netbeans_modules_java_Util_getFileEncoding. 476 invoke(null, new Object [] {fo}); 477 return encoding; 478 } catch (Exception e) { 479 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 480 } 481 } 482 return null; 483 } 484 485 private static String findPropertiesEncoding() { 486 return "ISO-8859-1"; } 488 489 private static class DocWriter extends Writer { 490 491 private Document doc; 492 private FileObject fo; 493 private FileLock foLock; 494 private File file; 495 private EditorKit kit; 496 private CloneableEditorSupport editorSupport; 497 private Method saveFromKitToStreamMethod; 498 private boolean closed; 499 500 public DocWriter(Document doc, FileObject fo, FileLock foLock, File file, 501 EditorKit kit, CloneableEditorSupport editorSupport, 502 Method 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 513 public void write(int c) throws IOException { 514 try { 515 doc.insertString(doc.getLength(), Character.toString((char) c), null); 516 } catch (BadLocationException blex) { 517 IOException ioex = new IOException(blex.getLocalizedMessage()); 518 ioex.initCause(blex); 519 throw ioex; 520 } 521 } 522 523 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 (); 536 } else if (len == 0) { 537 return; 538 } 539 try { 540 doc.insertString(doc.getLength(), new String (cbuf, off, len), null); 541 } catch (BadLocationException blex) { 542 IOException ioex = new IOException(blex.getLocalizedMessage()); 543 ioex.initCause(blex); 544 throw ioex; 545 } 546 } 547 548 551 public void write(String str) throws IOException { 552 try { 553 doc.insertString(doc.getLength(), str, null); 554 } catch (BadLocationException 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 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 [] { doc, kit, out }); 576 } catch (Exception 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 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 |