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

net.sf.xolite.dom.DomXMLEventParser Maven / Gradle / Ivy

Go to download

This project provides a lightweight framework to serialize/deserialize (or marshall/unmarshall) java objects into XML. The implementation is based on standard SAX (Simple Api for Xml) but it follows a original approach based on the strong data encapsulation paradigm of Object Oriented (OO) programming.

The newest version!
/*-------------------------------------------------------------------------
 Copyright 2006 Olivier Berlanger

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 -------------------------------------------------------------------------*/
package net.sf.xolite.dom;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.NamespaceContext;

import net.sf.xolite.XMLParseException;
import net.sf.xolite.XMLSerializable;
import net.sf.xolite.impl.BaseXMLEventParser;
import net.sf.xolite.impl.MapPrefixResolver;
import net.sf.xolite.utils.RootHolder;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;


/**
 * A XMLEventParser implementation using a DOM tree as input.
 */
public class DomXMLEventParser extends BaseXMLEventParser {

    /** Current parsed XML element. */
    private Element currentElement;


    /**
     * Build a DomEventParser.
     */
    public DomXMLEventParser() {
    }


    /**
     * 'Parse' the given DOM Document to java objects. 
* This method will succeed only if a factory knowing the class of the root element is defined. * * @param src * source DOM Document. * @throws XMLParseException * if the source contains an invalid XML document. */ public XMLSerializable parse(Document src) throws XMLParseException { RootHolder holder = new RootHolder(); parse(src, holder); return holder.getRoot(); } /** * 'Parse' the given DOM Document using the given XMLSerializable as root handler. * * @param src * source DOM Document. * @param rootHandler * the root handler. * @throws XMLParseException * if the source contains an invalid DOM document. */ public void parse(Document src, XMLSerializable rootHandler) throws XMLParseException { if (src == null) throw new IllegalArgumentException("InputSource cannot be null"); if (rootHandler == null) throw new IllegalArgumentException("Root SaxHandler cannot be null"); try { setup(rootHandler); parseImpl(src.getDocumentElement()); tearDown(); } catch (Exception e) { transformAndThrowException(e); } } /** * Clean state and avoid keeping dangling references to internal objects. */ @Override protected void tearDown() { currentElement = null; super.tearDown(); } private void parseImpl(Element elem) throws Exception { currentElement = elem; startElementImpl(elem.getNamespaceURI(), elem.getLocalName()); NodeList childNodes = elem.getChildNodes(); int len = childNodes.getLength(); Node child; for (int i = 0; i < len; i++) { child = childNodes.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { parseImpl((Element) child); } } currentElement = elem; endElementImpl(elem.getNamespaceURI(), elem.getLocalName()); } /** * Get namespace URI corresponding to the given prefix. Note: the mapped namespace set depends on the current parsed node. */ @Override public String getNamespaceURI(String prefix) { return DomUtils.getDefinedUri(currentElement, prefix); } /** * Get the first perfix mapped to the given namespace. * * @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String) */ @Override public String getPrefix(String namespaceURI) { return DomUtils.getDefinedPerfix(currentElement, namespaceURI); } /** * Get all the prefix mapped to the given namespace. * * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String) */ @Override public Iterator getPrefixes(String namespaceURI) { return DomUtils.getDefinedPerfixes(currentElement, namespaceURI).iterator(); } // ------------------------ XMLEventParser interface implementation ----------------------------------------------- @Override public NamespaceContext getCurrentDefinedNamespaces() { MapPrefixResolver prefixMapping = new MapPrefixResolver(); String prefix; Element elem = currentElement; NamedNodeMap attrs; int len; Attr a; String attrName; int attrNameLen; Node parent; while (elem != null) { // add any namespace definitions attrs = elem.getAttributes(); len = (attrs == null) ? 0 : attrs.getLength(); for (int i = 0; i < len; i++) { a = (Attr) attrs.item(i); attrName = a.getName(); if (attrName.startsWith("xmlns")) { attrNameLen = attrName.length(); if (attrNameLen == 5) prefix = ""; else if ((attrNameLen > 6) && (attrName.charAt(5) == ':')) prefix = attrName.substring(6); else prefix = null; if (prefix != null) prefixMapping.addPrefixMapping(prefix, a.getValue()); } } parent = elem.getParentNode(); if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) elem = (Element) parent; else elem = null; } return prefixMapping; } @Override public XMLSerializable parseElement(String uri, String localName) throws XMLParseException { XMLSerializable child = getFactory().createObject(uri, localName, this); delegateParsingTo(child); return child; } public String getElementText() { if (currentElement == null) throw new IllegalStateException("No characters available"); String text = null; NodeList childNodes = currentElement.getChildNodes(); int len = childNodes.getLength(); Node child; String nodeText; for (int i = 0; i < len; i++) { child = childNodes.item(i); if (child.getNodeType() == Node.TEXT_NODE) { nodeText = ((Text) child).getData(); if (text == null) text = nodeText; else text += nodeText; } } return text; } // --------------------------------- Exception management ----------------------------------- @Override protected void addLocationInfo(XMLParseException xpe) { if (currentElement != null) { xpe.setSource(getSourceDescription()); } } public String getSourceDescription() { StringBuffer sb = new StringBuffer("DOM Document"); Document doc = (currentElement == null) ? null : currentElement.getOwnerDocument(); DocumentType docType = (doc == null) ? null : doc.getDoctype(); if (docType != null) sb.append(docType.getPublicId()); return sb.toString(); } // ------------------------- Attributes management ------------------------------------------- public String getAttributeValue(String attrName) throws XMLParseException { return getAttributeValueNS(null, attrName); } public String getAttributeValueNS(String attrNamespaceURI, String attrName) throws XMLParseException { if (currentElement == null) throw new XMLParseException( "getAttributeValue(..) can only be called from startElement(..) method"); Attr attrib = (attrNamespaceURI == null) ? currentElement.getAttributeNode(attrName) : currentElement.getAttributeNodeNS( attrNamespaceURI, attrName); return (attrib == null) ? null : attrib.getValue(); } public Iterator getAttributeNamespaceIterator() throws XMLParseException { if (currentElement == null) throw new XMLParseException( "getAttributeNameIterator(..) can only be called from startElement(..) method"); List uris = new ArrayList(); NamedNodeMap attrMap = currentElement.getAttributes(); int len = attrMap.getLength(); for (int i = 0; i < len; i++) { Node n = attrMap.item(i); String uri = n.getNamespaceURI(); if (!uris.contains(uri)) uris.add(uri); } return uris.iterator(); } public Iterator getAttributeNameIterator(String attrNamespaceURI) throws XMLParseException { if (currentElement == null) throw new XMLParseException( "getAttributeNameIterator(..) can only be called from startElement(..) method"); NamedNodeMap attrMap = currentElement.getAttributes(); return new AttributeNameIterator(attrNamespaceURI, attrMap); } // -------------------- Inner Attribute Name Iterator implementation ------------------------------------------- /** * Iterator on the attribute names of a DOM element. */ static class AttributeNameIterator implements Iterator { private String namespaceURI; private NamedNodeMap attrMap; private int nbrAttr; private int index; AttributeNameIterator(String uri, NamedNodeMap attrs) { namespaceURI = uri; attrMap = attrs; index = 0; nbrAttr = (attrMap == null) ? 0 : attrMap.getLength(); checkNextAttibuteNamespace(); } private void checkNextAttibuteNamespace() { boolean namespaceOK; while (index < nbrAttr) { Attr attribute = (Attr) attrMap.item(index); if (namespaceURI == null) namespaceOK = (attribute.getNamespaceURI() == null); else namespaceOK = namespaceURI.equals(attribute.getNamespaceURI()); if (namespaceOK) break; else index++; } } public boolean hasNext() { return index < nbrAttr; } public String next() { Attr attribute = (Attr) attrMap.item(index); String name = attribute.getLocalName(); index++; checkNextAttibuteNamespace(); return name; } public void remove() { throw new UnsupportedOperationException("Cannot remove attribute"); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy