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

XercesDocumentBridge.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.
 */


#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)


#include "XercesDocumentBridge.hpp"



#include <algorithm>
#include <cassert>



#include <xalanc/Include/STLHelper.hpp>



#include <xalanc/DOMSupport/DOMServices.hpp>



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



#include <xalanc/XercesParserLiaison/Deprecated/XercesAttrBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesBridgeHelper.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesCommentBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesCDATASectionBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesDOM_NodeHack.hpp>
#include <xalanc/XercesParserLiaison/XercesDOMException.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesDOMImplementationBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesDocumentFragmentBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesDocumentTypeBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesElementBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesEntityBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesEntityReferenceBridge.hpp>
#include <xalanc/XercesParserLiaison/XercesLiaisonXalanDOMStringPool.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesNodeListBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesNotationBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesProcessingInstructionBridge.hpp>
#include <xalanc/XercesParserLiaison/Deprecated/XercesTextBridge.hpp>



XALAN_CPP_NAMESPACE_BEGIN



XercesDocumentBridge::XercesDocumentBridge(
                  const DOM_Document_Type&      theXercesDocument,
                  bool                                threadSafe,
                  bool                                buildBridge) :
      XalanDocument(),
      m_xercesDocument(theXercesDocument),
      m_documentElement(0),
      m_nodeMap(),
      m_domImplementation(new XercesDOMImplementationBridge(theXercesDocument.getImplementation())),
      m_navigators(1, XercesBridgeNavigator(this, threadSafe == true ? false : !buildBridge)),
      m_navigator(&m_navigators.front()),
      m_children(theXercesDocument.getChildNodes(),
                     *m_navigator),
      m_nodes(),
      m_doctype(0),
      m_mappingMode(threadSafe == true ? false : !buildBridge),
      m_indexValid(false),
      m_elementAllocator(25),
      m_textAllocator(25),
      m_attributeAllocator(25),
      m_stringPool(threadSafe == true ? new XercesLiaisonXalanDOMStringPool : new XalanDOMStringPool)
{
      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...
            buildBridgeNodes();
      }
      else
      {
            m_nodeMap.addAssociation(m_xercesDocument, this);
      }
}



XercesDocumentBridge::~XercesDocumentBridge()
{
      destroyBridge();
}



XalanNode*
XercesDocumentBridge::mapNode(const DOM_NodeType&     theXercesNode) const
{
      return mapNode(XercesDOM_NodeHack::getImpl(theXercesNode));
}



XalanNode*
XercesDocumentBridge::mapNode(NodeImplType*           theXercesNodeImpl) const
{
      XalanNode*  theXalanNode = 0;

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

            if (theXalanNode == 0)
            {
                  XercesDOM_NodeHack      theHack(theXercesNodeImpl);

                  if (theHack != m_xercesDocument &&
                              theHack.getOwnerDocument() != m_xercesDocument &&
                        theHack.getParentNode() != m_xercesDocument)
                  {
                        throw XalanDOMException(XalanDOMException::WRONG_DOCUMENT_ERR);
                  }
                  else if (m_mappingMode == true)
                  {
                        // OK, we haven't yet created a bridge not, so go ahead and
                        // create one.
                        theXalanNode = createBridgeNode(theHack, 0, true);
                        assert(theXalanNode != 0);
                  }
            }
      }

      return theXalanNode;
}



DOM_NodeType
XercesDocumentBridge::mapNode(const XalanNode*  theXalanNode) const
{
      DOM_NodeType      theXercesNode;

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

            if (theXercesNode.isNull() == true)
            {
                  throw XalanDOMException(XalanDOMException::WRONG_DOCUMENT_ERR);
            }
      }

      return theXercesNode;
}



DOM_AttrType
XercesDocumentBridge::mapNode(const XalanAttr*  theXalanNode) const
{
      NodeImplType* const           theXercesNodeImpl =
            mapNodeToImpl(theXalanNode);

#if defined(XALAN_OLD_STYLE_CASTS)
      return XercesDOM_AttrHack((AttrImplType*)theXercesNodeImpl);
#else
      return XercesDOM_AttrHack(reinterpret_cast<AttrImplType*>(theXercesNodeImpl));
#endif
}



NodeImplType*
XercesDocumentBridge::mapNodeToImpl(const XalanNode*  theXalanNode) const
{
      NodeImplType*     theXercesNodeImpl = 0;

      if (theXalanNode != 0)
      {
            theXercesNodeImpl = m_nodeMap.getNodeImpl(theXalanNode);

            if (theXercesNodeImpl == 0)
            {
                  throw XalanDOMException(XalanDOMException::WRONG_DOCUMENT_ERR);
            }
      }

      return theXercesNodeImpl;
}



XalanAttr*
XercesDocumentBridge::mapNode(const DOM_AttrType&     theXercesNode) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
      return (XercesAttrBridge*)mapNode(XercesDOM_NodeHack::getImpl(theXercesNode));
#else
      return static_cast<XercesAttrBridge*>(mapNode(XercesDOM_NodeHack::getImpl(theXercesNode)));
#endif
}



XalanElement*
XercesDocumentBridge::mapNode(const DOM_ElementType&  theXercesNode) const
{
#if defined(XALAN_OLD_STYLE_CASTS)
      return (XercesElementBridge*)mapNode(XercesDOM_NodeHack::getImpl(theXercesNode));
#else
      return static_cast<XercesElementBridge*>(mapNode(XercesDOM_NodeHack::getImpl(theXercesNode)));
#endif
}



void
XercesDocumentBridge::destroyBridge()
{
      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>());

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

      // Clear out all of the navigators, except ours...
      m_navigators.erase(m_navigators.begin() + 1, m_navigators.end());

      m_navigator = &m_navigators.front();

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

      m_indexValid = false;

      m_mappingMode = true;

      m_stringPool->clear();
}



void
XercesDocumentBridge::rebuildBridge()
{
      destroyBridge();

      buildBridgeNodes();
}



XercesBridgeNavigator&
XercesDocumentBridge::pushNavigator(bool  mappingMode) const
{
      XercesDocumentBridge* const         This =
#if defined(XALAN_OLD_STYLE_CASTS)
            (XercesDocumentBridge*)this;
#else
            const_cast<XercesDocumentBridge*>(this);
#endif

      This->m_navigators.push_back(XercesBridgeNavigator(This, mappingMode));

      return This->m_navigators.back();
}



XercesDocumentTypeBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_DocumentType_Type&  theDoctype,
                  IndexType                                 theIndex,
                  bool                                      mapNode) const
{
      // This is a special case, since there is only one
      // doctype node allowed...
      assert(m_doctype == 0);
      assert(m_xercesDocument.getDoctype().isNull() == false &&
               m_xercesDocument.getDoctype() == theDoctype);

      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

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

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

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

      This->m_nodes.push_back(m_doctype);

      return m_doctype;
}



XercesElementBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_ElementType&  theXercesNode,
                  IndexType                     theIndex,
                  bool                          mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

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

      XercesElementBridge* const    theBridge =
            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, theBridge);
      }

      return theBridge;
}



XercesDocumentFragmentBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_DocumentFragmentType&           theXercesNode,
                  IndexType                                       theIndex,
                  bool                                            mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesDocumentFragmentBridge* const       theBridge =
            new XercesDocumentFragmentBridge(theXercesNode,
                                                             theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XercesTextBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_TextType&           theXercesNode,
                  IndexType                     theIndex,
                  bool                          mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

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

      XercesTextBridge* const       theBridge =
            This->m_textAllocator.create(theXercesNode,
                                                       theNavigator);

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

      return theBridge;
}



XercesCommentBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_CommentType&  theXercesNode,
                  IndexType                     theIndex,
                  bool                          mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesCommentBridge* const    theBridge =
            new XercesCommentBridge(theXercesNode,
                                                theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XercesCDATASectionBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_CDATASectionType&         theXercesNode,
                  IndexType                                 theIndex,
                  bool                                      mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesCDATASectionBridge* const           theBridge =
            new XercesCDATASectionBridge(theXercesNode,
                                                       theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XercesProcessingInstructionBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_ProcessingInstructionType&      theXercesNode,
                  IndexType                                             theIndex,
                  bool                                                  mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesProcessingInstructionBridge* const  theBridge =
            new XercesProcessingInstructionBridge(theXercesNode,
                                                                    theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XercesAttrBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_AttrType&           theXercesNode,
                  IndexType                     theIndex,
                  bool                          mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

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

      XercesAttrBridge* const       theBridge =
            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, theBridge);

      return theBridge;
}



XercesEntityBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_EntityType&   theXercesNode,
                  IndexType                     theIndex,
                  bool                          mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesEntityBridge* const     theBridge =
            new XercesEntityBridge(theXercesNode,
                                             theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XercesEntityReferenceBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_EntityReferenceType&      theXercesNode,
                  IndexType                                 theIndex,
                  bool                                      mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesEntityReferenceBridge* const  theBridge =
            new XercesEntityReferenceBridge(theXercesNode,
                                                            theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XercesNotationBridge*
XercesDocumentBridge::createBridgeNode(
                  const DOM_NotationType&       theXercesNode,
                  IndexType                           theIndex,
                  bool                                mapNode) const
{
      // Create a navigator...
      XercesBridgeNavigator&  theNavigator = pushNavigator(mapNode);

      theNavigator.setIndex(theIndex);

      XercesNotationBridge* const         theBridge =
            new XercesNotationBridge(theXercesNode,
                                                 theNavigator);

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

      This->m_nodes.push_back(theBridge);

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

      return theBridge;
}



XalanNode*
XercesDocumentBridge::createBridgeNode(
                  const DOM_NodeType&           theXercesNode,
                  IndexType                     theIndex,
                  bool                          mapNode) const
{
      XalanNode*                    theNewNode = 0;

      switch(theXercesNode.getNodeType())
      {
      case DOM_NodeType::ATTRIBUTE_NODE:
            {
                  const DOM_AttrType&           theAttrNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_AttrType&)theXercesNode;
#else
                                    static_cast<const DOM_AttrType&>(theXercesNode);
#endif

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

      case DOM_NodeType::CDATA_SECTION_NODE:
            {
                  const DOM_CDATASectionType&         theCDATASectionNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_CDATASectionType&)theXercesNode;
#else
                                    static_cast<const DOM_CDATASectionType&>(theXercesNode);
#endif

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

            }
            break;

      case DOM_NodeType::COMMENT_NODE:
            {
                  const DOM_CommentType&  theCommentNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_CommentType&)theXercesNode;
#else
                                    static_cast<const DOM_CommentType&>(theXercesNode);
#endif

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

      case DOM_NodeType::DOCUMENT_FRAGMENT_NODE:
            {
                  const DOM_DocumentFragmentType&           theDocumentFragmentNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_DocumentFragmentType&)theXercesNode;
#else
                                    static_cast<const DOM_DocumentFragmentType&>(theXercesNode);
#endif

                  theNewNode = createBridgeNode(theDocumentFragmentNode, theIndex, mapNode);
                  assert(theNewNode != 0);

            }
            break;

      case DOM_NodeType::ELEMENT_NODE:
            {
                  const DOM_ElementType&  theElementNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_ElementType&)theXercesNode;
#else
                                    static_cast<const DOM_ElementType&>(theXercesNode);
#endif

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

      case DOM_NodeType::ENTITY_NODE:
            {
                  const DOM_EntityType&   theEntityNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_EntityType&)theXercesNode;
#else
                                    static_cast<const DOM_EntityType&>(theXercesNode);
#endif

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

      case DOM_NodeType::ENTITY_REFERENCE_NODE:
            {
                  const DOM_EntityReferenceType&      theEntityReferenceNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_EntityReferenceType&)theXercesNode;
#else
                                    static_cast<const DOM_EntityReferenceType&>(theXercesNode);
#endif

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

      case DOM_NodeType::NOTATION_NODE:
            {
                  const DOM_NotationType&       theNotationNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_NotationType&)theXercesNode;
#else
                                    static_cast<const DOM_NotationType&>(theXercesNode);
#endif

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

      case DOM_NodeType::PROCESSING_INSTRUCTION_NODE:
            {
                  const DOM_ProcessingInstructionType&      thePINode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_ProcessingInstructionType&)theXercesNode;
#else
                                    static_cast<const DOM_ProcessingInstructionType&>(theXercesNode);
#endif

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

      case DOM_NodeType::TEXT_NODE:
            {
                  const DOM_TextType&           theTextNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_TextType&)theXercesNode;
#else
                                    static_cast<const DOM_TextType&>(theXercesNode);
#endif

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

      case DOM_NodeType::DOCUMENT_TYPE_NODE:
            {
                  const DOM_DocumentType_Type&  theDoctypeNode =
#if defined(XALAN_OLD_STYLE_CASTS)
                                    (const DOM_DocumentType_Type&)theXercesNode;
#else
                                    static_cast<const DOM_DocumentType_Type&>(theXercesNode);
#endif

                  theNewNode = createBridgeNode(theDoctypeNode, theIndex, mapNode);

                  assert(theNewNode != 0);
            }
            break;

      default:
            assert(false);
            break;
      }

      return theNewNode;
}



void
XercesDocumentBridge::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 XercesDOMException(XercesDOMException::WRONG_DOCUMENT_ERR);
      }
      else
      {
            // Delete the node...
            delete *i;

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



XalanNode*
XercesDocumentBridge::internalCloneNode(
                  const XalanNode*        theXalanNode,
                  const DOM_NodeType&           theXercesNode,
                  bool                          deep)
{
      XalanNode*  theNewNode = 0;

      if (theXalanNode->getOwnerDocument() != this)
      {
            throw XercesDOMException(XercesDOMException::WRONG_DOCUMENT_ERR);
      }

      try
      {
            const DOM_NodeType      theNewXercesNode = 
                  theXercesNode.cloneNode(deep);

            theNewNode = createBridgeNode(theNewXercesNode, 0, true);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theNewNode;
}



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

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



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

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



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



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



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



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

      return m_navigator->getFirstChild(m_xercesDocument);
}



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

      return m_navigator->getLastChild(m_xercesDocument);
}



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



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



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



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



#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
XalanNode*
#else
XercesDocumentBridge*
#endif
XercesDocumentBridge::cloneNode(bool      deep) const
{
      XercesDocumentBridge*   theBridge = 0;

      try
      {
            const DOM_NodeType      theNewDocument = m_xercesDocument.cloneNode(deep);

            theBridge =
#if defined(XALAN_OLD_STYLE_CASTS)
                  new XercesDocumentBridge((const DOM_Document_Type&)theNewDocument);
#else
                  new XercesDocumentBridge(static_cast<const DOM_Document_Type&>(theNewDocument));
#endif
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridge;
}



XalanNode*
XercesDocumentBridge::insertBefore(
                  XalanNode*  newChild,
                  XalanNode*  refChild)
{
      assert(m_navigator != 0);

      return m_navigator->insertBefore(m_xercesDocument, newChild, refChild);
}



XalanNode*
XercesDocumentBridge::replaceChild(
                  XalanNode*  newChild,
                  XalanNode*  oldChild)
{
      assert(m_navigator != 0);

      return m_navigator->replaceChild(m_xercesDocument, newChild, oldChild);
}



XalanNode*
XercesDocumentBridge::removeChild(XalanNode*     oldChild)
{
      assert(m_navigator != 0);

      return m_navigator->removeChild(m_xercesDocument, oldChild);
}



XalanNode*
XercesDocumentBridge::appendChild(XalanNode*    newChild)
{
      assert(m_navigator != 0);

      return m_navigator->appendChild(m_xercesDocument, newChild);
}



bool
XercesDocumentBridge::hasChildNodes() const
{
      return m_xercesDocument.hasChildNodes();
}



void
XercesDocumentBridge::setNodeValue(const XalanDOMString&    nodeValue)
{
      XercesBridgeHelper::setNodeValue(m_xercesDocument, nodeValue);
}



void
XercesDocumentBridge::normalize()
{
      XercesBridgeHelper::normalize(m_xercesDocument);
}


bool
XercesDocumentBridge::isSupported(
                  const XalanDOMString&   feature,
                  const XalanDOMString&   version) const
{
      return m_xercesDocument.isSupported(
                        XercesBridgeHelper::XalanDOMStringToXercesDOMString(feature),
                        XercesBridgeHelper::XalanDOMStringToXercesDOMString(version));
}



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

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



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

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



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

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



void
XercesDocumentBridge::setPrefix(const XalanDOMString& prefix)
{
      XercesBridgeHelper::setPrefix(m_xercesDocument, prefix);
}



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



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

      return m_navigator->getIndex();
}



XalanElement*
XercesDocumentBridge::createElement(const XalanDOMString&   tagName)
{
      XalanElement*     theBridgeNode = 0;

      try
      {
            const DOM_ElementType   theXercesNode =
                  m_xercesDocument.createElement(c_wstr(tagName));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanDocumentFragment*
XercesDocumentBridge::createDocumentFragment()
{
      XalanDocumentFragment*  theBridgeNode = 0;

      try
      {
            const DOM_DocumentFragmentType      theXercesNode =
                  m_xercesDocument.createDocumentFragment();
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanText*
XercesDocumentBridge::createTextNode(const XalanDOMString&  data)
{
      XalanText*  theBridgeNode = 0;

      try
      {
            const DOM_TextType      theXercesNode =
                  m_xercesDocument.createTextNode(c_wstr(data));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanComment*
XercesDocumentBridge::createComment(const XalanDOMString&   data)
{
      XalanComment*     theBridgeNode = 0;

      try
      {
            const DOM_CommentType   theXercesNode =
                  m_xercesDocument.createComment(c_wstr(data));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanCDATASection*
XercesDocumentBridge::createCDATASection(const XalanDOMString&    data)
{
      XalanCDATASection*      theBridgeNode = 0;

      try
      {
            const DOM_CDATASectionType    theXercesNode =
                  m_xercesDocument.createCDATASection(c_wstr(data));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanProcessingInstruction*
XercesDocumentBridge::createProcessingInstruction(
                  const XalanDOMString&   target,
                  const XalanDOMString&   data)
{
      XalanProcessingInstruction*   theBridgeNode = 0;

      try
      {
            const DOM_ProcessingInstructionType       theXercesNode =
                  m_xercesDocument.createProcessingInstruction(c_wstr(target), c_wstr(data));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanAttr*
XercesDocumentBridge::createAttribute(const XalanDOMString&       name)
{
      XalanAttr*  theBridgeNode = 0;

      try
      {
            const DOM_AttrType      theXercesNode =
                  m_xercesDocument.createAttribute(c_wstr(name));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanEntityReference*
XercesDocumentBridge::createEntityReference(const XalanDOMString& name)
{
      XalanEntityReference*   theBridgeNode = 0;

      try
      {
            const DOM_EntityReferenceType theXercesNode =
                  m_xercesDocument.createEntityReference(c_wstr(name));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



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




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



XalanElement*
XercesDocumentBridge::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*
XercesDocumentBridge::getElementsByTagName(const XalanDOMString&  /* tagname */) const
{
      // Not supported
      throw XercesDOMException(XercesDOMException::NOT_SUPPORTED_ERR);

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



XalanNode*
XercesDocumentBridge::importNode(
                  XalanNode*  /* importedNode */,
                  bool        /* deep */)
{
      throw XercesDOMException(XercesDOMException::NOT_SUPPORTED_ERR);

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



XalanElement*
XercesDocumentBridge::createElementNS(
                  const XalanDOMString&   namespaceURI,
                  const XalanDOMString&   qualifiedName)
{
      XalanElement*     theBridgeNode = 0;

      try
      {
            const DOM_ElementType   theXercesNode =
                  m_xercesDocument.createElementNS(c_wstr(namespaceURI), c_wstr(qualifiedName));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



XalanAttr*
XercesDocumentBridge::createAttributeNS(
                  const XalanDOMString&   namespaceURI,
                  const XalanDOMString&   qualifiedName)
{
      XalanAttr*  theBridgeNode = 0;

      try
      {
            const DOM_AttrType      theXercesNode =
                  m_xercesDocument.createAttributeNS(c_wstr(namespaceURI), c_wstr(qualifiedName));
            assert(theXercesNode.isNull() == false);

            theBridgeNode = createBridgeNode(theXercesNode, 0, true);
            assert(mapNode(theXercesNode) == theBridgeNode);
      }
      catch(const DOM_DOMExceptionType&   theException)
      {
            throw XercesDOMException(theException);
      }

      return theBridgeNode;
}



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

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



XalanElement*
XercesDocumentBridge::getElementById(const XalanDOMString&  elementId) const
{
      // $$$ ToDo: This is because DOM_Document::getElementById() is not
      // const...
#if defined(XALAN_NO_MUTABLE)
      const DOM_NodeType      theXercesNode(((DOM_Document_Type&)m_xercesDocument).getElementById(c_wstr(elementId)));
#else
      const DOM_NodeType      theXercesNode(m_xercesDocument.getElementById(c_wstr(elementId)));
#endif

      return theXercesNode.isNull() == true ? 0 :
#if defined(XALAN_OLD_STYLE_CASTS)
                        (XalanElement*)mapNode(theXercesNode);
#else
                        static_cast<XalanElement*>(mapNode(theXercesNode));
#endif
}



void
XercesDocumentBridge::buildBridgeNodes()
{
      const DOM_NodeType      theStartChild = m_xercesDocument.getFirstChild();

      if (theStartChild.isNull() == false)
      {
            assert(m_navigator != 0);
            assert(m_navigators.size() == 1);

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

            BuildBridgeTreeWalker   theTreeWalker(
                        this,
                        &m_navigators.back(),
                        m_navigators,
                        2);

            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;
}



XercesDocumentBridge::BuildBridgeTreeWalker::BuildBridgeTreeWalker(
                  XercesDocumentBridge*         theDocument,
                  XercesBridgeNavigator*        theDocumentNavigator,
                  NavigatorBridgeVectorType&    theNavigators,
                  IndexType                           theStartIndex) :
      m_document(theDocument),
      m_navigators(theNavigators),
      m_currentIndex(theStartIndex),
      m_parentNavigatorStack(),
      m_siblingNavigatorStack()
{
      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));
}



XercesDocumentBridge::BuildBridgeTreeWalker::~BuildBridgeTreeWalker()
{
}



void
XercesDocumentBridge::BuildBridgeTreeWalker::startNode(const DOM_NodeType&    node)
{
      XalanNode* const  theBridgeNode = m_document->createBridgeNode(node, m_currentIndex, false);

      XercesBridgeNavigator&  theCurrentNodeNavigator = m_navigators.back();

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

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

      theCurrentNodeNavigator.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(theBridgeNode);
      }

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

      theCurrentNodeNavigator.setPreviousSibling(theSiblingEntry.m_node);

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

      // Build an entry for the stacks...
      const NavigatorStackEntryType theCurrentEntry(&theCurrentNodeNavigator, theBridgeNode);

      // 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 == DOM_NodeType::DOCUMENT_TYPE_NODE)
      {
            // Special case for doctype -- we have to build its entities...
            const DOM_DocumentType_Type&  theDoctype =
#if defined(XALAN_OLD_STYLE_CASTS)
                  (const DOM_DocumentType_Type&)node;
#else
                  static_cast<const DOM_DocumentType_Type&>(node);
#endif

            const DOM_NamedNodeMapType    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->createBridgeNode(theEntities.item(i), m_currentIndex++, true);
            }
      }
      else if (theType == DOM_NodeType::ELEMENT_NODE)
      {
      // Special case for element nodes -- we have to build the attributes...
            const DOM_ElementType&  theElement =
#if defined(XALAN_OLD_STYLE_CASTS)
                  (const DOM_ElementType&)node;
#else
                  static_cast<const DOM_ElementType&>(node);
#endif

            const DOM_NamedNodeMapType    theAttributes =
                  theElement.getAttributes();

            const unsigned int      theLength =
                  theAttributes.getLength();

            XercesBridgeNavigator*  thePreviousAttrNavigator = 0;
            XalanNode*                    thePreviousAttr = 0;

            for (unsigned int i = 0; i < theLength; ++i)
            {
                  // Get the attribute from the node map...
                  const DOM_NodeType      theAttr = theAttributes.item(i);
                  assert(theAttr.isNull() == false);

                  // Create a bridge node.
                  XalanNode* const  theCurrentAttr =
                        m_document->createBridgeNode(theAttr, m_currentIndex, false);
                  assert(theCurrentAttr != 0);

                  // Get the attribute node's navigator...
                  XercesBridgeNavigator&  theCurrentAttrNavigator =
                        m_navigators.back();

                  // Set the parent node...
                  theCurrentAttrNavigator.setParentNode(theBridgeNode);

                  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;
            }
      }
}



void
XercesDocumentBridge::BuildBridgeTreeWalker::endNode(const DOM_NodeType&      /* 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();
}



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



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



XALAN_CPP_NAMESPACE_END


#endif //XALAN_BUILD_DEPRECATED_DOM_BRIDGE 



Generated by  Doxygen 1.6.0   Back to index