Package net.sourceforge.javautil.common.jaxb.xml

Source Code of net.sourceforge.javautil.common.jaxb.xml.XMLReader

package net.sourceforge.javautil.common.jaxb.xml;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;


import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IInputSource;
import net.sourceforge.javautil.common.jaxb.IJavaXMLElement;
import net.sourceforge.javautil.common.jaxb.xml.IXMLElement.NoopElement;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DefaultHandler2;

/**
* This will parse XML and integrate it with the {@link IXMLDocument} API.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class XMLReader<CTX extends XMLContext> extends DefaultHandler2 {
 
  /**
   * @param <CTX> The type of context
   * @param <D> The type of handler
   * @param input The source of the raw XML
   * @param handler The handler instance that will handle XML events
   * @param context The context instance to use with the handler
   * @return The handler for chaining
   */
  public static <CTX extends XMLContext, D extends IXMLDocument<CTX>> CTX parse (IInputSource input, D handler, CTX context) {
    try {
      SAXParserFactory factory = SAXParserFactory.newInstance();
      SAXParser parser = factory.newSAXParser();
     
      XMLReader<CTX> xmlHandler = new XMLReader<CTX>(handler, context);
     
      org.xml.sax.XMLReader reader = parser.getXMLReader();
      reader.setContentHandler(xmlHandler);
      reader.setDTDHandler(xmlHandler);
      reader.setEntityResolver(xmlHandler);
      reader.setErrorHandler(xmlHandler);
     
      reader.setProperty("http://xml.org/sax/properties/lexical-handler", xmlHandler);
     
      reader.parse(new InputSource( input.getInputStream() ));
     
      return context;
    } catch (ParserConfigurationException e) {
      throw ThrowableManagerRegistry.caught(e);
    } catch (SAXException e) {
      throw ThrowableManagerRegistry.caught(e);
    } catch (IOException e) {
      throw ThrowableManagerRegistry.caught(e);
    }
  }
 
  protected final IXMLDocument<CTX> document;
  protected final CTX context;
 
  protected NoopElement<CTX> NULL = new NoopElement<CTX>();
  protected IXMLElement<CTX> currentElement;
 
  protected boolean cdata = false;
  protected IXMLCharacterData<CTX> cdataElement;
 
  protected final List<IXMLElement<CTX>> elements = new ArrayList<IXMLElement<CTX>>();
 
  public XMLReader(IXMLDocument<CTX> document, CTX context) {
    this.document = document;
    this.context = context;
    this.currentElement = document;
  }

  @Override public void startDTD(String name, String publicId, String systemId) throws SAXException {
    document.visitDTD(context, name, publicId, systemId);
  }

  @Override public void endDTD() throws SAXException {}
 
  @Override public void startDocument() throws SAXException {}

  @Override public void comment(char[] ch, int start, int length) throws SAXException {
    if (currentElement != NULL) {
      try {
        currentElement.visitComment(context, ch, start, length);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
  }

  @Override public void startPrefixMapping(String prefix, String uri) throws SAXException {
    if (currentElement != NULL) {
      try {
        currentElement.visitXmlNSDeclaration(context, prefix, uri);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
  }

  @Override public void endPrefixMapping(String prefix) throws SAXException {}

  @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    try {
      if (!"".equals(qName)) {
        String[] parts = qName.split(":");
        this.currentElement = currentElement.visitElement(context, parts.length == 2 ? parts[0] : null, parts.length == 2 ? parts[1] : parts[0]);
      } else if (!"".equals(localName)) {
        this.currentElement = currentElement.visitElement(context, null, localName);
      }
     
      this.elements.add(0, this.currentElement == null ? this.currentElement = NULL : this.currentElement);
     
      if (this.currentElement != NULL) {
        for (int i=0; i<attributes.getLength(); i++) {
          String name = !"".equals( attributes.getLocalName(i) ) ? attributes.getLocalName(i) : attributes.getQName(i);
          String[] parts = name.split(":");
          this.currentElement.visitAttribute(context, parts.length == 2 ? parts[0] : null, parts.length == 2 ? parts[1] : parts[0], attributes.getValue(i));
        }
      }
    } catch (JAXBException e) {
      throw new SAXException(e);
    }
  }

  @Override public void startCDATA() throws SAXException {
    if (currentElement != NULL) {
      this.cdata = true;
      try {
        this.cdataElement = currentElement.visitCharacterData(context);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
  }

  @Override public void endCDATA() throws SAXException {
    if (this.cdataElement != null) {
      try {
        this.cdataElement.visitEnd(context);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
    this.cdata = false;
  }

  @Override public void characters(char[] ch, int start, int length) throws SAXException {
    if (this.cdata) {
      try {
        if (this.cdataElement != NULL) this.cdataElement.visitData(context, ch, start, length);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    } else {
      try {
        if (this.currentElement != NULL)
          this.currentElement.visitContent(context, ch, start, length);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
  }

  @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
    if (this.currentElement != NULL) {
      try {
        this.currentElement.visitWhitespace(context, ch, start, length);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
  }

  @Override public void endElement(String uri, String localName, String qName) throws SAXException {
    if (this.currentElement != NULL) {
      try {
        this.currentElement.visitEnd(context);
      } catch (JAXBException e) {
        throw new SAXException(e);
      }
    }
   
    if (this.elements.size() == 0) {
      throw new SAXException("Stack incorrectly managed");
    } else {
      this.elements.remove(0);
    }
   
    if (this.elements.size() > 0) {
      this.currentElement = this.elements.get(0);
    } else {
      this.currentElement = null;
    }
  }

  @Override public void endDocument() throws SAXException {
//    try {
//      this.document.visitEnd(context);
//    } catch (JAXBException e) {
//      throw new SAXException(e);
//    }
  }

  //
  // ERROR HANDLING
  //

  @Override public void warning(SAXParseException e) throws SAXException {
   
  }

  @Override public void error(SAXParseException e) throws SAXException {
   
  }

  @Override public void fatalError(SAXParseException e) throws SAXException {
   
  }
 
  //
  // SPECIAL PROCESSING
  //

  @Override public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException { return super.resolveEntity(publicId, systemId); }

  @Override public void notationDecl(String name, String publicId, String systemId) throws SAXException { }

  @Override public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException { }

  @Override public void setDocumentLocator(Locator locator) { }

  @Override public void processingInstruction(String target, String data) throws SAXException {}

  @Override public void skippedEntity(String name) throws SAXException {}

  @Override public void startEntity(String name) throws SAXException {}

  @Override public void endEntity(String name) throws SAXException {}

  @Override public void attributeDecl(String eName, String aName, String type, String mode, String value) throws SAXException { }

  @Override public void elementDecl(String name, String model) throws SAXException { }

  @Override public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException { }

  @Override public void internalEntityDecl(String name, String value) throws SAXException { }

  @Override public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException {
    return super.getExternalSubset(name, baseURI);
  }

  @Override public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException {
    return super.resolveEntity(name, publicId, baseURI, systemId);
  }

 
}
TOP

Related Classes of net.sourceforge.javautil.common.jaxb.xml.XMLReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.