KickJava   Java API By Example, From Geeks To Geeks.

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


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.IOException JavaDoc;
23 import java.util.*;
24 import java.util.logging.Level JavaDoc;
25
26 import org.openide.*;
27 import org.openide.filesystems.*;
28
29 /** Loader for any kind of <code>MultiDataObject</code>. It provides
30 * support for recognition of a composite data object and registering
31 * entries into it.
32 *
33 * @author Jaroslav Tulach
34 */

35 public abstract class MultiFileLoader extends DataLoader {
36     static final long serialVersionUID=1521919955690157343L;
37
38
39     /** Creates new multi file loader.
40      * @param representationClass the representation class
41      * @deprecated Use MultiFileLoader#MultiFileLoader(String) instead.
42     */

43     @Deprecated JavaDoc
44     protected MultiFileLoader(Class JavaDoc<? extends DataObject> representationClass) {
45         super(representationClass);
46     }
47
48     /** Creates new multi file loader.
49     * @param representationClassName the fully qualified name of the
50     * representation class.
51     *
52     * @since 1.10
53     */

54     protected MultiFileLoader (String JavaDoc representationClassName) {
55         super (representationClassName);
56     }
57
58     /* Provides standard implementation for recognizing files in the
59     * loader. First of all the findEntry method is called to allow the
60     * subclass to find right entry for the
61     *
62     * @param fo file object to recognize
63     * @param recognized recognized files buffer.
64     * @exception DataObjectExistsException if the data object for specific
65     * primary file already exists (thrown by constructor of DataObject)
66     * @exception IOException if the object is recognized but cannot be created
67     *
68     * @return suitable data object or <CODE>null</CODE> if the handler cannot
69     * recognize this object (or its group)
70     */

71     protected final DataObject handleFindDataObject (
72         FileObject fo, RecognizedFiles recognized ) throws IOException JavaDoc {
73         // finds primary file for given file
74
FileObject primary = findPrimaryFileImpl (fo);
75
76         // if this loader does not recognizes this file => return
77
if (primary == null) return null;
78
79
80         boolean willLog = ERR.isLoggable(Level.FINE);
81         
82         if (willLog) {
83             ERR.fine(getClass().getName() + " is accepting: " + fo); // NOI18N
84
}
85
86         if (primary != fo) {
87             if (willLog) {
88                 ERR.fine("checking correctness: primary is different than provided file: " + primary + " fo: " + fo); // NOI18N
89
}
90             Enumeration en = DataLoaderPool.getDefault().allLoaders();
91             for (;;) {
92                 DataLoader l = (DataLoader)en.nextElement();
93                 if (l == this) {
94                     ERR.fine("ok, consistent"); // NOI18N
95
break;
96                 }
97                 if (l instanceof MultiFileLoader) {
98                     MultiFileLoader ml = (MultiFileLoader)l;
99                     if (ml.findPrimaryFile(primary) == primary) {
100                         if (willLog) {
101                             ERR.fine("loader seems to also take care of the file: " + ml);
102                         }
103                         DataObject snd;
104                         try {
105                             snd = ml.findDataObject(primary, recognized);
106                         } catch (DataObjectExistsException ex) {
107                             snd = ex.getDataObject();
108                         }
109                         if (snd != null) {
110                             return null;
111                         }
112                     }
113                 }
114             }
115         }
116
117         MultiDataObject obj;
118         try {
119             // create the multi object
120
obj = createMultiObject (primary);
121             if (willLog) {
122                 ERR.fine(getClass().getName() + " created object for: " + fo + " obj: " + obj); // NOI18N
123
}
124         } catch (DataObjectExistsException ex) {
125             // object already exists
126
DataObject dataObject = ex.getDataObject ();
127             if (willLog) {
128                 ERR.fine(getClass().getName() + " object already exists for: " + fo + " obj: " + dataObject); // NOI18N
129
}
130             
131             if (dataObject.getLoader () != this) {
132                 if (willLog) {
133                     ERR.fine(getClass().getName() + " loader is wrong: " + dataObject.getLoader().getClass().getName()); // NOI18N
134
}
135
136                 if (dataObject.getLoader() instanceof MultiFileLoader) {
137                     MultiFileLoader mfl = (MultiFileLoader)dataObject.getLoader();
138                     FileObject loaderPrimary = mfl.findPrimaryFileImpl(fo);
139                     ERR.log(Level.FINE, "Its primary file is {0}", loaderPrimary); // NOI18N
140
if (loaderPrimary != null && dataObject.getPrimaryFile() != loaderPrimary) {
141                         ERR.log(Level.FINE, "Which is different than primary of found: {0}", dataObject); // NOI18N
142

143                         Enumeration before = DataLoaderPool.getDefault().allLoaders();
144                         while (before.hasMoreElements()) {
145                             Object JavaDoc o = before.nextElement();
146                             if (o == mfl) {
147                                 ERR.log(Level.FINE, "Returning null"); // NOI18N
148
return null;
149                             }
150                             if (o == this) {
151                                 ERR.log(Level.FINE, "The loader" + mfl + " is after " + this + ". So do break."); // NOI18N
152
break;
153                             }
154                         }
155                     }
156                 }
157
158                 // try to update the data object by allowing other
159
// loaders to take care of the object
160
dataObject = checkCollision (dataObject, fo);
161             }
162             
163             if (!(dataObject instanceof MultiDataObject)) {
164                 // but if it is not MultiDataObject, propadate the exception
165
if (willLog) {
166                     ERR.fine(getClass().getName() + " object is not MultiDataObject: " + dataObject); // NOI18N
167
}
168                 throw ex;
169             }
170             obj = (MultiDataObject)dataObject;
171         } catch (IOException JavaDoc ex) {
172             ERR.log(Level.FINE, null, ex);
173             throw ex;
174         }
175
176         if (obj.getLoader () != this) {
177             if (willLog) {
178                 ERR.fine(getClass().getName() + " wrong loader: " + obj.getLoader().getClass().getName()); // NOI18N
179
}
180             // this primary file is recognized by a different
181
// loader. We should not add entries to it
182
return obj;
183         }
184
185         // mark all secondary entries used
186
if (willLog) {
187             ERR.fine(getClass().getName() + " marking secondary entries"); // NOI18N
188
}
189         obj.markSecondaryEntriesRecognized (recognized);
190
191         // if the file is not between
192
if (willLog) {
193             ERR.fine(getClass().getName() + " register entry: " + fo); // NOI18N
194
}
195         org.openide.loaders.MultiDataObject.Entry e = obj.registerEntry (fo);
196         if (willLog) {
197             ERR.fine(getClass().getName() + " success: " + e); // NOI18N
198
}
199
200         return obj;
201     }
202
203
204     /** For a given file finds the primary file.
205     * @param fo the (secondary) file
206     *
207     * @return the primary file for the file or <code>null</code> if the file is not
208     * recognized by this loader
209     */

210     protected abstract FileObject findPrimaryFile (FileObject fo);
211
212     /** Creates the right data object for a given primary file.
213     * It is guaranteed that the provided file will actually be the primary file
214     * returned by {@link #findPrimaryFile}.
215     *
216     * @param primaryFile the primary file
217     * @return the data object for this file
218     * @exception DataObjectExistsException if the primary file already has a data object
219     */

220     protected abstract MultiDataObject createMultiObject (FileObject primaryFile)
221     throws DataObjectExistsException, IOException JavaDoc;
222
223     /** Creates the right primary entry for a given primary file.
224     *
225     * @param obj requesting object
226     * @param primaryFile primary file recognized by this loader
227     * @return primary entry for that file
228     */

229     protected abstract MultiDataObject.Entry createPrimaryEntry (MultiDataObject obj, FileObject primaryFile);
230
231     /** Creates a new secondary entry for a given file.
232     * Note that separate entries must be created for every secondary
233     * file within a given multi-file data object.
234     *
235     * @param obj requesting object
236     * @param secondaryFile a secondary file
237     * @return the entry
238     */

239     protected abstract MultiDataObject.Entry createSecondaryEntry (MultiDataObject obj, FileObject secondaryFile);
240
241     /** Called when there is a collision between a data object that
242     * this loader tries to create and already existing one.
243     *
244     * @param obj existing data object
245     * @param file the original file that has been recognized by this loader
246     * as bellonging to obj data object
247     * @return the data object created for this or null
248     */

249     DataObject checkCollision (DataObject obj, FileObject file) {
250         /* JST: Make protected when necessary. Do not forget to
251         * change UniFileDataLoader too.
252         */

253         FileObject primary = obj.getPrimaryFile ();
254         
255         /*Set refusing = */DataObjectPool.getPOOL().revalidate (
256             new HashSet<FileObject> (Collections.singleton(primary))
257         );
258             // ok, the obj is discarded
259
DataObject result = DataObjectPool.getPOOL().find (primary);
260         return result;
261     }
262     
263     /** Called when an entry of the data object is deleted.
264     *
265     * @param obj the object to check
266     */

267     void checkConsistency (MultiDataObject obj) {
268         /* JST: Make protected when necessary. Do not forget to
269         * change UniFileDataLoader too.
270         */

271         FileObject primary = obj.getPrimaryFile ();
272         if (primary.equals (findPrimaryFileImpl (primary))) {
273             // ok recognized
274
return;
275         }
276         
277         // something is wrong the loader does not recognize the data
278
// object anymore
279
try {
280             obj.setValid (false);
281         } catch (java.beans.PropertyVetoException JavaDoc ex) {
282             // ignore
283
}
284     }
285     
286     
287     
288     /** Called before list of files belonging to a data object
289     * is returned from MultiDataObject.files () method. This allows
290     * each loader to perform additional tests and update the set of
291     * entries for given data object.
292     * <P>
293     * Current implementation scans all files in directory.
294     *
295     * @param obj the object to test
296     */

297     void checkFiles (MultiDataObject obj) {
298         /* JST: Make protected (and rename) when necessary. Do not forget to
299         * change UniFileDataLoader too.
300         */

301
302
303         FileObject primary = obj.getPrimaryFile ();
304         assert primary != null : "Object " + obj + " cannot have null primary file"; // NOI18N
305
FileObject parent = primary.getParent ();
306         assert parent != null : "Object " + obj + " cannot have null parent file"; // NOI18N
307

308         FileObject[] arr = parent.getChildren ();
309         for (int i = 0; i < arr.length; i++) {
310             FileObject pf = findPrimaryFileImpl (arr[i]);
311
312             if (pf == primary) {
313                 // this object could belong to this loader
314
try {
315                     // this will go thru regular process of looking for
316
// data object and register this file with the right (but not
317
// necessary this one) data object
318
DataObject.find (arr[i]);
319                 } catch (DataObjectNotFoundException ex) {
320                     // ignore
321
}
322             }
323         }
324     }
325
326     MultiDataObject.Entry createSecondaryEntryImpl (MultiDataObject obj, FileObject secondaryFile) {
327         return createSecondaryEntry (obj, secondaryFile);
328     }
329
330     FileObject findPrimaryFileImpl (FileObject fo) {
331         return findPrimaryFile (fo);
332     }
333 }
334
Popular Tags