View Javadoc
1   /*
2    * Copyright 2007 Edward Kuns
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * $Id: XMLReader.java 0000 2007-01-11 00:00:00Z ekuns $
17   */
18  package org.castor.xmlctf.xmldiff.xml;
19  
20  import java.io.File;
21  import java.io.FileReader;
22  import java.net.MalformedURLException;
23  
24  import javax.xml.parsers.SAXParser;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.castor.core.util.Messages;
28  import org.castor.xmlctf.xmldiff.xml.nodes.Root;
29  import org.castor.xmlctf.xmldiff.xml.nodes.XMLNode;
30  import org.exolab.castor.util.NestedIOException;
31  import org.exolab.castor.xml.util.XMLParserUtils;
32  import org.xml.sax.InputSource;
33  import org.xml.sax.SAXException;
34  import org.xml.sax.SAXParseException;
35  import org.xml.sax.XMLReader;
36  
37  /**
38   * A Utility class to read an XML document from a file into the XMLNode tree
39   * used by the XMLDiff class.
40   *
41   * @author <a href="mailto:edward.kuns@aspect.com">Edward Kuns</a>
42   * @version $Revision: 0000 $ $Date: 2007-01-11 00:00:00 -0600 (Thu, 11 Jan 2007) $
43   * @see org.castor.xmlctf.xmldiff.XMLDiff
44   * @since Castor 1.1
45   */
46  public class XMLFileReader {
47  
48      /** 
49       * The <a href="http://jakarta.apache.org/commons/logging/">Jakarta
50       * Commons Logging</a> instance used for all logging. 
51       */
52      private static final Log LOG = LogFactory.getLog(XMLFileReader.class);
53  
54      /** The file we are reading. */
55      private final File      _file;
56      /** URL for the document to be parsed. */
57      private final String    _location;
58      /** A handle to the SAX parser. */
59      private XMLReader _parser;
60  
61      /**
62       * Creates a new XMLReader for the given URILocation.
63       *
64       * @param filename the URILocation to create this reader for.
65       */
66      public XMLFileReader(final String filename) {
67          if (filename == null) {
68              throw new IllegalArgumentException("You must give a non-null fliename");
69          }
70          _file = new File(filename);
71          if (!_file.exists()) {
72              throw new IllegalArgumentException("File '" + filename + "' does not exist");
73          }
74  
75          _location = getUrlFromFile();
76          
77          SAXParser saxParser = XMLParserUtils.getSAXParser(false, true);
78          try {
79              _parser = saxParser.getXMLReader();
80          }
81          catch(org.xml.sax.SAXException sx) {
82              LOG.error(Messages.format("conf.configurationError", sx));
83          }
84          
85          if (_parser == null) {
86              _parser = XMLParserUtils.instantiateXMLReader("org.apache.xerces.parsers.SAXParser");
87          }
88      }
89  
90      /**
91       * Reads an XML Document into an BaseNode from the provided file.
92       *
93       * @return the BaseNode
94       * @throws java.io.IOException if any exception occurs during parsing
95       */
96      public XMLNode read() throws java.io.IOException {
97          XMLNode node = null;
98  
99          try {
100             InputSource source = new InputSource();
101             source.setSystemId(_location);
102             source.setCharacterStream(new FileReader(_file));
103 
104             XMLContentHandler builder = new XMLContentHandler();
105 
106             _parser.setContentHandler(builder);
107             _parser.parse(source);
108 
109             node = builder.getRoot();
110         } catch (SAXException sx) {
111             Exception nested = sx.getException();
112 
113             SAXParseException sxp = null;
114             if (sx instanceof SAXParseException) {
115                 sxp = (SAXParseException) sx;
116             } else if (nested != null && (nested instanceof SAXParseException)) {
117                 sxp = (SAXParseException) nested;
118             } else {
119                 throw new NestedIOException(sx);
120             }
121 
122             StringBuffer err = new StringBuffer(sxp.toString());
123             err.append("\n - ");
124             err.append(sxp.getSystemId());
125             err.append("; line: ");
126             err.append(sxp.getLineNumber());
127             err.append(", column: ");
128             err.append(sxp.getColumnNumber());
129             throw new NestedIOException(err.toString(), sx);
130         }
131 
132         Root root = (Root) node;
133         return root;
134     }
135 
136     /**
137      * Returns the absolute URL as a string.
138      * @param file The URL to resolve
139      * @return the absolute URL as a string.
140      */
141     private String getUrlFromFile() {
142         try {
143             return _file.toURL().toString();
144         } catch (MalformedURLException e) {
145             // ignore -- cannot happen
146         }
147         return null;
148     }
149 
150 }