Logo Search packages:      
Sourcecode: xalan version File versions  Download package

XercesDocumentWrapper.cpp

/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.
 */
#include "XercesDocumentWrapper.hpp"



#include <algorithm>
#include <cassert>



#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMCDATASection.hpp>
#include <xercesc/dom/DOMComment.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMEntity.hpp>
#include <xercesc/dom/DOMEntityReference.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>
#include <xercesc/dom/DOMNotation.hpp>
#include <xercesc/dom/DOMProcessingInstruction.hpp>
#include <xercesc/dom/DOMText.hpp>



#include <xalanc/Include/STLHelper.hpp>



#include <xalanc/DOMSupport/DOMServices.hpp>



#include <xalanc/XalanDOM/XalanDocumentType.hpp>
#include <xalanc/XalanDOM/XalanElement.hpp>



#include "XercesAttrWrapper.hpp"
#include "XercesWrapperHelper.hpp"
#include "XercesCommentWrapper.hpp"
#include "XercesCDATASectionWrapper.hpp"
#include "XercesDOMWrapperException.hpp"
#include "XercesDOMImplementationWrapper.hpp"
#include "XercesDocumentTypeWrapper.hpp"
#include "XercesElementWrapper.hpp"
#include "XercesEntityWrapper.hpp"
#include "XercesEntityReferenceWrapper.hpp"
#include "XercesLiaisonXalanDOMStringPool.hpp"
#include "XercesNodeListWrapper.hpp"
#include "XercesNotationWrapper.hpp"
#include "XercesProcessingInstructionWrapper.hpp"
#include "XercesTextWrapper.hpp"



XALAN_CPP_NAMESPACE_BEGIN



XercesDocumentWrapper::XercesDocumentWrapper(
            MemoryManagerType&          theManager,
                  const DOMDocument_Type*       theXercesDocument,
                  bool                                threadSafe,
                  bool                                buildWrapper,
                  bool                                buildMaps) :
      XalanDocument(),
      m_xercesDocument(theXercesDocument),
      m_documentElement(0),
      m_nodeMap(theManager),
    m_domImplementation(theManager, XercesDOMImplementationWrapper::create(theManager, theXercesDocument->getImplementation())),
      m_navigatorAllocator(theManager, 25),
      m_navigator(0),
      m_children(theXercesDocument->getChildNodes(),
                     *m_navigator),
      m_nodes(theManager),
      m_doctype(0),
      m_mappingMode(threadSafe == true ? false : !buildWrapper),
      m_indexValid(false),
      m_buildMaps(m_mappingMode == true ? true : buildMaps),
      m_elementAllocator(theManager, 25),
      m_textAllocator(theManager, 25),
      m_attributeAllocator(theManager, 25),
    m_stringPool(theManager, threadSafe == true ? XercesLiaisonXalanDOMStringPool::create(theManager) : XalanDOMStringPool::create(theManager))
{
      assert(theXercesDocument != 0);

    m_navigator = m_navigatorAllocator.create(this);

      if (m_mappingMode == false)
      {
            // The document index is always 1...
            m_navigator->setIndex(1);

            // OK, let's build the nodes.  This makes things
            // thread-safe, so the document can be shared...
            buildWrapperNodes();
      }
      else
      {
            m_nodeMap.addAssociation(theXercesDocument, this);
      }
}

XercesDocumentWrapper*
XercesDocumentWrapper::create( 
            MemoryManagerType&          theManager,
                  const DOMDocument_Type*       theXercesDocument,
                  bool                                threadSafe,
                  bool                                buildWrapper,
                  bool                                buildMaps)
{
    typedef XercesDocumentWrapper ThisType;

    XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType)));

    ThisType* theResult = theGuard.get();

    new (theResult) ThisType(theManager,
                            theXercesDocument,
                            threadSafe,
                            buildWrapper,
                            buildMaps);
        
    theGuard.release();

    return theResult;
}

XercesDocumentWrapper::~XercesDocumentWrapper()
{
      destroyWrapper();
}



XalanNode*
XercesDocumentWrapper::mapNode(const DOMNodeType*     theXercesNode) const
{
      XalanNode*  theXalanNode = 0;

      if (theXercesNode != 0)
      {
            theXalanNode = m_nodeMap.getNode(theXercesNode);

            if (theXalanNode == 0)
            {
                  if (theXercesNode != m_xercesDocument &&
                              theXercesNode->getOwnerDocument() != m_xercesDocument &&
#if defined(XALAN_OLD_STYLE_CASTS)
                        theXercesNode->getParentNode() != (const DOMNodeType*)m_xercesDocument)
#else
                        theXercesNode->getParentNode() != static_cast<const DOMNodeType*>(m_xercesDocument))
#endif
                  {
                        throw XercesDOMWrapperException(XercesDOMWrapperException::WRONG_DOCUMENT_ERR);
                  }
                  else if (m_mappingMode == true)
                  {
                        // OK, we haven't yet created a wrapper, so go ahead and
                        // create one.
                        theXalanNode = createWrapperNode(theXercesNode, 0, true);
                        assert(theXalanNode != 0);
                  }
            }
      }

      return theXalanNode;
}



const DOMNodeType*
XercesDocumentWrapper::mapNode(XalanNode* theXalanNode) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
      if ((const XalanNode*)this == theXalanNode)
#else
      if (static_cast<const XalanNode*>(this) == theXalanNode)
#endif
      {
            return m_xercesDocument;
      }
      else if (theXalanNode == 0 ||
#if defined(XALAN_OLD_STYLE_CASTS)
            (const XalanDocument*)this != theXalanNode->getOwnerDocument())
#else
            static_cast<const XalanDocument*>(this) != theXalanNode->getOwnerDocument())
#endif
      {
            throw XercesDOMWrapperException(XercesDOMWrapperException::WRONG_DOCUMENT_ERR);
      }
      else
      {
            switch(theXalanNode->getNodeType())
            {
            case XalanNode::ATTRIBUTE_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesAttrWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesAttrWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::CDATA_SECTION_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesCDATASectionWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesCDATASectionWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::COMMENT_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesCommentWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesCommentWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::DOCUMENT_FRAGMENT_NODE:
                  throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);
                  break;

            case XalanNode::ELEMENT_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesElementWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesElementWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::ENTITY_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesEntityWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesEntityWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::ENTITY_REFERENCE_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesEntityReferenceWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesEntityReferenceWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::NOTATION_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesNotationWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesNotationWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::PROCESSING_INSTRUCTION_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesProcessingInstructionWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesProcessingInstructionWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::TEXT_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesTextWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesTextWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            case XalanNode::DOCUMENT_TYPE_NODE:
#if defined(XALAN_OLD_STYLE_CASTS)
                  return ((const XercesDocumentTypeWrapper*)theXalanNode)->getXercesNode();
#else
                  return static_cast<const XercesDocumentTypeWrapper*>(theXalanNode)->getXercesNode();
#endif
                  break;

            default:
                  assert(false);
                  break;
            }

            return 0;
      }
}



XalanAttr*
XercesDocumentWrapper::mapNode(const DOMAttrType*     theXercesNode) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
      return (XalanAttr*)mapNode((const DOMNodeType*)theXercesNode);
#else
      return static_cast<XalanAttr*>(mapNode(static_cast<const DOMNodeType*>(theXercesNode)));
#endif
}



XalanElement*
XercesDocumentWrapper::mapNode(const DOMElementType*  theXercesNode) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
      return (XercesElementWrapper*)mapNode((const DOMNodeType*)theXercesNode);
#else
      return static_cast<XercesElementWrapper*>(mapNode(static_cast<const DOMNodeType*>(theXercesNode)));
#endif
}



void
XercesDocumentWrapper::destroyWrapper()
{
      XALAN_USING_STD(for_each)

      // Set this to null, since it will be deleted
      // by the next for_each...
      m_doctype = 0;

      // m_bridgeMap contains all of the nodes that
      // are still alive...
      for_each(
                  m_nodes.begin(),
                  m_nodes.end(),
            DeleteFunctor<XalanNode>(m_nodes.getMemoryManager()));

      // Clear everything out, since we just delete everything...
      m_nodes.clear();

      // Clear out all of the navigators, except ours...
      m_navigatorAllocator.reset();

      m_navigator = m_navigatorAllocator.create(this);

      // Clear the node map...
      m_nodeMap.clear();

      m_indexValid = false;

      m_mappingMode = true;

      m_stringPool->clear();
}



void
XercesDocumentWrapper::rebuildWrapper()
{
      destroyWrapper();

      buildWrapperNodes();
}



XercesWrapperNavigator&
XercesDocumentWrapper::createNavigator() const
{
      XercesDocumentWrapper* const        This =
#if defined(XALAN_OLD_STYLE_CASTS)
            (XercesDocumentWrapper*)this;
#else
            const_cast<XercesDocumentWrapper*>(this);
#endif

      return *This->m_navigatorAllocator.create(This);
}



XercesDocumentTypeWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMDocumentType_Type*         theDoctype,
                  IndexType                                 theIndex,
                  bool                                      mapNode,
            XercesWrapperNavigator**        theWrapperNodeNavigator) const
{
      // This is a special case, since there is only one
      // doctype node allowed...
      assert(m_doctype == 0);
      assert(m_xercesDocument->getDoctype() != 0 &&
               m_xercesDocument->getDoctype() == theDoctype);

      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      // Update the member variable for the new instance.
    This->m_doctype =  XercesDocumentTypeWrapper::create( getMemoryManager(), theDoctype, theNavigator);

      if (mapNode == true)
      {
            This->m_nodeMap.addAssociation(theDoctype, m_doctype);
      }

      This->m_nodes.push_back(m_doctype);

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return m_doctype;
}



XercesElementWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMElementType*       theXercesNode,
                  IndexType                         theIndex,
                  bool                              mapNode,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      XercesElementWrapper* const   theWrapper =
            This->m_elementAllocator.create(theXercesNode,
                                                            theNavigator);

      if (m_doctype != 0 || mapNode == true)
      {
            // Add it to the node map, since we my need it for getting
            // elements by ID, or we're in mapping mode.
            This->m_nodeMap.addAssociation(theXercesNode, theWrapper);
      }

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesTextWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMTextType*              theXercesNode,
                  IndexType                       theIndex,
                  bool                            mapNode,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      XercesTextWrapper* const            theWrapper =
            This->m_textAllocator.create(theXercesNode,
                                                       theNavigator);

      if (mapNode == true)
      {
            // Add it to the node map...
            This->m_nodeMap.addAssociation(theXercesNode, theWrapper);
      }

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesCommentWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMCommentType*       theXercesNode,
                  IndexType                         theIndex,
                  bool                              mapNode,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

      XercesCommentWrapper* const   theWrapper =
        XercesCommentWrapper::create(
                                getMemoryManager(),
                                theXercesNode,
                                                theNavigator);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      This->m_nodes.push_back(theWrapper);

      if (mapNode == true)
      {
            // Add it to the node map...
            This->m_nodeMap.addAssociation(theXercesNode, theWrapper);
      }

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesCDATASectionWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMCDATASectionType*    theXercesNode,
                  IndexType                           theIndex,
                  bool                                mapNode,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

      XercesCDATASectionWrapper* const          theWrapper =
        XercesCDATASectionWrapper::create(
                                     getMemoryManager(),
                                     theXercesNode,
                                                       theNavigator);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      This->m_nodes.push_back(theWrapper);

      if (mapNode == true)
      {
            // Add it to the node map...
            This->m_nodeMap.addAssociation(theXercesNode, theWrapper);
      }

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesProcessingInstructionWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMProcessingInstructionType*       theXercesNode,
                  IndexType                                             theIndex,
                  bool                                                  mapNode,
            XercesWrapperNavigator**                theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

      XercesProcessingInstructionWrapper* const theWrapper =
        XercesProcessingInstructionWrapper::create(
                                              getMemoryManager(),
                                              theXercesNode,
                                                                    theNavigator);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      This->m_nodes.push_back(theWrapper);

      if (mapNode == true)
      {
            // Add it to the node map...
            This->m_nodeMap.addAssociation(theXercesNode, theWrapper);
      }

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesAttrWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMAttrType*              theXercesNode,
                  IndexType                       theIndex,
                  bool                            /* mapNode */,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      XercesAttrWrapper* const            theWrapper =
            This->m_attributeAllocator.create(theXercesNode,
                                                              theNavigator);

      // Add it to the node map -- attributes ALWAYS go in the map
      // for now...
      This->m_nodeMap.addAssociation(theXercesNode, theWrapper);

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesEntityWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMEntityType*        theXercesNode,
                  IndexType                         theIndex,
                  bool                              /* mapNode */,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

      XercesEntityWrapper* const    theWrapper =
        XercesEntityWrapper::create(
                               getMemoryManager(),
                               theXercesNode,
                                             theNavigator);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      This->m_nodes.push_back(theWrapper);

      // Add it to the node map -- entities ALWAYS go in the map
      // for now...
      This->m_nodeMap.addAssociation(theXercesNode, theWrapper);

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesEntityReferenceWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMEntityReferenceType*       theXercesNode,
                  IndexType                                 theIndex,
                  bool                                      mapNode,
            XercesWrapperNavigator**        theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

      XercesEntityReferenceWrapper* const theWrapper =
        XercesEntityReferenceWrapper::create(
                                        getMemoryManager(),
                                        theXercesNode,
                                                            theNavigator);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      This->m_nodes.push_back(theWrapper);

      if (mapNode == true)
      {
            // Add it to the node map...
            This->m_nodeMap.addAssociation(theXercesNode, theWrapper);
      }

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XercesNotationWrapper*
XercesDocumentWrapper::createWrapperNode(
                  const DOMNotationType*      theXercesNode,
                  IndexType                         theIndex,
                  bool                              /* mapNode */,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      // Create a navigator...
      XercesWrapperNavigator& theNavigator = createNavigator();

      theNavigator.setIndex(theIndex);

      XercesNotationWrapper* const        theWrapper =
        XercesNotationWrapper::create(
                                 getMemoryManager(),
                                 theXercesNode,
                                                 theNavigator);

#if defined(XALAN_NO_MUTABLE)
      XercesDocumentWrapper* const        This =
            (XercesDocumentWrapper*)this;
#else
      const XercesDocumentWrapper* const  This =
            this;
#endif

      This->m_nodes.push_back(theWrapper);

      // Add it to the node map -- notations ALWAYS go in the map
      // for now...
      This->m_nodeMap.addAssociation(theXercesNode, theWrapper);

    if (theWrapperNodeNavigator != 0)
    {
        *theWrapperNodeNavigator = &theNavigator;
    }

      return theWrapper;
}



XalanNode*
XercesDocumentWrapper::createWrapperNode(
                  const DOMNodeType*              theXercesNode,
                  IndexType                       theIndex,
                  bool                            mapNode,
            XercesWrapperNavigator**    theWrapperNodeNavigator) const
{
      assert(theXercesNode != 0);

      XalanNode*                    theNewNode = 0;

      switch(theXercesNode->getNodeType())
      {
      case DOMNodeType::ATTRIBUTE_NODE:
            {
                  const DOMAttrType*            theAttrNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMAttrType*)theXercesNode;
#else
                                    static_cast<const DOMAttrType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theAttrNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::CDATA_SECTION_NODE:
            {
                  const DOMCDATASectionType*    theCDATASectionNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMCDATASectionType*)theXercesNode;
#else
                                    static_cast<const DOMCDATASectionType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theCDATASectionNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);

            }
            break;

      case DOMNodeType::COMMENT_NODE:
            {
                  const DOMCommentType*   theCommentNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMCommentType*)theXercesNode;
#else
                                    static_cast<const DOMCommentType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theCommentNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::DOCUMENT_FRAGMENT_NODE:
            throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);
            break;

      case DOMNodeType::ELEMENT_NODE:
            {
                  const DOMElementType*   theElementNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMElementType*)theXercesNode;
#else
                                    static_cast<const DOMElementType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theElementNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::ENTITY_NODE:
            {
                  const DOMEntityType*    theEntityNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMEntityType*)theXercesNode;
#else
                                    static_cast<const DOMEntityType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theEntityNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::ENTITY_REFERENCE_NODE:
            {
                  const DOMEntityReferenceType* theEntityReferenceNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMEntityReferenceType*)theXercesNode;
#else
                                    static_cast<const DOMEntityReferenceType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theEntityReferenceNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::NOTATION_NODE:
            {
                  const DOMNotationType*  theNotationNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMNotationType*)theXercesNode;
#else
                                    static_cast<const DOMNotationType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theNotationNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::PROCESSING_INSTRUCTION_NODE:
            {
                  const DOMProcessingInstructionType*       thePINode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMProcessingInstructionType*)theXercesNode;
#else
                                    static_cast<const DOMProcessingInstructionType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(thePINode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::TEXT_NODE:
            {
                  const DOMTextType*      theTextNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMTextType*)theXercesNode;
#else
                                    static_cast<const DOMTextType*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theTextNode, theIndex, mapNode, theWrapperNodeNavigator);
                  assert(theNewNode != 0);
            }
            break;

      case DOMNodeType::DOCUMENT_TYPE_NODE:
            {
                  const DOMDocumentType_Type*         theDoctypeNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOMDocumentType_Type*)theXercesNode;
#else
                                    static_cast<const DOMDocumentType_Type*>(theXercesNode);
#endif

                  theNewNode = createWrapperNode(theDoctypeNode, theIndex, mapNode, theWrapperNodeNavigator);

                  assert(theNewNode != 0);
            }
            break;

      default:
            assert(false);
            break;
      }

      return theNewNode;
}



void
XercesDocumentWrapper::destroyNode(XalanNode*   theNode)
{
      XALAN_USING_STD(find)

      const NodeVectorType::iterator      i =
            find(m_nodes.begin(), m_nodes.end(), theNode);

      if (i == m_nodes.end())
      {
            // Doesn't belong to this doc, so throw...
            throw XercesDOMWrapperException(XercesDOMWrapperException::WRONG_DOCUMENT_ERR);
      }
      else
      {
            // Delete the node...
        XalanNode* ptrToDelete = *i;

        if ( ptrToDelete != 0 )
        {
            MemoryManagerType& theManager = m_nodes.getMemoryManager();

            ptrToDelete->~XalanNode();

            theManager.deallocate(ptrToDelete);

        }

            // Erase it from the map...
            m_nodes.erase(i);
      }
}



const XalanDOMString&
XercesDocumentWrapper::getNodeName() const
{
      assert(m_navigator != 0);

      return m_navigator->getPooledString(m_xercesDocument->getNodeName());
}



const XalanDOMString&
XercesDocumentWrapper::getNodeValue() const
{
      assert(m_navigator != 0);

      return m_navigator->getPooledString(m_xercesDocument->getNodeValue());
}



XercesDocumentWrapper::NodeType
XercesDocumentWrapper::getNodeType() const
{
      return DOCUMENT_NODE;
}



XalanNode*
XercesDocumentWrapper::getParentNode() const
{
      return 0;
}



const XalanNodeList*
XercesDocumentWrapper::getChildNodes() const
{
      return &m_children;
}



XalanNode*
XercesDocumentWrapper::getFirstChild() const
{
      assert(m_navigator != 0);

      return m_navigator->getFirstChild(m_xercesDocument);
}



XalanNode*
XercesDocumentWrapper::getLastChild() const
{
      assert(m_navigator != 0);

      return m_navigator->getLastChild(m_xercesDocument);
}



XalanNode*
XercesDocumentWrapper::getPreviousSibling() const
{
      return 0;
}



XalanNode*
XercesDocumentWrapper::getNextSibling() const
{
      return 0;
}



const XalanNamedNodeMap*
XercesDocumentWrapper::getAttributes() const
{
      return 0;
}



XalanDocument*
XercesDocumentWrapper::getOwnerDocument() const
{
      return 0;
}



#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
XalanNode*
#else
XercesDocumentWrapper*
#endif
XercesDocumentWrapper::cloneNode(bool     /* deep */) const
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanNode*
XercesDocumentWrapper::insertBefore(
                  XalanNode*  /* newChild */,
                  XalanNode*  /* refChild */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanNode*
XercesDocumentWrapper::replaceChild(
                  XalanNode*  /* newChild */,
                  XalanNode*  /* oldChild */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);

      return 0;
}



XalanNode*
XercesDocumentWrapper::removeChild(XalanNode*   /* oldChild */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);

      return 0;
}



XalanNode*
XercesDocumentWrapper::appendChild(XalanNode*   /* newChild */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);

      return 0;
}



bool
XercesDocumentWrapper::hasChildNodes() const
{
      return m_xercesDocument->hasChildNodes();
}



void
XercesDocumentWrapper::setNodeValue(const XalanDOMString&   /* nodeValue */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);
}



void
XercesDocumentWrapper::normalize()
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);
}


bool
XercesDocumentWrapper::isSupported(
                  const XalanDOMString&   feature,
                  const XalanDOMString&   version) const
{
      return XercesWrapperHelper::isSupported(m_xercesDocument, feature, version);
}



const XalanDOMString&
XercesDocumentWrapper::getNamespaceURI() const
{
      assert(m_navigator != 0);

      return m_navigator->getPooledString(m_xercesDocument->getNamespaceURI());
}



const XalanDOMString&
XercesDocumentWrapper::getPrefix() const
{
      assert(m_navigator != 0);

      return m_navigator->getPooledString(m_xercesDocument->getPrefix());
}



const XalanDOMString&
XercesDocumentWrapper::getLocalName() const
{
      assert(m_navigator != 0);

      return m_navigator->getPooledString(m_xercesDocument->getLocalName());
}



void
XercesDocumentWrapper::setPrefix(const XalanDOMString&      /* prefix */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);
}



bool
XercesDocumentWrapper::isIndexed() const
{
      return m_indexValid;
}



XercesDocumentWrapper::IndexType
XercesDocumentWrapper::getIndex() const
{
      assert(m_navigator != 0);
      assert(m_navigator->getIndex() == 1);

      return m_navigator->getIndex();
}



XalanElement*
XercesDocumentWrapper::createElement(const XalanDOMString&  /* tagName */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanDocumentFragment*
XercesDocumentWrapper::createDocumentFragment()
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanText*
XercesDocumentWrapper::createTextNode(const XalanDOMString& /* data */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanComment*
XercesDocumentWrapper::createComment(const XalanDOMString&  /* data */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanCDATASection*
XercesDocumentWrapper::createCDATASection(const XalanDOMString&         /* data */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanProcessingInstruction*
XercesDocumentWrapper::createProcessingInstruction(
                  const XalanDOMString&   /* target */,
                  const XalanDOMString&   /* data */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanAttr*
XercesDocumentWrapper::createAttribute(const XalanDOMString&      /* name */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanEntityReference*
XercesDocumentWrapper::createEntityReference(const XalanDOMString&      /* name */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      return 0;
}



XalanDocumentType*
XercesDocumentWrapper::getDoctype() const
{
      return m_doctype;
}




XalanDOMImplementation*
XercesDocumentWrapper::getImplementation() const
{
      return m_domImplementation.get();
}



XalanElement*
XercesDocumentWrapper::getDocumentElement() const
{
      // If we're working in mapping mode, m_documentElement will
      // be null, so we'll have to map the node...
      return m_documentElement != 0 ? m_documentElement : mapNode(m_xercesDocument->getDocumentElement());
}



XalanNodeList*
XercesDocumentWrapper::getElementsByTagName(const XalanDOMString& /* tagname */) const
{
      // Not supported...
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      // Dummy return value...
      return 0;
}



XalanNode*
XercesDocumentWrapper::importNode(
                  XalanNode*  /* importedNode */,
                  bool        /* deep */)
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NO_MODIFICATION_ALLOWED_ERR);

      // Dummy return value...
      return 0;
}



XalanElement*
XercesDocumentWrapper::createElementNS(
                  const XalanDOMString&   /* namespaceURI */,
                  const XalanDOMString&   /* qualifiedName */)
{
      // Not supported...
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      // Dummy return value...
      return 0;
}



XalanAttr*
XercesDocumentWrapper::createAttributeNS(
                  const XalanDOMString&   /* namespaceURI */,
                  const XalanDOMString&   /* qualifiedName */)
{
      // Not supported...
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      // Dummy return value...
      return 0;
}



XalanNodeList*
XercesDocumentWrapper::getElementsByTagNameNS(
                  const XalanDOMString&   /* namespaceURI */,
                  const XalanDOMString&   /* localName */) const
{
      throw XercesDOMWrapperException(XercesDOMWrapperException::NOT_SUPPORTED_ERR);

      // Dummy return value...
      return 0;
}



XalanElement*
XercesDocumentWrapper::getElementById(const XalanDOMString&       elementId) const
{
      const DOMNodeType* const      theXercesNode = m_xercesDocument->getElementById(c_wstr(elementId));

      if (theXercesNode == 0)
      {
            return 0;
      }
      else
      {
#if defined(XALAN_OLD_STYLE_CASTS)
            return (XalanElement*)mapNode(theXercesNode);
#else
            return static_cast<XalanElement*>(mapNode(theXercesNode));
#endif
      }
}



void
XercesDocumentWrapper::buildWrapperNodes()
{
      const DOMNodeType*      theStartChild = m_xercesDocument->getFirstChild();

      if (theStartChild != 0)
      {
            assert(m_navigator != 0);

            m_navigator->setIndex(1);
            m_navigator->setFirstChild(0);

            BuildWrapperTreeWalker  theTreeWalker(
                        this,
                        m_navigator,
                        2,
                        m_buildMaps);

            theTreeWalker.traverse(theStartChild, m_xercesDocument);
      }

      // OK, now set m_documentElement...
      XalanNode*  theChild = m_navigator->getFirstChild();

      while(theChild != 0 && theChild->getNodeType() != XalanNode::ELEMENT_NODE)
      {
            theChild = theChild->getNextSibling();
      }

#if defined(XALAN_OLD_STYLE_CASTS)
      m_documentElement = (XalanElement*)theChild;
#else
      m_documentElement = static_cast<XalanElement*>(theChild);
#endif

      m_indexValid = true;

      m_mappingMode = false;
}



XercesDocumentWrapper::BuildWrapperTreeWalker::BuildWrapperTreeWalker(
                  XercesDocumentWrapper*                  theDocument,
                  XercesWrapperNavigator*                 theDocumentNavigator,
                  IndexType                                     theStartIndex,
                  bool                                          theBuildMapsFlag) :
      m_document(theDocument),
      m_currentIndex(theStartIndex),
      m_parentNavigatorStack(theDocument->getMemoryManager()),
      m_siblingNavigatorStack(theDocument->getMemoryManager()),
      m_buildMaps(theBuildMapsFlag)
{
      assert(theDocument != 0 && theDocumentNavigator != 0);

      // Reserve some space...
      m_parentNavigatorStack.reserve(100);
      m_parentNavigatorStack.reserve(100);

      // The document navigator is the last navigator on the stack...
      m_parentNavigatorStack.push_back(NavigatorStackEntryType(theDocumentNavigator, theDocument));

      // There is no previous sibling...
      m_siblingNavigatorStack.push_back(NavigatorStackEntryType(0, 0));
}



XercesDocumentWrapper::BuildWrapperTreeWalker::~BuildWrapperTreeWalker()
{
}



bool
XercesDocumentWrapper::BuildWrapperTreeWalker::startNode(const DOMNodeType*         node)
{
    XercesWrapperNavigator*     theWrapperNodeNavigator;

      XalanNode* const  theWrapperNode =
            m_document->createWrapperNode(
                node,
                m_currentIndex,
                m_buildMaps,
                &theWrapperNodeNavigator);
    assert(theWrapperNodeNavigator != 0);

      assert(m_parentNavigatorStack.empty() == false);
      assert(m_siblingNavigatorStack.empty() == false);

      // Get the two navigators...
      NavigatorStackEntryType&      theParentEntry = m_parentNavigatorStack.back();
      NavigatorStackEntryType&      theSiblingEntry = m_siblingNavigatorStack.back();

      theWrapperNodeNavigator->setParentNode(theParentEntry.m_node);

      // If the first child has not been set, then set it
      // now...
      if (theParentEntry.m_navigator->getFirstChild() == 0)
      {
            assert(theSiblingEntry.m_node == 0);

            theParentEntry.m_navigator->setFirstChild(theWrapperNode);
      }

      // Always set the last child...
      theParentEntry.m_navigator->setLastChild(theWrapperNode);

      theWrapperNodeNavigator->setPreviousSibling(theSiblingEntry.m_node);

      if (theSiblingEntry.m_navigator != 0)
      {
            theSiblingEntry.m_navigator->setNextSibling(theWrapperNode);
      }

      // Build an entry for the stacks...
      const NavigatorStackEntryType theCurrentEntry(theWrapperNodeNavigator, theWrapperNode);

      // My child nodes will now be visited, so push the current
      // context on the parent stack...
      m_parentNavigatorStack.push_back(theCurrentEntry);

      // My siblings will also need to know about me as well...
      m_siblingNavigatorStack.push_back(theCurrentEntry);

      // This will serve to mark the sibling context for my first child,
      // since it has no previous sibling.  This will be popped off
      // when endNode() is called.
      m_siblingNavigatorStack.push_back(NavigatorStackEntryType(0, 0));

      // Finally, increment the index counter...
      ++m_currentIndex;

      const short       theType = node->getNodeType();

      if (theType == DOMNodeType::DOCUMENT_TYPE_NODE)
      {
            // Special case for doctype -- we have to build its entities...
            const DOMDocumentType_Type* const   theDoctype =
#if defined(XALAN_OLD_STYLE_CASTS)
                  (const DOMDocumentType_Type*)node;
#else
                  static_cast<const DOMDocumentType_Type*>(node);
#endif

            const DOMNamedNodeMapType* const    theEntities =
                  theDoctype->getEntities();

            const unsigned int      theLength =
                  theEntities->getLength();

            for (unsigned int i = 0; i < theLength; ++i)
            {
                  // Build it, but don't index it...
                  m_document->createWrapperNode(theEntities->item(i), m_currentIndex++, true);
            }
      }
      else if (theType == DOMNodeType::ELEMENT_NODE)
      {
      // Special case for element nodes -- we have to build the attributes...
            const DOMElementType* const         theElement =
#if defined(XALAN_OLD_STYLE_CASTS)
                  (const DOMElementType*)node;
#else
                  static_cast<const DOMElementType*>(node);
#endif

            const DOMNamedNodeMapType* const    theAttributes =
                  theElement->getAttributes();
            assert(theAttributes != 0);

            const unsigned int      theLength =
                  theAttributes->getLength();

            XercesWrapperNavigator* thePreviousAttrNavigator = 0;
            XalanNode*                    thePreviousAttr = 0;

            for (unsigned int i = 0; i < theLength; ++i)
            {
                  // Get the attribute from the node map...
                  const DOMNodeType* const      theAttr = theAttributes->item(i);
                  assert(theAttr != 0);

            XercesWrapperNavigator*     theCurrentAttrNavigator;

                  // Create a wrapper node.
                  XalanNode* const  theCurrentAttr =
                        m_document->createWrapperNode(
                    theAttr,
                    m_currentIndex,
                    m_buildMaps,
                    &theCurrentAttrNavigator);
                  assert(theCurrentAttr != 0 && theCurrentAttrNavigator != 0);

                  // Set the parent node...
                  theCurrentAttrNavigator->setParentNode(theWrapperNode);

                  if (thePreviousAttr != 0)
                  {
                        assert(thePreviousAttrNavigator != 0);

                        // Link in the previous attribute...
                        theCurrentAttrNavigator->setPreviousSibling(thePreviousAttr);

                        thePreviousAttrNavigator->setNextSibling(theCurrentAttr);
                  }

                  // Update the pointers so they point to this attribute...
                  thePreviousAttr = theCurrentAttr;
                  thePreviousAttrNavigator = theCurrentAttrNavigator;

                  // Finally, increment the index...
                  ++m_currentIndex;
            }
      }

      return false;
}



bool
XercesDocumentWrapper::BuildWrapperTreeWalker::endNode(const DOMNodeType*     /* node */)
{
      assert(m_parentNavigatorStack.empty() == false);
      assert(m_siblingNavigatorStack.empty() == false);

      // I have to pop my entry, since my children are finished...
      m_parentNavigatorStack.pop_back();

      // Pop any sibling navigators my child pushed...
      while(m_siblingNavigatorStack.back().m_navigator != 0)
      {
            assert(m_siblingNavigatorStack.back().m_node != 0);

            m_siblingNavigatorStack.pop_back();
      }

      // There must be a context marker...
      assert(m_siblingNavigatorStack.back().m_navigator == 0 &&
               m_siblingNavigatorStack.back().m_node == 0);

      // Pop the context marker...
      m_siblingNavigatorStack.pop_back();

      return false;
}



const XalanDOMString&
XercesDocumentWrapper::getPooledString(const XalanDOMString&      theString) const
{
      return m_stringPool->get(theString);
}



const XalanDOMString&
XercesDocumentWrapper::getPooledString(
                  const XalanDOMChar*                 theString,
                  XalanDOMString::size_type     theLength) const
{
      return m_stringPool->get(theString, theLength);
}



XALAN_CPP_NAMESPACE_END

Generated by  Doxygen 1.6.0   Back to index