Skip to content
Snippets Groups Projects
DOMBuilderImpl.cpp 16.2 KiB
Newer Older
/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
*  This file contains code to build the DOM tree. It registers a document
*  handler with the scanner. In these handler methods, appropriate DOM nodes
*  are created and added to the DOM tree.
*
* $Id$
*
*/



// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/parsers/DOMBuilderImpl.hpp>
#include <xercesc/util/IOException.hpp>
#include <xercesc/dom/DOMEntityResolver.hpp>
#include <xercesc/dom/DOMErrorHandler.hpp>
#include <xercesc/dom/impl/DOMErrorImpl.hpp>
#include <xercesc/dom/impl/DOMLocatorImpl.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/internal/XMLScanner.hpp>
#include <xercesc/util/DOMInputSourceWrapper.hpp>


// ---------------------------------------------------------------------------
//  DOMBuilderImpl: Constructors and Destructor
// ---------------------------------------------------------------------------
DOMBuilderImpl::DOMBuilderImpl(XMLValidator* const valToAdopt) :

AbstractDOMParser(valToAdopt)
, fAutoValidation(false)
, fValidation(false)
, fErrorHandler(0)
, fEntityResolver(0)
, fFilter(0)
, fReuseGrammar(false)
, fCharsetOverridesXMLEncoding(true)
{
}


DOMBuilderImpl::~DOMBuilderImpl()
{
}


// ---------------------------------------------------------------------------
//  DOMBuilderImpl: Setter methods
// ---------------------------------------------------------------------------
void DOMBuilderImpl::setErrorHandler(DOMErrorHandler* const handler)
{
    fErrorHandler = handler;
    if (fErrorHandler) {
        getScanner()->setErrorReporter(this);
    }
    else {
        getScanner()->setErrorReporter(0);
    }
}

void DOMBuilderImpl::setEntityResolver(DOMEntityResolver* const handler)
{
    fEntityResolver = handler;
    if (fEntityResolver) {
        getScanner()->setEntityHandler(this);
    }
    else {
        getScanner()->setEntityHandler(0);
    }
}

void DOMBuilderImpl::setFilter(DOMBuilderFilter* const filter)
{
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);
}


// ---------------------------------------------------------------------------
//  DOMBuilderImpl: Feature methods
// ---------------------------------------------------------------------------
void DOMBuilderImpl::setFeature(const XMLCh* const name, const bool state)
{
    if (XMLString::compareIString(name, XMLUni::fgDOMEntities) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMComments) == 0) {
        setCreateCommentNodes(state);
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMDatatypeNormalization) == 0) {
        getScanner()->setNormalizeData(state);
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMNamespaces) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMWhitespaceInElementContent) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMValidation) == 0) {

        fValidation = state;

        if (state) {
            if (getValidationScheme() == AbstractDOMParser::Val_Never)
                setValidationScheme(AbstractDOMParser::Val_Always);
        }
        else {
            setValidationScheme(AbstractDOMParser::Val_Never);
        }
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMValidateIfSchema) == 0) {

        fAutoValidation = state;

        if (state) {
            setValidationScheme(AbstractDOMParser::Val_Auto);
        }
        else {
            setValidationScheme(AbstractDOMParser::Val_Never);
        }
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMCharsetOverridesXMLEncoding) == 0) {
        // in fact, setting this has no effect to the parser
        fCharsetOverridesXMLEncoding = state;
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMSupportedMediatypesOnly) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMInfoset) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMCanonicalForm) == 0 ) {
        if (state)
            throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMNamespaceDeclarations) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMCDATASections) == 0 ) {
        if (!state)
            throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);
    }
    else if (XMLString::compareIString(name, XMLUni::fgXercesReuseGrammar) == 0)
    {
        fReuseGrammar = state;
    }
    else if (XMLString::compareIString(name, XMLUni::fgXercesSchema) == 0)
    {
    	  setDoSchema(state);
    }

    else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaFullChecking) == 0)
    {
    	  setValidationSchemaFullChecking(state);
    }

    else if (XMLString::compareIString(name, XMLUni::fgXercesLoadExternalDTD) == 0)
    {
    	  setLoadExternalDTD(state);
    }

    else if (XMLString::compareIString(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
    {
         setExitOnFirstFatalError(!state);
    }
    else if (XMLString::compareIString(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)
    {
         setValidationConstraintFatal(state);
    }
        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
    }
}

bool DOMBuilderImpl::getFeature(const XMLCh* const name)
{
    if (XMLString::compareIString(name, XMLUni::fgDOMEntities) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMComments) == 0) {
        return getCreateCommentNodes();
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMDatatypeNormalization) == 0) {
        return getScanner()->getNormalizeData();
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMNamespaces) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMWhitespaceInElementContent) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMValidation) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMValidateIfSchema) == 0) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMCharsetOverridesXMLEncoding) == 0) {
        return fCharsetOverridesXMLEncoding;
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMSupportedMediatypesOnly) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMInfoset) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMCanonicalForm) == 0 ) {
        return false;
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMNamespaceDeclarations) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMCDATASections) == 0 ) {
        return true;
    }
    else if (XMLString::compareIString(name, XMLUni::fgXercesReuseGrammar) == 0)
    {
        return fReuseGrammar;
    }
    else if (XMLString::compareIString(name, XMLUni::fgXercesSchema) == 0)
    {
    	  return getDoSchema();
    }

    else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaFullChecking) == 0)
    {
    	  return getValidationSchemaFullChecking();
    }

    else if (XMLString::compareIString(name, XMLUni::fgXercesLoadExternalDTD) == 0)
    {
    	  return getLoadExternalDTD();
    }

    else if (XMLString::compareIString(name, XMLUni::fgXercesContinueAfterFatalError) == 0)
    {
         return !getExitOnFirstFatalError();
    }
    else if (XMLString::compareIString(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)
    {
         return getValidationConstraintFatal();
    }
        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
    }

    return false;
}

bool DOMBuilderImpl::canSetFeature(const XMLCh* const name, const bool state)
{
    if ((XMLString::compareIString(name, XMLUni::fgDOMEntities) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMComments) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMDatatypeNormalization) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMNamespaces) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMValidation) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMValidateIfSchema) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMCharsetOverridesXMLEncoding) == 0) ||
        (XMLString::compareIString(name, XMLUni::fgDOMWhitespaceInElementContent) == 0)) {
    else if (XMLString::compareIString(name, XMLUni::fgDOMSupportedMediatypesOnly) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMInfoset) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMCanonicalForm) == 0 ) {
        if (!state)
            return true;
    }
    else if (XMLString::compareIString(name, XMLUni::fgDOMNamespaceDeclarations) == 0 ||
             XMLString::compareIString(name, XMLUni::fgDOMCDATASections) == 0 ) {
        if (state)
            return true;
    }
    else if ((XMLString::compareIString(name, XMLUni::fgXercesReuseGrammar) == 0) ||
             (XMLString::compareIString(name, XMLUni::fgXercesSchema) == 0) ||
             (XMLString::compareIString(name, XMLUni::fgXercesSchemaFullChecking) == 0) ||
             (XMLString::compareIString(name, XMLUni::fgXercesLoadExternalDTD) == 0) ||
             (XMLString::compareIString(name, XMLUni::fgXercesContinueAfterFatalError) == 0) ||
             (XMLString::compareIString(name, XMLUni::fgXercesValidationErrorAsFatal) == 0)) {
        return true;
    }
void DOMBuilderImpl::setProperty(const XMLCh* const name, void* value)
{
	if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalSchemaLocation) == 0)
	{
		setExternalSchemaLocation((XMLCh*)value);
	}

	else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation) == 0)
	{
		setExternalNoNamespaceSchemaLocation((XMLCh*)value);
	}

   else
      throw DOMException(DOMException::NOT_FOUND_ERR, 0);
}


void* DOMBuilderImpl::getProperty(const XMLCh* const name) const
{
    if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalSchemaLocation) == 0)
        return (void*)getExternalSchemaLocation();
    else if (XMLString::compareIString(name, XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation) == 0)
        return (void*)getExternalNoNamespaceSchemaLocation();
    else
        throw DOMException(DOMException::NOT_FOUND_ERR, 0);
// ---------------------------------------------------------------------------
//  DOMBuilderImpl: Parsing methods
// ---------------------------------------------------------------------------
DOMDocument* DOMBuilderImpl::parse(const DOMInputSource& source)
{
    DOMInputSourceWrapper isWrapper((DOMInputSource*) &source);

    isWrapper.setAdoptInputSource(false);
    AbstractDOMParser::parse(isWrapper, fReuseGrammar);
DOMDocument* DOMBuilderImpl::parseURI(const XMLCh* const systemId)
    AbstractDOMParser::parse(systemId, fReuseGrammar);
DOMDocument* DOMBuilderImpl::parseURI(const char* const systemId)
    AbstractDOMParser::parse(systemId, fReuseGrammar);
    return getDocument();
}

void DOMBuilderImpl::parseWithContext(const DOMInputSource& source,
                                      DOMNode* const contextNode,
                                      const short action)
{
    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0);
}


// ---------------------------------------------------------------------------
//  DOMBuilderImpl: Implementation of the XMLErrorReporter interface
// ---------------------------------------------------------------------------
void DOMBuilderImpl::error( const   unsigned int                code
                            , const XMLCh* const                msgDomain
                            , const XMLErrorReporter::ErrTypes  errType
                            , const XMLCh* const                errorText
                            , const XMLCh* const                systemId
                            , const XMLCh* const                publicId
                            , const XMLSSize_t                  lineNum
                            , const XMLSSize_t                  colNum)
{
    if (fErrorHandler) {

        short severity = DOMError::DOM_SEVERITY_ERROR;

        if (errType == XMLErrorReporter::ErrType_Warning)
            severity = DOMError::DOM_SEVERITY_WARNING;
        else if (errType == XMLErrorReporter::ErrType_Fatal)
            severity = DOMError::DOM_SEVERITY_FATAL_ERROR;

        DOMLocatorImpl location((int)lineNum, (int) colNum, getCurrentNode(), systemId);
        DOMErrorImpl domError(severity, errorText, &location);

        fErrorHandler->handleError(domError);
    }
}

void DOMBuilderImpl::resetErrors()
{
}


// ---------------------------------------------------------------------------
//  DOMBuilderImpl: Implementation of XMLEntityHandler interface
// ---------------------------------------------------------------------------
InputSource*
DOMBuilderImpl::resolveEntity(const XMLCh* const publicId,
                              const XMLCh* const systemId,
                              const XMLCh* const baseURI)
{
    //
    //  Just map it to the SAX entity resolver. If there is not one installed,
    //  return a null pointer to cause the default resolution.
    //
    if (fEntityResolver) {

        DOMInputSource* is = fEntityResolver->resolveEntity(publicId, systemId, baseURI);

        if (is)
            return new DOMInputSourceWrapper(is);
    }

    return 0;
}