KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > loaders > DataLoaderPool


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.openide.loaders;
21
22 import java.io.*;
23 import java.util.*;
24 import java.util.logging.Level JavaDoc;
25 import java.util.logging.Logger JavaDoc;
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 /** Pool of data loaders.
34  * Provides access to set of registered
35  * {@link DataLoader loaders} in the system. They are used to find valid data objects
36  * for given files.
37  * <P>
38  * The default instance can be retrieved using lookup.
39  *
40  * @author Jaroslav Tulach, Petr Hamernik, Dafe Simonek
41  */

42 public abstract class DataLoaderPool extends Object JavaDoc
43 implements java.io.Serializable JavaDoc {
44
45     /** SUID */
46     static final long serialVersionUID=-360141823874889956L;
47     /** standard system loaders. Accessed by getSystemLoaders method only */
48     private static MultiFileLoader[] systemLoaders;
49     /** standard default loaders. Accessed by getDefaultLoaders method only */
50     private static MultiFileLoader[] defaultLoaders;
51     
52     private static DataLoaderPool DEFAULT;
53     
54     /** Getter for the default pool of loaders used in the system.
55      * By default it looks it up using Lookup, if not found it provides
56      * default one that does lookup individual loaders using Lookup.
57      *
58      * @return instance of system DataLoaderPool
59      * @since 5.1
60      */

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     /** Cache of loaders for faster toArray() method. */
72     private transient DataLoader[] loaderArray;
73     /** cache of loaders for allLoaders method */
74     private transient List<DataLoader> allLoaders;
75     /** counts number of changes in the loaders pool */
76     private transient int cntchanges;
77     
78     private transient EventListenerList listeners;
79     
80     /** prefered loader */
81     private transient DataLoader preferredLoader;
82     
83     /** Create new loader pool.
84      */

85     protected DataLoaderPool () {
86     }
87     
88     /** Create new loader pool and set preferred loader.
89      * The preferred loader will be asked before any other to recognize files (also before the system
90      * loader).
91      *
92      * @param loader the preferred loader
93      */

94     protected DataLoaderPool (DataLoader loader) {
95         preferredLoader = loader;
96     }
97     
98     /** Get an enumeration of data loaders.
99      * Must be overridden in subclasses to provide a list of additional loaders.
100      * The list should <em>not</em> include the preferred loader.
101      *
102      * @return enumeration of loaders
103      */

104     protected abstract Enumeration<? extends DataLoader> loaders ();
105     
106     /** Add a new listener to the listener list. A listener is notified of
107      * any change which was made to the loader pool (add, remove, or reorder).
108      *
109      * @param chl new listener
110      */

111     public final synchronized void addChangeListener (ChangeListener chl) {
112         if (listeners == null) listeners = new EventListenerList();
113         listeners.add( ChangeListener.class, chl);
114     }
115     
116     /** Remove a listener from the listener list.
117      *
118      * @param chl listener to remove
119      */

120     public final synchronized void removeChangeListener (ChangeListener chl) {
121         if (listeners != null) {
122             listeners.remove( ChangeListener.class, chl);
123         }
124     }
125     
126     /** Fire change event to all listeners. Asynchronously.
127      * @param che change event
128      */

129     protected final void fireChangeEvent (final ChangeEvent che) {
130         
131         Object JavaDoc[] 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         // could fire on given array, modifications will copy it out before
142
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     /** Factory to create weak OperationListener
152      *
153      * @param l listener
154      * @param s the source the new listener will be attached to
155      */

156     public static OperationListener createWeakOperationListener (OperationListener l, Object JavaDoc s) {
157         return WeakListeners.create(OperationListener.class, l, s);
158     }
159     
160     /** Add a listener for operations on data objects.
161      * @param l the listener
162      */

163     public synchronized final void addOperationListener (OperationListener l) {
164         if (listeners == null) listeners = new EventListenerList();
165         listeners.add( OperationListener.class, l);
166     }
167     
168     /** Remove a listener for operations on data objects.
169      * @param l the listener
170      */

171     public synchronized final void removeOperationListener (OperationListener l) {
172         if (listeners != null) {
173             listeners.remove( OperationListener.class, l);
174         }
175     }
176     
177     /** Fires operation event to all listeners.
178      * Clears loaderArray before firing a change.
179      * @param ev event to fire
180      * @param type the type of the event
181      */

182     final void fireOperationEvent (OperationEvent ev, int type) {
183         Object JavaDoc[] list;
184         synchronized( this ) {
185             if (listeners == null) return;
186             list = listeners.getListenerList();
187         }
188
189         // could fire on given array, modifications will copy it out before
190
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     /** Get an enumeration of all loaders, including the preferred and system loaders.
221      * This should be the list of loaders as actually used by the system.
222      * Typically it will consist of, in this order:
223      * <ol>
224      * <li>The preferred loader, if any.
225      * <li>The system loaders, such as may be used for folders, shadows, etc.
226      * <li>Module-specified loaders.
227      * <li>The loader for instance data objects.
228      * <li>Default loaders, which may handle files not otherwise recognizable.
229      * </ol>
230      * Applications should not rely on the exact contents of the pool,
231      * rather the fact that this contains all the loaders which are
232      * capable of recognizing files in the order in which they are
233      * called.
234      * @return enumeration of loaders
235      */

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     /** Get an array of loaders that are currently registered.
267      * Does not include special system loaders, etc.
268      * @return array of loaders
269      * @see #loaders
270      */

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     /** Finds the first producer of a representation class.
287      * Scans through the list of all loaders and returns the first one
288      * whose representation class is a superclass of <code>clazz</code>.
289      *
290      * @param clazz class to find producer for
291      * @return data loader or <CODE>null</CODE> if there is no loader that
292      * can produce the class
293      */

294     public final DataLoader firstProducerOf(Class JavaDoc<? extends DataObject> clazz) {
295         Enumeration<DataLoader> en = allLoaders ();
296         while (en.hasMoreElements ()) {
297             DataLoader dl = en.nextElement();
298             if (dl.getRepresentationClass ().isAssignableFrom (clazz)) {
299                 // representation class is super class of clazz
300
return dl;
301             }
302         }
303         return null;
304     }
305     
306     /** Get an enumeration of all producers of a representation class.
307      * @see #firstProducerOf
308      *
309      * @param clazz class to find producers for
310      * @return enumeration of loaders
311      */

312     public final Enumeration<DataLoader> producersOf(final Class JavaDoc<? extends DataObject> clazz) {
313         class ProducerOf implements Enumerations.Processor<DataLoader,DataLoader> {
314             public DataLoader process(DataLoader dl, java.util.Collection JavaDoc ignore) {
315                 return clazz.isAssignableFrom( dl.getRepresentationClass() ) ? dl : null;
316             }
317         }
318         
319         // Accepts only those loaders that produces superclass of clazz
320
return Enumerations.filter (allLoaders (), new ProducerOf ());
321     }
322     
323     
324     /** private class for next method. Empty implementation of
325      * DataLoaderRecognized.
326      */

327     private static final DataLoader.RecognizedFiles emptyDataLoaderRecognized =
328     new DataLoader.RecognizedFiles () {
329             /** No op. replacement.
330              *
331              * @param fo file object to exclude
332              */

333         public void markRecognized (FileObject fo) {
334         }
335     };
336     
337     /** Find a data object for this file object (not for normal users of the APIs).
338      * <strong>DO NOT USE THIS</strong> as a normal user of the APIs!
339      * Unless you really know what you are doing, use {@link DataObject#find} instead.
340      * This call will throw an exception if it already exists, and it is normally
341      * only for use by the loader infrastructure.
342      * <p>All loaders are asked to recognize it according to their priority.
343      * @param fo file object to recognize
344      * @return the data object for this object or <CODE>null</CODE> if
345      * no loader recognizes this file
346      * @exception DataObjectExistsException if the object for this primary file
347      * already exists
348      * @exception IOException if the data object is recognized but
349      * an error occurs during instantiation
350      * @see #findDataObject(FileObject, DataLoader.RecognizedFiles)
351      */

352     public DataObject findDataObject (FileObject fo) throws IOException {
353         return findDataObject (fo, emptyDataLoaderRecognized);
354     }
355     
356     /** Find a data object for this file object, considering already-recognized files (not for normal users of the APIs).
357      * <strong>DO NOT USE THIS</strong> as a normal user of the APIs!
358      * Unless you really know what you are doing, use {@link DataObject#find} instead.
359      * This call will throw an exception if it already exists, and it is normally
360      * only for use by the loader infrastructure.
361      * <p>First of all looks at the
362      * file extended attribute <code>NetBeansDataLoader</code>; if it is set and it
363      * contains the class name of a valid {@link DataLoader}, that loader is given preference.
364      * For all loaders used, the first to return non-<code>null</code> from {@link DataLoader#findDataObject}
365      * is used.
366      *
367      * @param fo file object to recognize
368      * @param r recognized files buffer
369      * @return the data object for this object
370      * @exception DataObjectExistsException if the object for this primary file
371      * already exists
372      * @exception IOException if the data object is recognized but
373      * an error occurs during instantiation
374      */

375     public DataObject findDataObject (
376     FileObject fo, DataLoader.RecognizedFiles r
377     ) throws IOException {
378         // try to find assigned loader
379
DataLoader pref = getPreferredLoader (fo);
380         if (pref != null) {
381             DataObject obj = pref.findDataObject (fo, r);
382             if (obj != null) {
383                 // file has been recognized
384
return obj;
385             }
386         }
387         
388         // scan through loaders
389
java.util.Enumeration JavaDoc 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     /** Utility method to mark a file as belonging to a loader.
402      * When the file is to be recognized this loader will be used first.
403      *
404      * @param fo file to mark
405      * @param loader the loader to assign to the file or null if previous
406      * association should be cleared
407      * @exception IOException if setting the file's attribute failed
408      */

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 JavaDoc c = loader.getClass();
421             // [PENDING] in the future a more efficient API may be introduced
422
Iterator modules = Lookup.getDefault().lookupAll(ModuleInfo.class).iterator();
423             String JavaDoc 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); // NOI18N
436
}
437     }
438     
439     /** Get the preferred loader for a file.
440      * @param fo the file to get loader from
441      * @return the loader or null if there is no particular preferred loader
442      */

443     public static DataLoader getPreferredLoader (FileObject fo) {
444         String JavaDoc assignedLoaderName = (String JavaDoc)fo.getAttribute (DataObject.EA_ASSIGNED_LOADER);
445         if (assignedLoaderName != null) {
446             // First check to see if it comes from an uninstalled module.
447
String JavaDoc modulename = (String JavaDoc)fo.getAttribute(DataObject.EA_ASSIGNED_LOADER_MODULE);
448             if (modulename != null) {
449                 // [PENDING] in the future a more efficient API may be introduced
450
// (actually currently you can look up with a template giving the name
451
// as part of the lookup item ID but this is not an official API)
452
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                             // Carry on.
459
ok = true;
460                             break;
461                         } else {
462                             // Uninstalled module.
463
return null;
464                         }
465                     }
466                 }
467                 if (! ok) {
468                     // Unknown module.
469
return null;
470                 }
471             } // else don't worry about it (compatibility)
472
try {
473                 ClassLoader JavaDoc load = Lookup.getDefault().lookup(ClassLoader JavaDoc.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 JavaDoc ex) {
481                 Logger.getLogger(DataLoaderPool.class.getName()).log(Level.WARNING, null, ex);
482             }
483         }
484         return null;
485     }
486     
487     
488     /** Lazy getter for system loaders.
489      */

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     /** Lazy getter for default loaders.
501      */

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     /** Getter for default file loader
515      * @return the default file loader
516      */

517     static MultiFileLoader getDefaultFileLoader () {
518         return getDefaultLoaders ()[3];
519     }
520     
521     /** Getter for folder loader
522      * @return the folder loader
523      */

524     static MultiFileLoader getFolderLoader () {
525         return getDefaultLoaders ()[0];
526     }
527     
528     /** Getter for shadow loader.
529      */

530     static MultiFileLoader getShadowLoader () {
531         return getSystemLoaders ()[0];
532     }
533
534     /**
535      * Special pool for unit testing etc.
536      * Finds all relevant data loaders in default lookup.
537      */

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     //
558
// Default loaders
559
//
560

561     /* Instance loader recognizing .settings files. It's placed at the beginning
562      * of loader pool, .settings files must alwaus be recognized by this loader
563      * otherwise IDE settings will not work at all. No module is permitted to use
564      * .settings files.
565      */

566     private static class InstanceLoaderSystem extends InstanceLoader {
567         private static final long serialVersionUID = -935749906623354837L;
568         
569         /* Creates new InstanceLoader */
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         /** @return list of all required extensions for this loader */
588         protected String JavaDoc [] getRequiredExt () {
589             return new String JavaDoc[] {
590                 InstanceDataObject.INSTANCE,
591                 InstanceDataObject.XML_EXT
592             };
593         }
594     }
595
596
597 /* Instance loader recognizing .ser and .instance files. It's placed at
598  * the end of loader pool among default loaders.
599  */

600 private static class InstanceLoader extends UniFileLoader {
601     static final long serialVersionUID =-3462727693843631328L;
602
603
604     /* Creates new InstanceLoader */
605     public InstanceLoader () {
606         super ("org.openide.loaders.InstanceDataObject"); // NOI18N
607
}
608
609     protected void initialize () {
610         super.initialize();
611         setExtensions(null);
612     }
613
614     protected String JavaDoc actionsContext () {
615         return "Loaders/application/x-nbsettings/Actions"; // NOI18N
616
}
617     
618     /** Get the default display name of this loader.
619     * @return default display name
620     */

621     protected String JavaDoc defaultDisplayName () {
622         return NbBundle.getMessage (DataLoaderPool.class, "LBL_instance_loader_display_name");
623     }
624
625     /* Creates the right data object for given primary file.
626      * It is guaranteed that the provided file is realy primary file
627      * returned from the method findPrimaryFile.
628      *
629      * @param primaryFile the primary file
630      * @return the data object for this file
631      * @exception DataObjectExistsException if the primary file already has data object
632      */

633     protected MultiDataObject createMultiObject (FileObject primaryFile)
634     throws DataObjectExistsException, java.io.IOException JavaDoc {
635         InstanceDataObject obj = new InstanceDataObject(primaryFile, this);
636         return obj;
637     }
638
639     public void writeExternal (ObjectOutput oo) throws IOException {
640         // does not use super serialization of extensions
641
oo.writeObject (this);
642
643         super.writeExternal (oo);
644     }
645
646     public void readExternal (ObjectInput oi) throws IOException, ClassNotFoundException JavaDoc {
647         // the result of following code is either ExtensionList (original version)
648
// or this (current version).
649
Object JavaDoc o = oi.readObject ();
650         if (o instanceof SystemAction[]) {
651             //added for compatibility with FFJ2.0
652
setActions ((SystemAction[]) o);
653             setExtensions(getExtensions());
654         } else if (o instanceof ExtensionList) {
655             // old serialization, add new extension
656
ExtensionList list = (ExtensionList)o;
657             setExtensions(list);
658         } else {
659             // newer serialization, everything should be ok, just read
660
// the original value
661
super.readExternal (oi);
662             setExtensions(getExtensions());
663         }
664     }
665
666     /** Set the extension list for this data loader.
667     * Checks if all required extensions are in new list of extensions.
668     * @param ext new list of extensions
669     */

670     public void setExtensions(ExtensionList ext) {
671         super.setExtensions(initExtensions(ext));
672     }
673
674     /** fill in instance file's extension list; if ext == null new list is created */
675     private ExtensionList initExtensions(ExtensionList ext) {
676         String JavaDoc 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     /**
684      * Just avoids loaders.ser, which is not a well-formed ser file and causes confusing
685      * exceptions when browsing system file system.
686      * Anyway reading the contents would mutate loader singletons! Evil.
687      */

688     protected FileObject findPrimaryFile(FileObject fo) {
689         FileObject r = super.findPrimaryFile(fo);
690         if (r != null && r.getPath().equals("loaders.ser")) { // NOI18N
691
try {
692                 if (r.getFileSystem().isDefault()) {
693                     // Skip it.
694
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     /** @return list of all required extensions for this loader */
704     protected String JavaDoc [] getRequiredExt () {
705         return new String JavaDoc[] {
706             InstanceDataObject.INSTANCE,
707             InstanceDataObject.SER_EXT,
708             InstanceDataObject.XML_EXT
709         };
710     }
711 } // end of InstanceLoader
712

713
714
715     
716
717 /** Loader for file objects not recognized by any other loader */
718 private static final class DefaultLoader extends MultiFileLoader {
719     static final long serialVersionUID =-6761887227412396555L;
720
721     /* Representation class is DefaultDataObject */
722     public DefaultLoader () {
723         super ("org.openide.loaders.DefaultDataObject"); // NOI18N
724
//super (DefaultDataObject.class);
725
}
726
727     protected String JavaDoc actionsContext () {
728         return "Loaders/content/unknown/Actions"; // NOI18N
729
}
730     
731     /** Get the default display name of this loader.
732     * @return default display name
733     */

734     protected String JavaDoc defaultDisplayName () {
735         return NbBundle.getMessage (DataLoaderPool.class, "LBL_default_loader_display_name");
736     }
737
738     /** Get the primary file.
739      * @param fo the file to find the primary file for
740      *
741      * @return the primary file
742      */

743     protected FileObject findPrimaryFile (FileObject fo) {
744         // never recognize folders
745
if (fo.isFolder()) return null;
746         return fo;
747     }
748
749     /* Creates the right data object for given primary file.
750      * It is guaranteed that the provided file is realy primary file
751      * returned from the method findPrimaryFile.
752      *
753      * @param primaryFile the primary file
754      * @return the data object for this file
755      * @exception DataObjectExistsException if the primary file already has data object
756      */

757     protected MultiDataObject createMultiObject (FileObject primaryFile)
758     throws DataObjectExistsException, java.io.IOException JavaDoc {
759         return new DefaultDataObject(primaryFile, this);
760     }
761
762     /* Creates the right primary entry for given primary file.
763      *
764      * @param obj requesting object
765      * @param primaryFile primary file recognized by this loader
766      * @return primary entry for that file
767      */

768     protected MultiDataObject.Entry createPrimaryEntry (MultiDataObject obj, FileObject primaryFile) {
769         return new FileEntry (obj, primaryFile);
770     }
771
772     /** Do not create a seconday entry.
773      *
774      * @param obj ignored
775      * @param secondaryFile ignored
776      * @return never returns
777      * @exception UnsupportedOperationException because this loader supports only a primary file object
778      */

779     protected MultiDataObject.Entry createSecondaryEntry (MultiDataObject obj, FileObject secondaryFile) {
780         throw new UnsupportedOperationException JavaDoc ();
781     }
782
783     /** Does nothing because this loader works only with objects
784      * with one file => primary file so it is not necessary to search
785      * for anything else.
786      *
787      * @param obj the object to test
788      */

789     void checkFiles (MultiDataObject obj) {
790     }
791 } // end of DefaultLoader
792

793
794 /** Loader for shadows, since 1.13 changed to UniFileLoader. */
795 private static final class ShadowLoader extends UniFileLoader {
796     static final long serialVersionUID =-11013405787959120L;
797
798     /* DO NOT REMOVE THIS, the ShadowChangeAdapter must be constructed, it listens
799      * on filesystems changes and converts DataShadows to BrokenDataShadows and vice versa.
800      */

801     private static ShadowChangeAdapter changeAdapter = new ShadowChangeAdapter();
802
803     /* Representation class is DataShadow */
804     public ShadowLoader () {
805         super ("org.openide.loaders.DataShadow"); // NOI18N
806
//super (DataShadow.class);
807
}
808
809     /** Get the default display name of this loader.
810     * @return default display name
811     */

812     protected String JavaDoc defaultDisplayName () {
813         return NbBundle.getMessage (DataLoaderPool.class, "LBL_shadow_loader_display_name");
814     }
815
816     /** For a given file finds the primary file.
817      * @param fo the (secondary) file
818      *
819      * @return the primary file for the file or <code>null</code> if the file is not
820      * recognized by this loader
821      */

822     protected FileObject findPrimaryFile(FileObject fo) {
823         if (fo.hasExt (DataShadow.SHADOW_EXTENSION)) {
824             return fo;
825         }
826         return null;
827     }
828
829     /** Creates the right primary entry for a given primary file.
830      *
831      * @param obj requesting object
832      * @param primaryFile primary file recognized by this loader
833      * @return primary entry for that file
834      */

835     protected MultiDataObject.Entry createPrimaryEntry(MultiDataObject obj, FileObject primaryFile) {
836         return new FileEntry(obj, primaryFile);
837     }
838
839     /** Creates the right data object for a given primary file.
840      * It is guaranteed that the provided file will actually be the primary file
841      * returned by {@link #findPrimaryFile}.
842      *
843      * @param primaryFile the primary file
844      * @return the data object for this file
845      * @exception DataObjectExistsException if the primary file already has a data object
846      */

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             // broken link or damaged shadow file
853
}
854         /* Link is broken, create BrokenDataShadow */
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 JavaDoc {
860     }
861 } // end of ShadowLoader
862

863 /** Loader for folders.
864  */

865 static final class FolderLoader extends UniFileLoader {
866     static final long serialVersionUID =-8325525104047820255L;
867
868     /* Representation class is DataFolder */
869     public FolderLoader () {
870         super ("org.openide.loaders.DataFolder"); // NOI18N
871
// super (DataFolder.class);
872
}
873
874     protected String JavaDoc actionsContext () {
875         return "Loaders/folder/any/Actions"; // NOI18N
876
}
877     
878     /** Get the default display name of this loader.
879     * @return default display name
880     */

881     protected String JavaDoc 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     /** This method is used only in DataFolder.handleMove method.
901      * For more comments see {@link org.openide.loaders.DataFolder#handleMove}.
902      *
903      * @param primaryFile the primary file of the data folder to be created
904      * @param original The original DataFolder. The returned MultiDataObject
905      * delegates createNodeDelegate and getClonedNodeDelegate methods calls
906      * to the original DataFolder.
907      * @return The DataFolder that shares the nodes with the original DataFolder.
908      */

909     MultiDataObject createMultiObject(FileObject primaryFile, final DataFolder original) throws DataObjectExistsException, IOException {
910         class NodeSharingDataFolder extends DataFolder {
911             public NodeSharingDataFolder(FileObject fo) throws DataObjectExistsException, IllegalArgumentException JavaDoc {
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 JavaDoc {
925         try {
926             super.readExternal(oi);
927         } catch (OptionalDataException ode) {
928             // older ser of FolderLoader which did not store actions - ignore
929
}
930     }
931
932 } // end of FolderLoader
933

934 }
935
Popular Tags