1 19 20 package org.openide.loaders; 21 22 import java.io.*; 23 import java.util.*; 24 import java.util.logging.Level ; 25 import java.util.logging.Logger ; 26 import javax.swing.event.*; 27 import org.openide.filesystems.*; 28 import org.openide.modules.ModuleInfo; 29 import org.openide.nodes.*; 30 import org.openide.util.*; 31 import org.openide.util.actions.SystemAction; 32 33 42 public abstract class DataLoaderPool extends Object 43 implements java.io.Serializable { 44 45 46 static final long serialVersionUID=-360141823874889956L; 47 48 private static MultiFileLoader[] systemLoaders; 49 50 private static MultiFileLoader[] defaultLoaders; 51 52 private static DataLoaderPool DEFAULT; 53 54 61 public static synchronized DataLoaderPool getDefault() { 62 if (DEFAULT == null) { 63 DEFAULT = Lookup.getDefault().lookup(DataLoaderPool.class); 64 if (DEFAULT == null) { 65 DEFAULT = new DefaultPool(); 66 } 67 } 68 return DEFAULT; 69 } 70 71 72 private transient DataLoader[] loaderArray; 73 74 private transient List<DataLoader> allLoaders; 75 76 private transient int cntchanges; 77 78 private transient EventListenerList listeners; 79 80 81 private transient DataLoader preferredLoader; 82 83 85 protected DataLoaderPool () { 86 } 87 88 94 protected DataLoaderPool (DataLoader loader) { 95 preferredLoader = loader; 96 } 97 98 104 protected abstract Enumeration<? extends DataLoader> loaders (); 105 106 111 public final synchronized void addChangeListener (ChangeListener chl) { 112 if (listeners == null) listeners = new EventListenerList(); 113 listeners.add( ChangeListener.class, chl); 114 } 115 116 120 public final synchronized void removeChangeListener (ChangeListener chl) { 121 if (listeners != null) { 122 listeners.remove( ChangeListener.class, chl); 123 } 124 } 125 126 129 protected final void fireChangeEvent (final ChangeEvent che) { 130 131 Object [] list; 132 synchronized( this ) { 133 cntchanges++; 134 loaderArray = null; 135 allLoaders = null; 136 137 if (listeners == null) return; 138 list = listeners.getListenerList(); 139 } 140 141 for (int i = list.length-2; i>=0; i-=2) { 143 if (list[i] == ChangeListener.class) { 144 ChangeListener l = (ChangeListener)list[i+1]; 145 l.stateChanged(che); 146 } 147 } 148 } 149 150 151 156 public static OperationListener createWeakOperationListener (OperationListener l, Object s) { 157 return WeakListeners.create(OperationListener.class, l, s); 158 } 159 160 163 public synchronized final void addOperationListener (OperationListener l) { 164 if (listeners == null) listeners = new EventListenerList(); 165 listeners.add( OperationListener.class, l); 166 } 167 168 171 public synchronized final void removeOperationListener (OperationListener l) { 172 if (listeners != null) { 173 listeners.remove( OperationListener.class, l); 174 } 175 } 176 177 182 final void fireOperationEvent (OperationEvent ev, int type) { 183 Object [] list; 184 synchronized( this ) { 185 if (listeners == null) return; 186 list = listeners.getListenerList(); 187 } 188 189 for (int i = list.length-2; i>=0; i-=2) { 191 if (list[i] == OperationListener.class) { 192 OperationListener l = (OperationListener)list[i+1]; 193 switch (type) { 194 case OperationEvent.COPY: 195 l.operationCopy ((OperationEvent.Copy)ev); 196 break; 197 case OperationEvent.MOVE: 198 l.operationMove ((OperationEvent.Move)ev); 199 break; 200 case OperationEvent.DELETE: 201 l.operationDelete (ev); 202 break; 203 case OperationEvent.RENAME: 204 l.operationRename ((OperationEvent.Rename)ev); 205 break; 206 case OperationEvent.SHADOW: 207 l.operationCreateShadow ((OperationEvent.Copy)ev); 208 break; 209 case OperationEvent.TEMPL: 210 l.operationCreateFromTemplate ((OperationEvent.Copy)ev); 211 break; 212 case OperationEvent.CREATE: 213 l.operationPostCreate (ev); 214 break; 215 } 216 } 217 } 218 } 219 220 236 public final Enumeration<DataLoader> allLoaders () { 237 List<DataLoader> all; 238 int oldcnt; 239 synchronized (this) { 240 all = this.allLoaders; 241 oldcnt = this.cntchanges; 242 } 243 244 if (all == null) { 245 all = new ArrayList<DataLoader>(); 246 if (preferredLoader != null) { 247 all.add(preferredLoader); 248 } 249 all.addAll(Arrays.asList(getSystemLoaders())); 250 Enumeration<? extends DataLoader> en = loaders(); 251 while(en.hasMoreElements()) { 252 all.add(en.nextElement()); 253 } 254 all.addAll(Arrays.asList(getDefaultLoaders())); 255 256 synchronized (this) { 257 if (oldcnt == this.cntchanges) { 258 this.allLoaders = all; 259 } 260 } 261 } 262 263 return Collections.enumeration(all); 264 } 265 266 271 public DataLoader[] toArray () { 272 DataLoader[] localArray = loaderArray; 273 if (localArray != null) 274 return localArray; 275 ArrayList<DataLoader> loaders = new ArrayList<DataLoader> (); 276 Enumeration<? extends DataLoader> en = loaders (); 277 while (en.hasMoreElements ()) { 278 loaders.add(en.nextElement ()); 279 } 280 localArray = new DataLoader[loaders.size()]; 281 localArray = loaders.toArray(localArray); 282 loaderArray = localArray; 283 return localArray; 284 } 285 286 294 public final DataLoader firstProducerOf(Class <? extends DataObject> clazz) { 295 Enumeration<DataLoader> en = allLoaders (); 296 while (en.hasMoreElements ()) { 297 DataLoader dl = en.nextElement(); 298 if (dl.getRepresentationClass ().isAssignableFrom (clazz)) { 299 return dl; 301 } 302 } 303 return null; 304 } 305 306 312 public final Enumeration<DataLoader> producersOf(final Class <? extends DataObject> clazz) { 313 class ProducerOf implements Enumerations.Processor<DataLoader,DataLoader> { 314 public DataLoader process(DataLoader dl, java.util.Collection ignore) { 315 return clazz.isAssignableFrom( dl.getRepresentationClass() ) ? dl : null; 316 } 317 } 318 319 return Enumerations.filter (allLoaders (), new ProducerOf ()); 321 } 322 323 324 327 private static final DataLoader.RecognizedFiles emptyDataLoaderRecognized = 328 new DataLoader.RecognizedFiles () { 329 333 public void markRecognized (FileObject fo) { 334 } 335 }; 336 337 352 public DataObject findDataObject (FileObject fo) throws IOException { 353 return findDataObject (fo, emptyDataLoaderRecognized); 354 } 355 356 375 public DataObject findDataObject ( 376 FileObject fo, DataLoader.RecognizedFiles r 377 ) throws IOException { 378 DataLoader pref = getPreferredLoader (fo); 380 if (pref != null) { 381 DataObject obj = pref.findDataObject (fo, r); 382 if (obj != null) { 383 return obj; 385 } 386 } 387 388 java.util.Enumeration en = allLoaders (); 390 while (en.hasMoreElements ()) { 391 DataLoader l = (DataLoader)en.nextElement (); 392 393 DataObject obj = l.findDataObject (fo, r); 394 if (obj != null) { 395 return obj; 396 } 397 } 398 return null; 399 } 400 401 409 public static void setPreferredLoader (FileObject fo, DataLoader loader) 410 throws IOException { 411 DataLoader prev = getPreferredLoader (fo); 412 413 if (prev == loader) { 414 return; 415 } 416 417 if (loader == null) { 418 fo.setAttribute(DataObject.EA_ASSIGNED_LOADER, null); 419 } else { 420 Class c = loader.getClass(); 421 Iterator modules = Lookup.getDefault().lookupAll(ModuleInfo.class).iterator(); 423 String modulename = null; 424 while (modules.hasNext()) { 425 ModuleInfo module = (ModuleInfo)modules.next(); 426 if (module.owns(c)) { 427 modulename = module.getCodeNameBase(); 428 break; 429 } 430 } 431 fo.setAttribute (DataObject.EA_ASSIGNED_LOADER, c.getName ()); 432 fo.setAttribute(DataObject.EA_ASSIGNED_LOADER_MODULE, modulename); 433 } 434 if (!DataObjectPool.getPOOL().revalidate(Collections.singleton(fo)).isEmpty()) { 435 DataObject.LOG.fine("It was not possible to invalidate data object: " + fo); } 437 } 438 439 443 public static DataLoader getPreferredLoader (FileObject fo) { 444 String assignedLoaderName = (String )fo.getAttribute (DataObject.EA_ASSIGNED_LOADER); 445 if (assignedLoaderName != null) { 446 String modulename = (String )fo.getAttribute(DataObject.EA_ASSIGNED_LOADER_MODULE); 448 if (modulename != null) { 449 Iterator modules = Lookup.getDefault().lookupAll(ModuleInfo.class).iterator(); 453 boolean ok = false; 454 while (modules.hasNext()) { 455 ModuleInfo module = (ModuleInfo)modules.next(); 456 if (module.getCodeNameBase().equals(modulename)) { 457 if (module.isEnabled()) { 458 ok = true; 460 break; 461 } else { 462 return null; 464 } 465 } 466 } 467 if (! ok) { 468 return null; 470 } 471 } try { 473 ClassLoader load = Lookup.getDefault().lookup(ClassLoader .class); 474 if (load == null) { 475 load = DataLoaderPool.class.getClassLoader (); 476 } 477 478 return DataLoader.getLoader(Class.forName(assignedLoaderName, true, load). 479 asSubclass(DataLoader.class)); 480 } catch (Exception ex) { 481 Logger.getLogger(DataLoaderPool.class.getName()).log(Level.WARNING, null, ex); 482 } 483 } 484 return null; 485 } 486 487 488 490 private static synchronized MultiFileLoader[] getSystemLoaders () { 491 if (systemLoaders == null) { 492 systemLoaders = new MultiFileLoader [] { 493 (MultiFileLoader) DataLoader.getLoader(ShadowLoader.class), 494 (MultiFileLoader) DataLoader.getLoader(InstanceLoaderSystem.class) 495 }; 496 } 497 return systemLoaders; 498 } 499 500 502 private static synchronized MultiFileLoader[] getDefaultLoaders () { 503 if (defaultLoaders == null) { 504 defaultLoaders = new MultiFileLoader [] { 505 (MultiFileLoader) DataLoader.getLoader(FolderLoader.class), 506 (MultiFileLoader) DataLoader.getLoader(XMLDataObject.Loader.class), 507 (MultiFileLoader) DataLoader.getLoader(InstanceLoader.class), 508 (MultiFileLoader) DataLoader.getLoader(DefaultLoader.class) 509 }; 510 } 511 return defaultLoaders; 512 } 513 514 517 static MultiFileLoader getDefaultFileLoader () { 518 return getDefaultLoaders ()[3]; 519 } 520 521 524 static MultiFileLoader getFolderLoader () { 525 return getDefaultLoaders ()[0]; 526 } 527 528 530 static MultiFileLoader getShadowLoader () { 531 return getSystemLoaders ()[0]; 532 } 533 534 538 private static final class DefaultPool extends DataLoaderPool implements LookupListener { 539 540 private final Lookup.Result<DataLoader> result; 541 542 public DefaultPool() { 543 result = Lookup.getDefault().lookupResult(DataLoader.class); 544 result.addLookupListener(this); 545 } 546 547 protected Enumeration<? extends DataLoader> loaders() { 548 return Collections.enumeration(result.allInstances()); 549 } 550 551 public void resultChanged(LookupEvent e) { 552 fireChangeEvent(new ChangeEvent(this)); 553 } 554 555 } 556 557 561 566 private static class InstanceLoaderSystem extends InstanceLoader { 567 private static final long serialVersionUID = -935749906623354837L; 568 569 570 public InstanceLoaderSystem() { 571 super (); 572 } 573 574 protected FileObject findPrimaryFile (FileObject fo) { 575 FileSystem fs = null; 576 try { 577 fs = fo.getFileSystem (); 578 } catch (FileStateInvalidException e) { 579 return null; 580 } 581 if (fs != Repository.getDefault ().getDefaultFileSystem ()) { 582 return null; 583 } 584 return super.findPrimaryFile (fo); 585 } 586 587 588 protected String [] getRequiredExt () { 589 return new String [] { 590 InstanceDataObject.INSTANCE, 591 InstanceDataObject.XML_EXT 592 }; 593 } 594 } 595 596 597 600 private static class InstanceLoader extends UniFileLoader { 601 static final long serialVersionUID =-3462727693843631328L; 602 603 604 605 public InstanceLoader () { 606 super ("org.openide.loaders.InstanceDataObject"); } 608 609 protected void initialize () { 610 super.initialize(); 611 setExtensions(null); 612 } 613 614 protected String actionsContext () { 615 return "Loaders/application/x-nbsettings/Actions"; } 617 618 621 protected String defaultDisplayName () { 622 return NbBundle.getMessage (DataLoaderPool.class, "LBL_instance_loader_display_name"); 623 } 624 625 633 protected MultiDataObject createMultiObject (FileObject primaryFile) 634 throws DataObjectExistsException, java.io.IOException { 635 InstanceDataObject obj = new InstanceDataObject(primaryFile, this); 636 return obj; 637 } 638 639 public void writeExternal (ObjectOutput oo) throws IOException { 640 oo.writeObject (this); 642 643 super.writeExternal (oo); 644 } 645 646 public void readExternal (ObjectInput oi) throws IOException, ClassNotFoundException { 647 Object o = oi.readObject (); 650 if (o instanceof SystemAction[]) { 651 setActions ((SystemAction[]) o); 653 setExtensions(getExtensions()); 654 } else if (o instanceof ExtensionList) { 655 ExtensionList list = (ExtensionList)o; 657 setExtensions(list); 658 } else { 659 super.readExternal (oi); 662 setExtensions(getExtensions()); 663 } 664 } 665 666 670 public void setExtensions(ExtensionList ext) { 671 super.setExtensions(initExtensions(ext)); 672 } 673 674 675 private ExtensionList initExtensions(ExtensionList ext) { 676 String rqext [] = getRequiredExt (); 677 if (ext == null) ext = new ExtensionList(); 678 for (int i = 0; i < rqext.length; i++) 679 ext.addExtension(rqext[i]); 680 return ext; 681 } 682 683 688 protected FileObject findPrimaryFile(FileObject fo) { 689 FileObject r = super.findPrimaryFile(fo); 690 if (r != null && r.getPath().equals("loaders.ser")) { try { 692 if (r.getFileSystem().isDefault()) { 693 return null; 695 } 696 } catch (FileStateInvalidException e) { 697 Logger.getLogger(DataLoaderPool.class.getName()).log(Level.WARNING, null, e); 698 } 699 } 700 return r; 701 } 702 703 704 protected String [] getRequiredExt () { 705 return new String [] { 706 InstanceDataObject.INSTANCE, 707 InstanceDataObject.SER_EXT, 708 InstanceDataObject.XML_EXT 709 }; 710 } 711 } 713 714 715 716 717 718 private static final class DefaultLoader extends MultiFileLoader { 719 static final long serialVersionUID =-6761887227412396555L; 720 721 722 public DefaultLoader () { 723 super ("org.openide.loaders.DefaultDataObject"); } 726 727 protected String actionsContext () { 728 return "Loaders/content/unknown/Actions"; } 730 731 734 protected String defaultDisplayName () { 735 return NbBundle.getMessage (DataLoaderPool.class, "LBL_default_loader_display_name"); 736 } 737 738 743 protected FileObject findPrimaryFile (FileObject fo) { 744 if (fo.isFolder()) return null; 746 return fo; 747 } 748 749 757 protected MultiDataObject createMultiObject (FileObject primaryFile) 758 throws DataObjectExistsException, java.io.IOException { 759 return new DefaultDataObject(primaryFile, this); 760 } 761 762 768 protected MultiDataObject.Entry createPrimaryEntry (MultiDataObject obj, FileObject primaryFile) { 769 return new FileEntry (obj, primaryFile); 770 } 771 772 779 protected MultiDataObject.Entry createSecondaryEntry (MultiDataObject obj, FileObject secondaryFile) { 780 throw new UnsupportedOperationException (); 781 } 782 783 789 void checkFiles (MultiDataObject obj) { 790 } 791 } 793 794 795 private static final class ShadowLoader extends UniFileLoader { 796 static final long serialVersionUID =-11013405787959120L; 797 798 801 private static ShadowChangeAdapter changeAdapter = new ShadowChangeAdapter(); 802 803 804 public ShadowLoader () { 805 super ("org.openide.loaders.DataShadow"); } 808 809 812 protected String defaultDisplayName () { 813 return NbBundle.getMessage (DataLoaderPool.class, "LBL_shadow_loader_display_name"); 814 } 815 816 822 protected FileObject findPrimaryFile(FileObject fo) { 823 if (fo.hasExt (DataShadow.SHADOW_EXTENSION)) { 824 return fo; 825 } 826 return null; 827 } 828 829 835 protected MultiDataObject.Entry createPrimaryEntry(MultiDataObject obj, FileObject primaryFile) { 836 return new FileEntry(obj, primaryFile); 837 } 838 839 847 protected MultiDataObject createMultiObject(FileObject primaryFile) throws DataObjectExistsException, IOException { 848 try { 849 DataObject d = DataShadow.deserialize (primaryFile); 850 if (d != null) return new DataShadow (primaryFile, d, this); 851 } catch (IOException ex) { 852 } 854 855 return new BrokenDataShadow (primaryFile, this); 856 } 857 public void writeExternal(ObjectOutput oo) throws IOException { 858 } 859 public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException { 860 } 861 } 863 865 static final class FolderLoader extends UniFileLoader { 866 static final long serialVersionUID =-8325525104047820255L; 867 868 869 public FolderLoader () { 870 super ("org.openide.loaders.DataFolder"); } 873 874 protected String actionsContext () { 875 return "Loaders/folder/any/Actions"; } 877 878 881 protected String defaultDisplayName () { 882 return NbBundle.getMessage (DataLoaderPool.class, "LBL_folder_loader_display_name"); 883 } 884 885 protected FileObject findPrimaryFile(FileObject fo) { 886 if (fo.isFolder()) { 887 return fo; 888 } 889 return null; 890 } 891 892 protected MultiDataObject.Entry createPrimaryEntry(MultiDataObject obj, FileObject primaryFile) { 893 return new FileEntry.Folder(obj, primaryFile); 894 } 895 896 protected MultiDataObject createMultiObject(FileObject primaryFile) throws DataObjectExistsException, IOException { 897 return new DataFolder(primaryFile, this); 898 } 899 900 909 MultiDataObject createMultiObject(FileObject primaryFile, final DataFolder original) throws DataObjectExistsException, IOException { 910 class NodeSharingDataFolder extends DataFolder { 911 public NodeSharingDataFolder(FileObject fo) throws DataObjectExistsException, IllegalArgumentException { 912 super(fo, FolderLoader.this); 913 } 914 protected Node createNodeDelegate() { 915 return new FilterNode(original.getNodeDelegate()); 916 } 917 Node getClonedNodeDelegate (DataFilter filter) { 918 return new FilterNode(original.getClonedNodeDelegate(filter)); 919 } 920 } 921 return new NodeSharingDataFolder(primaryFile); 922 } 923 924 public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException { 925 try { 926 super.readExternal(oi); 927 } catch (OptionalDataException ode) { 928 } 930 } 931 932 } 934 } 935 | Popular Tags |