Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/merlotxml/merlot/XMLFile.java


1   /*
2   ====================================================================
3   Copyright (c) 1999-2000 ChannelPoint, Inc..  All rights reserved.
4   ====================================================================
5   
6   Redistribution and use in source and binary forms, with or without 
7   modification, are permitted provided that the following conditions 
8   are met:
9   
10  1. Redistribution of source code must retain the above copyright 
11  notice, this list of conditions and the following disclaimer. 
12  
13  2. Redistribution in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in the 
15  documentation and/or other materials provided with the distribution.
16  
17  3. All advertising materials mentioning features or use of this 
18  software must display the following acknowledgment:  "This product 
19  includes software developed by ChannelPoint, Inc. for use in the 
20  Merlot XML Editor (http://www.merlotxml.org/)."
21   
22  4. Any names trademarked by ChannelPoint, Inc. must not be used to 
23  endorse or promote products derived from this software without prior
24  written permission. For written permission, please contact
25  legal@channelpoint.com.
26  
27  5.  Products derived from this software may not be called "Merlot"
28  nor may "Merlot" appear in their names without prior written
29  permission of ChannelPoint, Inc.
30  
31  6. Redistribution of any form whatsoever must retain the following
32  acknowledgment:  "This product includes software developed by 
33  ChannelPoint, Inc. for use in the Merlot XML Editor 
34  (http://www.merlotxml.org/)."
35  
36  THIS SOFTWARE IS PROVIDED BY CHANNELPOINT, INC. "AS IS" AND ANY EXPRESSED OR 
37  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
38  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO 
39  EVENT SHALL CHANNELPOINT, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
40  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
41  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
42  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
43  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
44  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
45  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46   ====================================================================
47  
48  For more information on ChannelPoint, Inc. please see http://www.channelpoint.com.  
49  For information on the Merlot project, please see 
50  http://www.merlotxml.org.
51  */
52  
53  
54  // Copyright 1999 ChannelPoint, Inc., All Rights Reserved.
55  
56  package org.merlotxml.merlot;
57  
58  import java.awt.*;
59  
60  import java.beans.*;
61  import java.io.*;
62  import javax.swing.*;
63  import java.util.*;
64  
65  import org.w3c.dom.*;
66  
67  import org.merlotxml.util.xml.*;
68  import org.merlotxml.util.*;
69  import org.merlotxml.util.xml.xerces.DOMLiaison;
70  
71  
72  /**
73   * 
74   * An XML file. This provides an internface into a particular XML file,
75   * including its dtd and its file location. It provides methods for 
76   * loading and parsing a file, saving a file, and accessing the content
77   * model in the dtd.
78   *
79   * 
80   * @author Kelly A. Campbell
81   *
82   * @version $Id: XMLFile.java,v 1.3 2002/01/16 17:46:25 flament Exp $
83   *
84   */
85  public class XMLFile
86    implements MerlotConstants
87  
88  {
89      /**
90       * The parsed DOM document with validation
91       */
92      protected ValidDocument _doc = null;
93    
94      /**
95       * The document type (dtd)
96       */
97      protected DocumentType _docType = null;
98    
99      /**
100      * The file on the filesystem
101      */
102     protected File      _file = null;
103 
104     /**
105      * Status holder for marking the file as needing a save
106      */
107     protected boolean   _dirty = false;
108     /**
109      * Status marker for brand new files so we can call saveas instead of save
110      */
111     protected boolean   _new  = false;
112   
113     /**
114      * property change delegate
115      */
116     protected PropertyChangeSupport _propchange;
117   
118     /**
119      * Reads in the given filename to create the Document tree
120      */
121     
122     public XMLFile (File f) 
123   throws MerlotException
124     {
125   
126   _file = f;
127   
128   _propchange = new PropertyChangeSupport(this);
129   
130   // now parse the file and get a Document
131   parseDocument();
132   
133     }
134     
135     /**
136      * creates a new file with a blank Document tree
137      */
138     public XMLFile () 
139   throws MerlotException
140     {
141   
142   _propchange = new PropertyChangeSupport(this);
143   
144   _doc = XMLEditor.getSharedInstance().getDOMLiaison().createValidDocument();
145     }
146     
147     /**
148      * Returns the DOM document for this file
149      */
150     public Document getDocument() 
151     {
152   return _doc.getDocument();
153     }
154     
155     /**
156      * Returns the DOMLiaison ValidDocument wrapper for this file
157      */
158     public ValidDocument getValidDocument() 
159     {
160   return _doc;
161     }
162     
163     /**
164      * Returns the main DTDDocument for this file
165      */
166     public DTDDocument getDTD(String name) 
167     {
168   return _doc.getDTDDocument(name);
169     }
170     
171     /**
172      * returns the DTDCacheEntry for this document. Useful to get access to the
173      * DTD plugin associated with this file
174      */
175     public DTDCacheEntry getDTDCacheEntry() 
176     {
177   return _doc.getDTDCacheEntry();
178     }
179     
180     /**
181      * Sets the new property
182      */
183     public void setNew(boolean tf) 
184     {
185   _new = tf;
186     }
187     
188     /**
189      * returns the new property
190      */
191     public boolean isNew() 
192     {
193   return _new;
194     }
195     
196     /*
197     /* *
198      * sets this to the given document replacing the previous one
199      * /
200     public void setDocument(Document doc) 
201     {
202   //XXX  _doc = doc;
203     // update this to handle setDocument for the new valid parser liaison
204     }
205     */
206 
207     public DocumentType getDoctype() 
208     {
209   return _docType;
210     }
211   
212     
213     protected void parseDocument() 
214   throws MerlotException
215     {
216 
217   try {
218       InputStream fis = FileUtil.getInputStream(_file, this.getClass());
219       // get a DOMLiaison from the settings and parse the given file
220       ValidDOMLiaison domlia = XMLEditor.getSharedInstance().getDOMLiaison();
221       if (domlia != null) {
222     _doc = domlia.parseValidXMLStream(fis,_file.getCanonicalPath());
223       }
224       if (_doc != null || _doc.getDocument() == null) {
225     _docType = _doc.getDocument().getDoctype();
226       }
227       else {
228     throw new MerlotException(MerlotResource.getString(ERR, "xml.file.open.nodocument"));
229       }
230         
231   }
232   catch (FileNotFoundException fnf) {
233       MerlotDebug.exception(fnf);
234       throw new MerlotException("File not found: "+ _file, fnf);
235   }
236   catch (IOException ioex) {
237       MerlotDebug.exception(ioex);
238       throw new MerlotException("IOException: "+ _file, ioex);
239   }
240   
241   catch (DOMLiaisonImplException dle) {
242       Exception blah = dle.getRealException();
243       if (blah != null) {
244     MerlotDebug.msg("dle.msessage = "+dle.getMessage());
245       
246     MerlotDebug.exception(dle);
247       }
248       else {
249     MerlotDebug.msg("wrapper exception with a null real exception");
250       }
251       
252       throw new MerlotException("Parse error: "+dle.getMessage(), dle);
253   }
254 
255     
256     
257     }
258 
259 
260     public void printRawXML (OutputStream s, boolean pretty) 
261   throws MerlotException
262     {
263   try {
264       Writer w;
265       String encoding = _doc.getEncoding();
266       if (encoding != null) {
267     w = new OutputStreamWriter(s,encoding);
268       }
269       else {
270     w = new OutputStreamWriter(s);
271       }
272       
273       XMLEditor.getSharedInstance().getDOMLiaison().print(_doc,w,null,pretty);
274       /* Xerces pretty printing is really bad in some cases. going back to original save routine
275 
276         DOMLiaison xercesDomLiaison = new DOMLiaison();
277     xercesDomLiaison.print(_doc,w,null,pretty);
278       */
279   }
280   catch (Exception ex) {
281       MerlotDebug.exception(ex);
282       throw new MerlotException (MerlotResource.getString(ERR,"xml.file.write.err"),ex);
283   }
284     
285     }
286   
287 
288     public String getName() 
289     {
290   return _file.getName();
291     }
292   
293     public String getPath() 
294     {
295   return _file.getPath();
296     }
297   
298     public Enumeration getDTDAttributes(String elementName) 
299     {
300   return _doc.getDTDAttributes(elementName);
301     }
302   
303     /*
304     public Enumeration getAppendableElements(Element el) {
305   DTDDocument doc = _doc.getDTDForElement(el);
306   if (doc != null) {
307       Enumeration e = doc.getAppendableElements(el);
308       return e;
309   }
310   return null;
311     }
312     */
313     public Enumeration getInsertableElements(Element el, int index)
314     {
315   DTDDocument doc = _doc.getDTDForElement(el);
316   if (doc != null) {
317       Enumeration e = doc.getInsertableElements(el, index);
318       return e;
319   }
320   return null;
321     }
322   
323   public boolean elementIsValid (Element el, boolean checkChildren)
324   {
325     DTDDocument doc = _doc.getDTDForElement(el);
326     if (doc == null) 
327       return false;
328     return doc.elementIsValid(el,checkChildren);
329   }
330          
331   public void setDirty(boolean tf) 
332     {
333   boolean old = _dirty;
334   _dirty = tf;
335     
336   firePropertyChange("dirty",old,tf);
337     
338 
339     }
340   
341     public boolean isDirty() 
342     {
343   return _dirty;
344     }
345   
346     public void addPropertyChangeListener(PropertyChangeListener l) 
347     {
348   _propchange.addPropertyChangeListener(l);
349     }
350   
351     public void firePropertyChange(String s, boolean ov, boolean nv) 
352     {
353   MerlotDebug.msg("XMLFile firePropertyChange: "+s);
354       
355   _propchange.firePropertyChange(s,ov,nv);
356     }
357 
358     /**
359      * Saves in the same file we opened
360      */
361     public void save() 
362   throws MerlotException
363     {
364   saveAs(_file);
365     
366     }
367   
368     /**
369      * Saves to a new file
370      */
371     public void saveAs(File f) 
372   throws MerlotException
373     {
374   try {
375 
376       // keep a backup of the original file incase the saveAs fails
377       File tmpFile = new File(f.getAbsolutePath() + ".tmpsave");
378       
379       //      _file = f;
380       OutputStream s = new FileOutputStream(tmpFile);
381       printRawXML(s,/*=$* true *=$*/false);
382       s.close();
383       
384       
385       // if it didn't work an exception will be thrown and we won't get here
386       // now replace the old file with the tmp one
387       File backup = new File(_file.getAbsolutePath() + ".$$$");
388       // if the backup already exists... remove it
389       boolean tf;
390       if (backup.exists()) {
391     tf = backup.delete();
392     MerlotDebug.msg("Deleting "+backup+" returns "+tf);
393       }
394       if (!_new) MerlotUtils.copyFile(_file, backup);
395       MerlotUtils.copyFile(tmpFile,f);
396       tf = tmpFile.delete();
397       MerlotDebug.msg("Deleting "+tmpFile+" returns "+tf);
398       
399     
400       _file = f;
401       
402       setDirty(false);
403       setNew(false);
404       
405   }
406   catch (IOException ex){
407       throw new MerlotException("IOException while saving file: "+ex.getMessage(), ex);
408   }
409     
410     }
411 
412 }