KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > core > XMLDataLoader


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 package org.netbeans.modules.xml.core;
20
21 import java.io.*;
22 import java.util.*;
23 import java.text.DateFormat JavaDoc;
24
25 import org.openide.filesystems.*;
26 import org.openide.loaders.*;
27 import org.openide.util.actions.SystemAction;
28 import org.openide.util.*;
29 import org.openide.actions.*;
30 import org.openide.ErrorManager;
31
32 import org.netbeans.modules.xml.core.actions.CollectXMLAction;
33 import org.netbeans.modules.xml.core.actions.XMLUpdateDocumentAction;
34
35 /** The DataLoader for XMLDataObjects.
36  * This class is final only for performance reasons,
37  * can be happily unfinaled if desired.
38  */

39 public class XMLDataLoader extends UniFileLoader {
40     // UID of F4J 1.0 build 501
41
private static final long serialVersionUID = 3824119075670384804L;
42
43     /** Extension constants */
44     private static final String JavaDoc XML_EXT = "xml"; // NOI18N
45
private static final String JavaDoc XMLINFO_EXT = "xmlinfo"; // NOI18N
46

47     /** Creates a new XMLDataLoader */
48     public XMLDataLoader () {
49         super ("org.netbeans.modules.xml.core.XMLDataObject"); // NOI18N
50
}
51
52 // protected XMLDataLoader (Class cls) {
53
// super (cls);
54
// }
55

56     /** Initialize XMLDataLoader: name, actions, ...
57      */

58     protected void initialize () {
59         super.initialize();
60         
61         ExtensionList ext = getExtensions();
62         ext.addExtension (XML_EXT);
63         ext.addMimeType (org.netbeans.modules.xml.core.XMLDataObject.MIME_TYPE);
64         ext.addMimeType ("application/xml"); // http://www.ietf.org/rfc/rfc3023.txt // NOI18N
65
// ext.addMimeType (org.netbeans.modules.xml.core.XMLDataObject.XSLT_MIME_TYPE);
66
setExtensions (ext);
67     }
68      
69     protected String JavaDoc actionsContext() {
70         return "Loaders/text/xml-mime/Actions/";
71     }
72
73     /**
74      * Lazy init name.
75      */

76     protected String JavaDoc defaultDisplayName () {
77         return Util.THIS.getString ("PROP_XmlLoader_Name");
78     }
79     
80     /** For a given file finds a primary file.
81      * @param fo the file to find primary file for
82      *
83      * @return the primary file for the file or null if the file is not
84      * recognized by this loader
85      */

86     protected FileObject findPrimaryFile (FileObject fo) {
87         if (fo.isFolder()) {
88             return null;
89         }
90
91         FileObject res = null;
92         if ( super.findPrimaryFile (fo) != null ) {
93             res = fo;
94         } else if ( XMLINFO_EXT.equals (fo.getExt()) ) {
95             res = FileUtil.findBrother (fo, XML_EXT);
96         } else if ( fo.getMIMEType().endsWith ("+xml") ) { // NOI18N
97
// recognize all XML flavours
98
res = fo;
99         }
100
101         // give up for files on system file system that don't prefer us
102
try {
103             if ( ( res != null ) &&
104                  ( res.getFileSystem().isDefault() == true ) ) { // system file system
105
if ( ( DataLoaderPool.getPreferredLoader (res) != this ) && // the preferred DataLoader is not this loader
106
( isTemplate (res) == false ) ) { // it is not template
107
res = null;
108                 }
109             }
110         } catch (FileStateInvalidException ex) {
111             // ok, go on
112
}
113         
114         return res;
115     }
116
117     
118     /** Get the template status of this data object.
119      * @return <code>true</code> if it is a template
120      */

121     private static boolean isTemplate (FileObject fo) {
122         Object JavaDoc o = fo.getAttribute (DataObject.PROP_TEMPLATE);
123         boolean ret = false;
124         if ( o instanceof Boolean JavaDoc ) {
125             ret = ((Boolean JavaDoc) o).booleanValue();
126         }
127         return ret;
128     }
129
130
131     /** Creates the right data object for given primary file.
132      * It is guaranteed that the provided file is realy primary file
133      * returned from the method findPrimaryFile.
134      *
135      * @param primaryFile the primary file
136      * @return the data object for this file
137      * @exception DataObjectExistsException if the primary file already has data object
138      */

139     protected MultiDataObject createMultiObject (FileObject primaryFile)
140     throws DataObjectExistsException {
141         try {
142 // System.err.println("Creating XML DO" + primaryFile);
143
return new org.netbeans.modules.xml.core.XMLDataObject (primaryFile, this);
144         } catch (org.openide.loaders.DataObjectExistsException ex) {
145 // System.err.println("Existing data object " + ex.getDataObject());
146
// ex.printStackTrace();
147
throw ex;
148         }
149     }
150
151     /** Creates the right primary entry for given primary file.
152      *
153      * @param primaryFile primary file recognized by this loader
154      * @return primary entry for that file
155      */

156     protected MultiDataObject.Entry createPrimaryEntry (MultiDataObject obj, FileObject primaryFile) {
157         return new XMLFileEntry (obj, primaryFile);
158     }
159
160     /** Creates right secondary entry for given file. The file is said to
161      * belong to an object created by this loader.
162      *
163      * @param secondaryFile secondary file for which we want to create entry
164      * @return the entry
165      */

166     protected MultiDataObject.Entry createSecondaryEntry (MultiDataObject obj, FileObject secondaryFile) {
167         return new FileEntry (obj, secondaryFile);
168     }
169
170
171     /** This entry defines the format for replacing the text during
172      * instantiation the data object.
173      */

174     public static class XMLFileEntry extends FileEntry.Format {
175
176         /** Serial Version UID */
177         private static final long serialVersionUID = -7300320795693949470L;
178         
179         
180         /**
181          * If true, the Entry refuses to open InputStream to prevent races
182          * between readers and attempts to delete the file.
183          */

184         boolean disableInputStream;
185         
186         /**
187          * Holds a collection of readers that read the file.
188          */

189         private Collection activeReaders;
190         
191         /** Creates new MakefileFileEntry */
192         public XMLFileEntry (MultiDataObject obj, FileObject file) {
193             super (obj, file);
194         }
195
196         /** Method to provide suitable format for substitution of lines.
197          *
198          * @param target the target folder of the installation
199          * @param name the name the file will have
200          * @param ext the extension the file will have
201          * @return format to use for formating lines
202          */

203         protected java.text.Format JavaDoc createFormat (FileObject target, String JavaDoc name, String JavaDoc ext) {
204             HashMap map = new HashMap();
205             Date now = new Date();
206
207             map.put ("NAME", name + "." + ext); // NOI18N
208

209             //??? find replacement (inline TAX code)
210
map.put ("ROOT", "root"); // NOI18N
211
// map.put ("ROOT", name);
212
// try {
213
// TreeName tn = new TreeName (name);
214
// map.put ("ROOT", TreeUtilities.isValidElementTagName(tn) ? name : "root"); //NOI18N
215
// } catch (InvalidArgumentException ex) {
216
// map.put ("ROOT", "root"); //NOI18N
217
// }
218

219             map.put ("DATE", DateFormat.getDateInstance (DateFormat.LONG).format (now)); // NOI18N
220
map.put ("TIME", DateFormat.getTimeInstance (DateFormat.SHORT).format (now)); // NOI18N
221
map.put ("USER", System.getProperty ("user.name")); // NOI18N
222

223             MapFormat format = new MapFormat (map);
224             format.setLeftBrace ("__"); // NOI18N
225
format.setRightBrace ("__"); // NOI18N
226
format.setExactMatch (false);
227             return format;
228         }
229         
230         /*###
231           this code is copied from FileEntry
232           TT EXPECTS that all XML templates are encoded as UTF-8
233           FileEntry implementation used just platform default encoding
234         ###*/

235
236         
237         /* Creates dataobject from template. Copies the file and applyes substitutions
238         * provided by the createFormat method.
239         *
240         * @param f the folder to create instance in
241         * @param name name of the file or null if it should be choosen automaticly
242         */

243         public FileObject createFromTemplate (FileObject f, String JavaDoc name) throws IOException {
244             String JavaDoc ext = getFile ().getExt ();
245
246             if (name == null) {
247                 name = FileUtil.findFreeFileName(
248                            f,
249                            getFile ().getName (), ext
250                        );
251             }
252             FileObject fo = f.createData (name, ext);
253
254             java.text.Format JavaDoc frm = createFormat (f, name, ext);
255
256             BufferedReader r = new BufferedReader (new InputStreamReader (getFile ().getInputStream (), "UTF8")); // NOI18N
257
try {
258                 FileLock lock = fo.lock ();
259                 try {
260                     BufferedWriter w = new BufferedWriter (new OutputStreamWriter (fo.getOutputStream (lock), "UTF8")); // NOI18N
261

262                     try {
263                         String JavaDoc line = null;
264                         String JavaDoc current;
265                         while ((current = r.readLine ()) != null) {
266                             line = frm.format (current);
267                             w.write (line);
268                             w.newLine ();
269                         }
270                     } finally {
271                         w.close ();
272                     }
273                 } finally {
274                     lock.releaseLock ();
275                 }
276             } finally {
277                 r.close ();
278             }
279
280             // copy attributes
281
FileUtil.copyAttributes (getFile (), fo);
282
283             // unmark template state //###
284
try {
285                 DataObject.find(fo).setTemplate (false);
286             } catch (DataObjectNotFoundException ex) {
287                 ErrorManager.getDefault().notify(ex);
288             }
289
290             return fo;
291         }
292
293         //!!!
294
// bloody OpemIDE why must every one copy paste this code?
295

296         private synchronized void addReader(InputStream r) {
297             if (activeReaders == null) {
298                 activeReaders = new LinkedList();
299             }
300             activeReaders.add(r);
301         }
302
303         private synchronized void removeReader(InputStream r) {
304             if (activeReaders == null)
305                 return;
306             activeReaders.remove(r);
307         }
308
309         public void delete() throws IOException {
310             synchronized (this) {
311                 if (activeReaders != null && activeReaders.size() > 0) {
312                     for (Iterator it = activeReaders.iterator(); it.hasNext(); ) {
313                         InputStream r = (InputStream)it.next();
314                         r.close();
315                         it.remove();
316                     }
317                 }
318                 activeReaders = null;
319                 disableInputStream = true;
320             }
321             super.delete();
322         }
323
324         public InputStream getInputStream() throws FileNotFoundException {
325             FileObject fob = getFile();
326             synchronized (this) {
327                 if (disableInputStream) {
328                     // refuse to create the stream.
329
throw new FileNotFoundException("File is being deleted."); // NOI18N
330
}
331                 InputStream s = new NotifyInputStream(fob.getInputStream());
332                 addReader(s);
333                 return s;
334             }
335         }
336
337         private class NotifyInputStream extends FilterInputStream {
338             public NotifyInputStream(InputStream is) {
339                 super(is);
340             }
341
342             public void close() throws IOException {
343                 super.close();
344                 removeReader(this);
345             }
346         }
347
348         // debug taking locks
349
public FileLock takeLock() throws IOException {
350             FileLock lock = super.takeLock();
351             
352             if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("XMLDataLoader.XMLEntry.takeLock()/" + getFile() + "=" + lock); // NOI18N
353

354             return lock;
355         }
356
357     }
358
359 }
360
Popular Tags