1 19 20 package org.openide.filesystems; 21 22 import java.io.File ; 23 import java.io.FileNotFoundException ; 24 import java.io.FilterOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.OutputStream ; 28 import java.io.Serializable ; 29 import java.net.URL ; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Collection ; 33 import java.util.Collections ; 34 import java.util.Enumeration ; 35 import java.util.LinkedList ; 36 import java.util.List ; 37 import java.util.StringTokenizer ; 38 import org.openide.util.Enumerations; 39 import org.openide.util.NbBundle; 40 41 47 public abstract class FileObject extends Object implements Serializable { 48 49 static final long serialVersionUID = 85305031923497718L; 50 51 59 public abstract String getName(); 60 61 67 public abstract String getExt(); 68 69 80 public abstract void rename(FileLock lock, String name, String ext) 81 throws IOException ; 82 83 92 public FileObject copy(FileObject target, String name, String ext) 93 throws IOException { 94 if (isFolder()) { 95 throw new IOException (NbBundle.getBundle(FileObject.class).getString("EXC_FolderCopy")); 96 } 97 98 FileObject dest = FileUtil.copyFileImpl(this, target, name, ext); 99 100 return dest; 101 } 102 103 113 public FileObject move(FileLock lock, FileObject target, String name, String ext) 114 throws IOException { 115 if (getParent().equals(target)) { 116 rename(lock, name, ext); 118 119 return this; 120 } else { 121 FileObject dest = copy(target, name, ext); 123 delete(lock); 124 125 return dest; 126 } 127 } 128 129 141 public String toString() { 142 String cname = getClass().getName(); 143 String cnameShort = cname.substring(cname.lastIndexOf('.') + 1); 144 145 return cnameShort + '@' + Integer.toHexString(System.identityHashCode(this)) + '[' + getPath() + 146 ']'; } 148 149 160 public String getPath() { 161 StringBuilder sb = new StringBuilder (); 162 constructName(sb, '/'); 163 164 return sb.toString(); 165 } 166 167 178 @Deprecated 179 public String getPackageNameExt(char separatorChar, char extSepChar) { 180 assert FileUtil.assertDeprecatedMethod(); 181 182 StringBuilder sb = new StringBuilder (); 183 184 if (isRoot() || getParent().isRoot()) { 185 return getNameExt(); 186 } 187 188 getParent().constructName(sb, separatorChar); 189 190 String ext = getExt(); 191 192 if ((ext == null) || ext.equals("")) { sb.append(separatorChar).append(getNameExt()); 194 } else { 195 sb.append(separatorChar).append(getName()).append(extSepChar).append(getExt()); 196 } 197 198 return sb.toString(); 199 } 200 201 207 @Deprecated 208 public String getPackageName(char separatorChar) { 209 assert FileUtil.assertDeprecatedMethod(); 210 211 StringBuilder sb = new StringBuilder (); 212 213 if (isRoot() || getParent().isRoot()) { 214 return (isFolder()) ? getNameExt() : getName(); 215 } 216 217 getParent().constructName(sb, separatorChar); 218 219 sb.append(separatorChar).append(getName()); 221 222 return sb.toString(); 223 } 224 225 229 public String getNameExt() { 230 String n = getName(); 231 String e = getExt(); 232 233 return ((e == null) || (e.length() == 0)) ? n : (n + '.' + e); 234 } 235 236 240 private void constructName(StringBuilder sb, char sepChar) { 241 FileObject parent = getParent(); 242 243 if ((parent != null) && !parent.isRoot()) { 244 parent.constructName(sb, sepChar); 245 sb.append(sepChar); 246 } 247 248 sb.append(getNameExt()); 249 } 250 251 259 public abstract FileSystem getFileSystem() throws FileStateInvalidException; 260 261 266 public abstract FileObject getParent(); 267 268 271 public abstract boolean isFolder(); 272 273 277 public abstract java.util.Date lastModified(); 278 279 283 public abstract boolean isRoot(); 284 285 289 public abstract boolean isData(); 290 291 296 public abstract boolean isValid(); 297 298 304 public boolean existsExt(String ext) { 305 FileObject parent = getParent(); 306 307 return (parent != null) && (parent.getFileObject(getName(), ext) != null); 308 } 309 310 316 public abstract void delete(FileLock lock) throws IOException ; 317 318 326 public final void delete() throws IOException { 327 FileLock lock = lock(); 328 329 try { 330 delete(lock); 331 } finally { 332 lock.releaseLock(); 333 } 334 } 335 336 340 abstract public Object getAttribute(String attrName); 341 342 347 abstract public void setAttribute(String attrName, Object value) 348 throws IOException ; 349 350 353 abstract public Enumeration <String > getAttributes(); 354 355 359 public final boolean hasExt(String ext) { 360 if (isHasExtOverride()) { 361 return hasExtOverride(ext); 362 } 363 364 return getExt().equals(ext); 365 } 366 367 368 boolean isHasExtOverride() { 369 return false; 370 } 371 372 373 boolean hasExtOverride(String ext) { 374 return false; 375 } 376 377 380 public abstract void addFileChangeListener(FileChangeListener fcl); 381 382 385 public abstract void removeFileChangeListener(FileChangeListener fcl); 386 387 391 protected void fireFileDataCreatedEvent(Enumeration <FileChangeListener> en, FileEvent fe) { 392 dispatchEvent(FCLSupport.Op.DATA_CREATED, en, fe); 393 } 394 395 399 protected void fireFileFolderCreatedEvent(Enumeration <FileChangeListener> en, FileEvent fe) { 400 dispatchEvent(FCLSupport.Op.FOLDER_CREATED, en, fe); 401 } 402 403 407 protected void fireFileChangedEvent(Enumeration <FileChangeListener> en, FileEvent fe) { 408 dispatchEvent(FCLSupport.Op.FILE_CHANGED, en, fe); 409 } 410 411 415 protected void fireFileDeletedEvent(Enumeration <FileChangeListener> en, FileEvent fe) { 416 dispatchEvent(FCLSupport.Op.FILE_DELETED, en, fe); 417 } 418 419 423 protected void fireFileAttributeChangedEvent(Enumeration <FileChangeListener> en, FileAttributeEvent fe) { 424 dispatchEvent(FCLSupport.Op.ATTR_CHANGED, en, fe); 425 } 426 427 431 protected void fireFileRenamedEvent(Enumeration <FileChangeListener> en, FileRenameEvent fe) { 432 dispatchEvent(FCLSupport.Op.FILE_RENAMED, en, fe); 433 } 434 435 437 private final void dispatchEvent(FCLSupport.Op op, Enumeration <FileChangeListener> en, FileEvent fe) { 438 try { 439 FileSystem fs = getFileSystem(); 440 fs.dispatchEvent(new ED(op, en, fe)); 441 } catch (FileStateInvalidException ex) { 442 } 444 } 445 446 final void dispatchEvent(Enumeration <FileChangeListener> en, FileEvent fe) { 447 try { 448 getFileSystem().dispatchEvent(new ED(en, fe)); 449 } catch (FileStateInvalidException ex) { 450 } 452 } 453 454 462 public String getMIMEType() { 463 return FileUtil.getMIMETypeOrDefault(this); 464 } 465 466 470 public abstract long getSize(); 471 472 477 public abstract InputStream getInputStream() throws FileNotFoundException ; 478 479 485 public abstract OutputStream getOutputStream(FileLock lock) 486 throws IOException ; 487 488 494 public final OutputStream getOutputStream() throws FileAlreadyLockedException, IOException { 495 final FileLock lock = lock(); 496 final OutputStream os; 497 try { 498 os = getOutputStream(lock); 499 return new FilterOutputStream (os) { 500 public void close() throws IOException { 501 try { 502 super.close(); 503 lock.releaseLock(); 504 } catch(IOException iex) { 505 if (lock.isValid()) { 506 lock.releaseLock(); 507 } 508 throw iex; 509 } 510 } 511 }; 512 } catch(IOException iex) { 513 if (lock.isValid()) { 514 lock.releaseLock(); 515 } 516 throw iex; 517 } 518 } 519 520 521 530 public abstract FileLock lock() throws IOException ; 531 532 543 @Deprecated 544 public abstract void setImportant(boolean b); 545 546 554 public abstract FileObject[] getChildren(); 555 556 562 public Enumeration <? extends FileObject> getChildren(final boolean rec) { 563 class WithChildren implements Enumerations.Processor<FileObject, FileObject> { 564 public FileObject process(FileObject fo, Collection <FileObject> toAdd) { 565 if (rec && fo.isFolder()) { 566 toAdd.addAll(Arrays.asList(fo.getChildren())); 567 } 568 569 return fo; 570 } 571 } 572 573 return Enumerations.queue(Enumerations.array(getChildren()), new WithChildren()); 574 } 575 576 580 public Enumeration <? extends FileObject> getFolders(boolean rec) { 581 return Enumerations.filter(getChildren(rec), new OnlyFolders(true)); 582 } 583 584 588 public Enumeration <? extends FileObject> getData(boolean rec) { 589 return Enumerations.filter(getChildren(rec), new OnlyFolders(false)); 590 } 591 592 601 public abstract FileObject getFileObject(String name, String ext); 602 603 610 public FileObject getFileObject(String relativePath) { 611 if (relativePath.startsWith("/")) { 612 relativePath = relativePath.substring(1); 613 } 614 615 FileObject myObj = this; 616 StringTokenizer st = new StringTokenizer (relativePath, "/"); 617 618 while ((myObj != null) && st.hasMoreTokens()) { 619 String nameExt = st.nextToken(); 620 myObj = myObj.getFileObject(nameExt, null); 621 } 622 623 return myObj; 624 } 625 626 635 public abstract FileObject createFolder(String name) 636 throws IOException ; 637 638 648 public abstract FileObject createData(String name, String ext) 649 throws IOException ; 650 651 661 public FileObject createData(String name) throws IOException { 662 return createData(name, ""); } 664 665 709 @Deprecated 710 public abstract boolean isReadOnly(); 711 712 721 public boolean canWrite() { 722 File f = FileUtil.toFile(this); 723 724 if (f != null) { 725 return f.canWrite(); 726 } 727 728 return !isReadOnly(); 729 } 730 731 740 public boolean canRead() { 741 File f = FileUtil.toFile(this); 742 743 if (f != null) { 744 return f.canRead(); 745 } 746 747 return true; 748 } 749 750 757 public void refresh(boolean expected) { 758 } 759 760 766 public void refresh() { 767 refresh(false); 768 } 769 770 779 public final URL getURL() throws FileStateInvalidException { 780 return URLMapper.findURL(this, URLMapper.INTERNAL); 782 } 783 784 789 public boolean isVirtual() { 790 return false; 791 } 792 793 796 static boolean isPriorityListener(FileChangeListener fcl) { 797 if (fcl instanceof PriorityFileChangeListener) { 798 return true; 799 } else { 800 return false; 801 } 802 } 803 804 interface PriorityFileChangeListener extends FileChangeListener {} 805 806 private class ED extends FileSystem.EventDispatcher { 807 private FCLSupport.Op op; 808 private Enumeration <FileChangeListener> en; 809 final private List <FileChangeListener> fsList; 810 final private List <FileChangeListener> repList; 811 812 813 private FileEvent fe; 814 815 public ED(FCLSupport.Op op, Enumeration <FileChangeListener> en, FileEvent fe) { 816 this.op = op; 817 this.en = en; 818 this.fe = fe; 819 FileSystem fs = null; 820 try { 821 fs = this.fe.getFile().getFileSystem(); 822 } catch (FileStateInvalidException ex) { 823 ExternalUtil.exception(ex); 824 } 825 ListenerList<FileChangeListener> fsll = (fs != null) ? fs.getFCLSupport().listeners : null; 826 ListenerList<FileChangeListener> repll = (fs != null && fs.getRepository() != null) ? fs.getRepository().getFCLSupport().listeners : null; 827 fsList = (fsll != null) ? new ArrayList <FileChangeListener>(fsll.getAllListeners()) : 828 new ArrayList <FileChangeListener>(); 829 repList = (repll != null) ? new ArrayList <FileChangeListener>(repll.getAllListeners()) : 830 new ArrayList <FileChangeListener>(); 831 832 } 833 834 public ED(Enumeration <FileChangeListener> en, FileEvent fe) { 835 this(null, en, fe); 836 } 837 838 841 protected void dispatch(boolean onlyPriority) { 842 if (this.op == null) { 843 this.op = fe.getFile().isFolder() ? FCLSupport.Op.FOLDER_CREATED : FCLSupport.Op.DATA_CREATED; 844 } 845 846 LinkedList <FileChangeListener> newEnum = new LinkedList <FileChangeListener>(); 848 while (en.hasMoreElements()) { 849 FileChangeListener fcl = en.nextElement(); 850 851 if (onlyPriority && !isPriorityListener(fcl)) { 852 newEnum.add(fcl); 853 854 continue; 855 } 856 FCLSupport.dispatchEvent(fcl, fe, op); 857 } 858 859 if (onlyPriority) { 860 this.en = Collections.enumeration(newEnum); 861 } 862 863 866 FileObject fo = fe.getFile(); 867 boolean transmit = false; 868 if (fo != null) { 869 switch (op) { 870 case FILE_CHANGED: 871 transmit = fo.equals(fe.getSource()); 872 break; 873 default: 874 transmit = !fo.equals(fe.getSource()); 875 } 876 877 } 878 879 if (!en.hasMoreElements() && transmit && !onlyPriority) { 880 FileSystem fs = null; 881 Repository rep = null; 882 883 try { 884 fs = fe.getFile().getFileSystem(); 885 rep = fs.getRepository(); 886 } catch (FileStateInvalidException fsix) { 887 return; 888 } 889 if (fs != null && fsList != null) { 890 for (FileChangeListener fcl : fsList) { 891 fs.getFCLSupport().dispatchEvent(fcl, fe, op); 892 } 893 } 894 895 896 if (rep != null && repList != null) { 897 for (FileChangeListener fcl : repList) { 898 rep.getFCLSupport().dispatchEvent(fcl, fe, op); 899 } 900 } 901 } 902 } 903 904 protected void setAtomicActionLink(EventControl.AtomicActionLink propID) { 905 fe.setAtomicActionLink(propID); 906 } 907 } 908 909 911 private static final class OnlyFolders implements Enumerations.Processor<FileObject, FileObject> { 912 private boolean folders; 913 914 public OnlyFolders(boolean folders) { 915 this.folders = folders; 916 } 917 918 public FileObject process(FileObject obj, Collection <FileObject> coll) { 919 FileObject fo = obj; 920 921 if (folders) { 922 return fo.isFolder() ? fo : null; 923 } else { 924 return fo.isData() ? fo : null; 925 } 926 } 927 } 928 } 930 | Popular Tags |