All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.ui.rsyntaxtextarea.parser.XmlParser Maven / Gradle / Ivy

The newest version!
/*
 * 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 java.io.IOException;
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);
 * 
* * To support DTD validation, specify an entity resolver when creating the * parser, and enable validation like so: * *
 * XmlParser xmlParser = new XmlParser(new MyEntityResolver());
 * xmlParser.setValidating(true);
 * 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/validation 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; private EntityResolver entityResolver; public XmlParser() { this(null); } /** * Constructor allowing DTD validation of documents. * * @param resolver An entity resolver to use if validation is enabled. * @see #setValidating(boolean) */ public XmlParser(EntityResolver resolver) { this.entityResolver = resolver; result = new DefaultParseResult(this); try { spf = SAXParserFactory.newInstance(); } catch (FactoryConfigurationError fce) { fce.printStackTrace(); } } /** * Returns whether this parser does DTD validation. * * @return Whether this parser does DTD validation. * @see #setValidating(boolean) */ public boolean isValidating() { return spf.isValidating(); } /** * {@inheritDoc} */ public ParseResult parse(RSyntaxDocument doc, String style) { result.clearNotices(); Element root = doc.getDefaultRootElement(); result.setParsedLines(0, root.getElementCount()-1); if (spf==null || doc.getLength()==0) { 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(); // Will print if DTD specified and can't be found result.addNotice(new DefaultParserNotice(this, "Error parsing XML: " + e.getMessage(), 0, -1, -1)); } return result; } /** * Sets whether this parser will use DTD validation if required. * * @param validating Whether DTD validation should be enabled. If this is * true, documents must specify a DOCTYPE, and you * should have used the constructor specifying an entity resolver. * @see #isValidating() */ public void setValidating(boolean validating) { spf.setValidating(validating); } /* public static void main(String[] args) { javax.swing.JFrame frame = new javax.swing.JFrame(); org.fife.ui.rsyntaxtextarea.RSyntaxTextArea textArea = new org.fife.ui.rsyntaxtextarea.RSyntaxTextArea(25, 40); textArea.setSyntaxEditingStyle("text/xml"); XmlParser parser = new XmlParser(new EntityResolver() { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if ("http://fifesoft.com/rsyntaxtextarea/theme.dtd".equals(systemId)) { return new org.xml.sax.InputSource(getClass().getResourceAsStream("/theme.dtd")); } return null; } }); parser.setValidating(true); textArea.addParser(parser); try { textArea.read(new java.io.BufferedReader(new java.io.FileReader("C:/temp/test.xml")), null); } catch (Exception e) { e.printStackTrace(); } frame.setContentPane(new org.fife.ui.rtextarea.RTextScrollPane(textArea)); frame.pack(); frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } */ /** * 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, ParserNotice.Level 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); } @Override public void error(SAXParseException e) { doError(e, ParserNotice.Level.ERROR); } @Override public void fatalError(SAXParseException e) { doError(e, ParserNotice.Level.ERROR); } @Override public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException { if (entityResolver!=null) { return entityResolver.resolveEntity(publicId, systemId); } return super.resolveEntity(publicId, systemId); } @Override public void warning(SAXParseException e) { doError(e, ParserNotice.Level.WARNING); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy