/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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(XERCESDOCUMENTWRAPPER_HEADER_GUARD_1357924680) #define XERCESDOCUMENTWRAPPER_HEADER_GUARD_1357924680 #include #include #include #if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION) #include #endif #include #include #include #include #include #include #include #include #include #include namespace XALAN_CPP_NAMESPACE { class XalanDOMStringPool; class XercesCommentWrapper; class XercesCDATASectionWrapper; class XercesDocumentFragmentWrapper; class XercesDocumentTypeWrapper; class XercesEntityWrapper; class XercesEntityReferenceWrapper; class XercesProcessingInstructionWrapper; class XercesNotationWrapper; class XALAN_XERCESPARSERLIAISON_EXPORT XercesDocumentWrapper : public XalanDocument { public: friend class XercesWrapperNavigator; /** * * Constructor for XercesDocumentWrapper. * * If the document will be shared amongst multiple threads of execution, * the parameter buildWrapper must be true. Otherwise, the bridge * nodes will be built on demand, a process which is not synchronized. * This could cause serious problems if multiple threads tried to visit * an unbuilt node at the same time. * * @param theXercesDocument The Xerces document to bridge * @param threadSafe If true, the tree can safely be shared amongst multiple threads. (Also implies buildWrapper == true) * @param buildWrapper If true, all of the bridge nodes will be built during construction. * @param buildMaps If true, a map of Xerces to Xalan nodes will be built, even if the bridge is built * */ XercesDocumentWrapper( MemoryManager& theManager, const DOMDocument_Type* theXercesDocument, bool threadSafe = true, bool buildWrapper = true, bool buildMaps = false); static XercesDocumentWrapper* create( MemoryManager& theManager, const DOMDocument_Type* theXercesDocument, bool threadSafe, bool buildWrapper, bool buildMaps); MemoryManager& getMemoryManager() const { return m_nodeMap.getMemoryManager(); } virtual ~XercesDocumentWrapper(); // These interfaces are inherited from XalanNode... virtual const XalanDOMString& getNodeName() const; virtual const XalanDOMString& getNodeValue() const; virtual NodeType getNodeType() const; virtual XalanNode* getParentNode() const; virtual const XalanNodeList* getChildNodes() const; virtual XalanNode* getFirstChild() const; virtual XalanNode* getLastChild() const; virtual XalanNode* getPreviousSibling() const; virtual XalanNode* getNextSibling() const; virtual const XalanNamedNodeMap* getAttributes() const; virtual XalanDocument* getOwnerDocument() const; virtual const XalanDOMString& getNamespaceURI() const; virtual const XalanDOMString& getPrefix() const; virtual const XalanDOMString& getLocalName() const; virtual bool isIndexed() const; virtual IndexType getIndex() const; virtual XalanElement* getDocumentElement() const; virtual XalanElement* getElementById(const XalanDOMString& elementId) const; // These are some special interfaces to manage relationships between // our nodes and Xerces nodes. /** * Destroy the entire bridge structure that connects * the Xerces document to this XercesDocumentWrapper * instance. This will invalidate any pointers to * any nodes in the document (except, of course, the * document itself). */ void destroyWrapper(); /** * Rebuild the entire bridge structure that connects * the Xerces document to this XercesDocumentWrapper * instance. This destroys the bridge before * rebuilding. */ void rebuildWrapper(); /** * Map a Xerces node to the corresponding wrapper node. * If the constructor for the instance was called with * the threadSafe or buildWrapper parameter equal to * true, this call will fail. * * @param theXercesNode The Xerces instance to map * * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. */ XalanNode* mapNode(const DOMNodeType* theXercesNode) const; /** * Map a Xerces node to the corresponding wrapper node. * If the constructor for the instance was called with * the threadSafe or buildWrapper parameter equal to * true, this call will fail. * * @param theXercesNode The Xerces instance to map * * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. */ XalanAttr* mapNode(const DOMAttrType* theXercesNode) const; /** * Map a Xerces node to the corresponding wrapper node. * If the constructor for the instance was called with * the threadSafe or buildWrapper parameter equal to * true, this call will fail. * * @param theXercesNode The Xerces instance to map * * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. */ XalanElement* mapNode(const DOMElementType* theXercesNode) const; /** * Map a XalanNode to the corresponding Xerces node. * If the node not owned by this document, the * function will throw XalanDOMException with the code * WRONG_DOCUMENT_ERR. * * @param theXalanNode The Xalan instance to map * * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. */ const DOMNodeType* mapNode(XalanNode* theXalanNode) const; /** * * Get the Xerces DOMDocument that this XercesDocument represents. * * @return the Xerces DOMDocument instance. * */ const DOMDocument_Type* getXercesDocument() const { return m_xercesDocument; } /** * Build the entire bridge structure. This should be done before any * processing begins, if the tree will be shared amongst multiple * threads. */ void buildWrapperNodes(); typedef XalanVector NodeVectorType; // Helper class to walk the tree and build everything... class BuildWrapperTreeWalker : public XercesDOMWalker { public: typedef XercesDOMWalker ParentType; BuildWrapperTreeWalker( XercesDocumentWrapper* theDocument, XercesWrapperNavigator* theDocumentNavigator, IndexType theStartIndex, bool theBuildMapsFlag); virtual ~BuildWrapperTreeWalker(); struct NavigatorStackEntryType { NavigatorStackEntryType( XercesWrapperNavigator* theNavigator = 0, XalanNode* theNode = 0) : m_navigator(theNavigator), m_node(theNode) { } XercesWrapperNavigator* m_navigator; XalanNode* m_node; }; typedef XalanVector NavigatorStackType; protected: virtual bool startNode(const DOMNodeType* node); virtual bool endNode(const DOMNodeType* node); using ParentType::startNode; using ParentType::endNode; private: XercesDocumentWrapper* m_document; IndexType m_currentIndex; NavigatorStackType m_parentNavigatorStack; NavigatorStackType m_siblingNavigatorStack; const bool m_buildMaps; }; /** * Get a pooled string. If the string is not in the pool, * add it. * * @param theString The string to pool. * @return A const reference to the pooled string. */ const XalanDOMString& getPooledString(const XalanDOMString& theString) const; /** * Get a pooled string. If the string is not in the pool, * add it. * * @param theString The string to pool. * @param theLength The length of the string. If XalanDOMString::npos, the string is assumed to be null-terminated. * @return A const reference to the pooled string. */ const XalanDOMString& getPooledString( const XalanDOMChar* theString, XalanDOMString::size_type theLength = XalanDOMString::npos) const; bool getMappingMode() const { return m_mappingMode; } private: // Destruction API... void destroyWrapperNode(XalanNode* theNode); // Not implemented... XercesDocumentWrapper(const XercesDocumentWrapper& theSource); XercesDocumentWrapper& operator=(const XercesDocumentWrapper& theRHS); bool operator==(const XercesDocumentWrapper& theRHS) const; // Private delete function... void destroyNode(XalanNode* theNode); // More internal implementation stuff... // Factory methods for our implementation nodes... XalanNode* createWrapperNode( const DOMNodeType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesDocumentTypeWrapper* createWrapperNode( const DOMDocumentType_Type* theDoctype, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesElementWrapper* createWrapperNode( const DOMElementType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesTextWrapper* createWrapperNode( const DOMTextType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesCommentWrapper* createWrapperNode( const DOMCommentType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesCDATASectionWrapper* createWrapperNode( const DOMCDATASectionType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesProcessingInstructionWrapper* createWrapperNode( const DOMProcessingInstructionType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesAttrWrapper* createWrapperNode( const DOMAttrType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesEntityWrapper* createWrapperNode( const DOMEntityType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesEntityReferenceWrapper* createWrapperNode( const DOMEntityReferenceType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesNotationWrapper* createWrapperNode( const DOMNotationType* theXercesNode, IndexType theIndex, bool mapNode, XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; XercesWrapperNavigator& createNavigator() const; // This is a private helper class for building the tree... friend class BuildWrapperTreeWalker; const DOMDocument_Type* const m_xercesDocument; XalanElement* m_documentElement; mutable XercesWrapperToXalanNodeMap m_nodeMap; mutable XercesWrapperNavigatorAllocator m_navigatorAllocator; // Our navigator will be the first entry in m_navigators, // but we'll cache this so access is faster... XercesWrapperNavigator* m_navigator; XercesNodeListWrapper m_children; mutable NodeVectorType m_nodes; mutable XercesDocumentTypeWrapper* m_doctype; bool m_mappingMode; bool m_indexValid; const bool m_buildMaps; mutable XercesElementWrapperAllocator m_elementAllocator; mutable XercesTextWrapperAllocator m_textAllocator; mutable XercesAttrWrapperAllocator m_attributeAllocator; const XalanMemMgrAutoPtr m_stringPool; }; } #endif // !defined(XERCESDOCUMENTWRAPPER_HEADER_GUARD_1357924680)