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

com.ibatis.common.xml.NodeletParser Maven / Gradle / Ivy

Go to download

The jBATIS persistence framework will help you to significantly reduce the amount of Java code that you normally need to access a relational database. iBATIS simply maps JavaBeans to SQL statements using a very simple XML descriptor.

The newest version!
package com.ibatis.common.xml;

import org.w3c.dom.*;
import org.xml.sax.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.*;

/**
 * The NodeletParser is a callback based parser similar to SAX. The big difference is that rather than having a single
 * callback for all nodes, the NodeletParser has a number of callbacks mapped to various nodes. The callback is called a
 * Nodelet and it is registered with the NodeletParser against a specific XPath.
 */
public class NodeletParser {

    private Map letMap = new HashMap();

    private boolean validation;
    private EntityResolver entityResolver;

    /**
     * Registers a nodelet for the specified XPath. Current XPaths supported are:
     * 
    *
  • Text Path - /rootElement/childElement/text() *
  • Attribute Path - /rootElement/childElement/@theAttribute *
  • Element Path - /rootElement/childElement/theElement *
  • All Elements Named - //theElement *
*/ public void addNodelet(String xpath, Nodelet nodelet) { letMap.put(xpath, nodelet); } /** * Begins parsing from the provided Reader. */ public void parse(String resource, Reader reader) throws NodeletException { try { Document doc = createDocument(reader); parse(doc.getLastChild()); } catch (SAXParseException e) { throw new NodeletException("Error parsing [" + resource + ", " + e.getLineNumber() + "]. Cause: " + e, e); } catch (NodeletException e) { throw e; } catch (Exception e) { throw new NodeletException("Error parsing [" + resource + "]. Cause: " + e, e); } } public void parse(String resource, InputStream inputStream) throws NodeletException { try { Document doc = createDocument(inputStream); parse(doc.getLastChild()); } catch (SAXParseException e) { throw new NodeletException("Error parsing [" + resource + ", " + e.getLineNumber() + "]. Cause: " + e); } catch (NodeletException e) { throw e; } catch (Exception e) { throw new NodeletException("Error parsing [" + resource + "]. Cause: " + e, e); } } /** * Begins parsing from the provided Node. */ public void parse(Node node) { Path path = new Path(); processNodelet(node, "/"); process(node, path); } /** * A recursive method that walkes the DOM tree, registers XPaths and calls Nodelets registered under those XPaths. */ private void process(Node node, Path path) { if (node instanceof Element) { // Element String elementName = node.getNodeName(); path.add(elementName); processNodelet(node, path.toString()); processNodelet(node, new StringBuilder("//").append(elementName).toString()); // Attribute NamedNodeMap attributes = node.getAttributes(); int n = attributes.getLength(); for (int i = 0; i < n; i++) { Node att = attributes.item(i); String attrName = att.getNodeName(); path.add("@" + attrName); processNodelet(att, path.toString()); processNodelet(node, new StringBuilder("//@").append(attrName).toString()); path.remove(); } // Children NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { process(children.item(i), path); } path.add("end()"); processNodelet(node, path.toString()); path.remove(); path.remove(); } else if (node instanceof Text) { // Text path.add("text()"); processNodelet(node, path.toString()); processNodelet(node, "//text()"); path.remove(); } } private void processNodelet(Node node, String pathString) { Nodelet nodelet = letMap.get(pathString); if (nodelet != null) { try { nodelet.process(node); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException("Error parsing XPath '" + pathString + "'. Cause: " + e, e); } } } /** * Creates a JAXP Document from a reader. */ private Document createDocument(Reader reader) throws ParserConfigurationException, FactoryConfigurationError, SAXException, IOException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(validation); factory.setNamespaceAware(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(false); factory.setCoalescing(false); factory.setExpandEntityReferences(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(entityResolver); builder.setErrorHandler(new ErrorHandler() { public void error(SAXParseException exception) throws SAXException { throw exception; } public void fatalError(SAXParseException exception) throws SAXException { throw exception; } public void warning(SAXParseException exception) throws SAXException { } }); return builder.parse(new InputSource(reader)); } /** * Creates a JAXP Document from an InoutStream. */ private Document createDocument(InputStream inputStream) throws ParserConfigurationException, FactoryConfigurationError, SAXException, IOException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(validation); factory.setNamespaceAware(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(false); factory.setCoalescing(false); factory.setExpandEntityReferences(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(entityResolver); builder.setErrorHandler(new ErrorHandler() { public void error(SAXParseException exception) throws SAXException { throw exception; } public void fatalError(SAXParseException exception) throws SAXException { throw exception; } public void warning(SAXParseException exception) throws SAXException { } }); return builder.parse(new InputSource(inputStream)); } public void setValidation(boolean validation) { this.validation = validation; } public void setEntityResolver(EntityResolver resolver) { this.entityResolver = resolver; } /** * Inner helper class that assists with building XPath paths. *

* Note: Currently this is a bit slow and could be optimized. */ private static class Path { private List nodeList = new ArrayList(); public Path() { } public void add(String node) { nodeList.add(node); } public void remove() { nodeList.remove(nodeList.size() - 1); } public String toString() { StringBuilder buffer = new StringBuilder("/"); for (int i = 0; i < nodeList.size(); i++) { buffer.append(nodeList.get(i)); if (i < nodeList.size() - 1) { buffer.append("/"); } } return buffer.toString(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy