Package org.exist.memtree

Source Code of org.exist.memtree.DocumentBuilderReceiver

/*
*  eXist Open Source Native XML Database
*  Copyright (C) 2001-10 The eXist-db project
*  wolfgang@exist-db.org
*  http://exist.sourceforge.net
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*  $Id$
*/
package org.exist.memtree;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;

import org.exist.dom.NodeProxy;
import org.exist.dom.QName;
import org.exist.dom.StoredNode;
import org.exist.util.serializer.AttrList;
import org.exist.util.serializer.Receiver;
import org.exist.xquery.XQueryContext;

import java.util.HashMap;
import java.util.Map;


/**
* Builds an in-memory DOM tree from SAX {@link org.exist.util.serializer.Receiver} events.
*
* @author  Wolfgang <wolfgang@exist-db.org>
*/
public class DocumentBuilderReceiver implements ContentHandler, LexicalHandler, Receiver {

    private MemTreeBuilder builder = null;

    private Map<String, String> namespaces = null;
    private boolean explicitNSDecl = false;
   
    public boolean checkNS = false;
   
    public DocumentBuilderReceiver() {
        super();
    }

    public DocumentBuilderReceiver(MemTreeBuilder builder) {
        this(builder, false);
    }

    public DocumentBuilderReceiver(MemTreeBuilder builder, boolean declareNamespaces) {
        super();
        this.builder        = builder;
        this.explicitNSDecl = declareNamespaces;
    }

    @Override
    public Document getDocument() {
        return builder.getDocument();
    }

    public XQueryContext getContext() {
        return builder.getContext();
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
     */
    @Override
    public void setDocumentLocator(Locator locator) {
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#startDocument()
     */
    @Override
    public void startDocument() throws SAXException {
        if(builder == null) {
            builder = new MemTreeBuilder();
            builder.startDocument();
        }
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#endDocument()
     */
    @Override
    public void endDocument() throws SAXException {
        builder.endDocument();
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
     */
    @Override
    public void startPrefixMapping(String prefix, String namespaceURI) throws SAXException {
        if(prefix == null || prefix.length() == 0) {
            builder.setDefaultNamespace(namespaceURI);
        }
        if (!explicitNSDecl) {
            return;
        }
        if(namespaces == null) {
            namespaces = new HashMap<String, String>();
        }
        namespaces.put(prefix, namespaceURI);
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
     */
    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
        if(prefix == null || prefix.length() == 0) {
            builder.setDefaultNamespace("");
        }
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
     */
    @Override
    public void startElement(String namespaceURI, String localName, String qName,
            Attributes attrs) throws SAXException {
        builder.startElement(namespaceURI, localName, qName, attrs);
        declareNamespaces();
    }

    private void declareNamespaces() {
        if (explicitNSDecl && namespaces != null) {
            for(final Map.Entry<String, String> entry : namespaces.entrySet()) {
                builder.namespaceNode(entry.getKey(), entry.getValue());
            }
            namespaces.clear();
        }
    }

    @Override
    public void startElement(QName qname, AttrList attribs) {
        qname = checkNS(true, qname);
        builder.startElement(qname, null);
        declareNamespaces();
        if (attribs != null) {
            for (int i = 0; i < attribs.getLength(); i++) {
                builder.addAttribute( attribs.getQName(i), attribs.getValue(i));
            }
        }
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
        builder.endElement();
    }

    @Override
    public void endElement(QName qname) throws SAXException {
        builder.endElement();
    }

    public void addReferenceNode(NodeProxy proxy) throws SAXException {
        builder.addReferenceNode(proxy);
    }

    public void addNamespaceNode(QName qname) throws SAXException {
        builder.namespaceNode(qname);
    }

    @Override
    public void characters(CharSequence seq) throws SAXException {
        builder.characters(seq);
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
     */
    @Override
    public void characters(char[] ch, int start, int len) throws SAXException {
        builder.characters(ch, start, len);
    }

    @Override
    public void attribute(QName qname, String value) throws SAXException {
        try {
            qname = checkNS(false, qname);
            builder.addAttribute(qname, value);
        } catch(final DOMException e) {
            throw new SAXException(e.getMessage());
        }
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
     */
    @Override
    public void ignorableWhitespace(char[] ch, int start, int len) throws SAXException {
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
     */
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        builder.processingInstruction(target, data);
    }

    /* (non-Javadoc)
     * @see org.exist.util.serializer.Receiver#cdataSection(char[], int, int)
     */
    @Override
    public void cdataSection(char[] ch, int start, int len) throws SAXException {
        builder.cdataSection(new String(ch, start, len));
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
     */
    @Override
    public void skippedEntity(String arg0) throws SAXException {
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#endCDATA()
     */
    @Override
    public void endCDATA() throws SAXException {
        // TODO ignored
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#endDTD()
     */
    @Override
    public void endDTD() throws SAXException {
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#startCDATA()
     */
    @Override
    public void startCDATA() throws SAXException {
        // TODO Ignored
    }

    @Override
    public void documentType(String name, String publicId, String systemId) throws SAXException {
        builder.documentType(name, publicId, systemId);
    }
   
    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
     */
    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {
        builder.comment(ch, start, length);
    }
   
    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
     */
    @Override
    public void endEntity(String name) throws SAXException{
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
     */
    @Override
    public void startEntity(String name) throws SAXException {
    }

    /* (non-Javadoc)
     * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void startDTD(String name, String publicId, String systemId) throws SAXException {
    }

    @Override
    public void highlightText(CharSequence seq) {
        // not supported with this receiver
    }

    @Override
    public void setCurrentNode(StoredNode node) {
        // ignored
    }
   
    public QName checkNS(boolean isElement, QName qname) {
        if(checkNS) {
            final XQueryContext context = builder.getContext();
            if(qname.getPrefix() == null) {
              if (qname.getNamespaceURI() == null || qname.getNamespaceURI().isEmpty()) {
                return qname;
             
              } else if (isElement) {
                  return qname;

              } else {
                  final String prefix = generatePrfix(context, context.getInScopePrefix(qname.getNamespaceURI()));

                  context.declareInScopeNamespace(prefix, qname.getNamespaceURI());
                  qname.setPrefix(prefix);
                  return qname;
              }
            }
          if(qname.getPrefix().isEmpty() && qname.getNamespaceURI() == null)
                {return qname;}

            final String inScopeNamespace = context.getInScopeNamespace(qname.getPrefix());
            if(inScopeNamespace == null) {
                context.declareInScopeNamespace(qname.getPrefix(), qname.getNamespaceURI());
               
            } else if(!inScopeNamespace.equals(qname.getNamespaceURI())) {
               
                final String prefix = generatePrfix(context, context.getInScopePrefix(qname.getNamespaceURI()));

                context.declareInScopeNamespace(prefix, qname.getNamespaceURI());
                qname.setPrefix(prefix);
            }
        }
        return qname;
    }
   
    private String generatePrfix(XQueryContext context, String prefix) {
        int i = 0;
        while (prefix == null) {
            prefix = "XXX";
            if(i > 0) {
                prefix += String.valueOf(i);
            }
            if(context.getInScopeNamespace(prefix) != null) {
                prefix = null;
                i++;
            }
        }
        return prefix;
    }
}
TOP

Related Classes of org.exist.memtree.DocumentBuilderReceiver

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.