/* * 08/16/2008 * * XMLParser.java - Simple XML parser. * * This library is distributed under a modified BSD license. See the included * RSyntaxTextArea.License.txt file for details. */ package org.fife.ui.rsyntaxtextarea.parser; import javax.swing.text.Document; import javax.swing.text.Element; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.*; import org.xml.sax.helpers.*; import org.fife.io.DocumentReader; import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; /** * A parser for XML documents. Adds squiggle underlines for any XML errors * found (though most XML parsers don't really have error recovery and so only * can find one error at a time).

* * This class isn't actually used by RSyntaxTextArea anywhere, but you can * install and use it yourself. Doing so is as simple as: * *

 * XmlParser xmlParser = new XmlParser();
 * textArea.addParser(xmlParser);
 * 
* * Also note that a single instance of this class can be installed on * multiple instances of RSyntaxTextArea. * * For a more complete XML parsing solution, see the * RSTALanguageSupport * project's XmlLanguageSupport class. * * @author Robert Futrell * @version 1.1 */ public class XmlParser extends AbstractParser { private SAXParserFactory spf; private DefaultParseResult result; public XmlParser() { result = new DefaultParseResult(this); try { spf = SAXParserFactory.newInstance(); } catch (FactoryConfigurationError fce) { fce.printStackTrace(); } } /** * {@inheritDoc} */ public ParseResult parse(RSyntaxDocument doc, String style) { result.clearNotices(); Element root = doc.getDefaultRootElement(); result.setParsedLines(0, root.getElementCount()-1); if (spf==null) { return result; } try { SAXParser sp = spf.newSAXParser(); Handler handler = new Handler(doc); DocumentReader r = new DocumentReader(doc); InputSource input = new InputSource(r); sp.parse(input, handler); r.close(); } catch (SAXParseException spe) { // A fatal parse error - ignore; a ParserNotice was already created. } catch (Exception e) { e.printStackTrace(); result.addNotice(new DefaultParserNotice(this, "Error parsing XML: " + e.getMessage(), 0, -1, -1)); } return result; } /** * Callback notified when errors are found in the XML document. Adds a * notice to be squiggle-underlined. */ private class Handler extends DefaultHandler { private Document doc; private Handler(Document doc) { this.doc = doc; } private void doError(SAXParseException e, int level) { int line = e.getLineNumber() - 1; Element root = doc.getDefaultRootElement(); Element elem = root.getElement(line); int offs = elem.getStartOffset(); int len = elem.getEndOffset() - offs; if (line==root.getElementCount()-1) { len++; } DefaultParserNotice pn = new DefaultParserNotice(XmlParser.this, e.getMessage(), line, offs, len); pn.setLevel(level); result.addNotice(pn); } public void error(SAXParseException e) { doError(e, ParserNotice.ERROR); } public void fatalError(SAXParseException e) { doError(e, ParserNotice.ERROR); } public void warning(SAXParseException e) { doError(e, ParserNotice.WARNING); } } }