1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 #if !defined(XERCESDOCUMENTWRAPPER_HEADER_GUARD_1357924680) 19 #define XERCESDOCUMENTWRAPPER_HEADER_GUARD_1357924680 20 21 22 23 #include <xalanc/XercesParserLiaison/XercesParserLiaisonDefinitions.hpp> 24 25 26 27 #include <xalanc/Include/XalanVector.hpp> 28 29 30 31 #include <xalanc/XalanDOM/XalanDocument.hpp> 32 33 34 35 #if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION) 36 #include <xalanc/PlatformSupport/XalanDOMStringPool.hpp> 37 #endif 38 39 40 41 #include <xalanc/Include/XalanMemMgrAutoPtr.hpp> 42 43 44 45 #include <xalanc/XercesParserLiaison/XercesDOMWalker.hpp> 46 #include <xalanc/XercesParserLiaison/XercesWrapperNavigator.hpp> 47 48 49 #include <xalanc/XercesParserLiaison/XercesWrapperToXalanNodeMap.hpp> 50 #include <xalanc/XercesParserLiaison/XercesNodeListWrapper.hpp> 51 #include <xalanc/XercesParserLiaison/XercesAttrWrapperAllocator.hpp> 52 #include <xalanc/XercesParserLiaison/XercesElementWrapperAllocator.hpp> 53 #include <xalanc/XercesParserLiaison/XercesTextWrapperAllocator.hpp> 54 #include <xalanc/XercesParserLiaison/XercesWrapperNavigatorAllocator.hpp> 55 56 57 #include <xalanc/XercesParserLiaison/XercesWrapperTypes.hpp> 58 59 60 61 namespace XALAN_CPP_NAMESPACE { 62 63 64 65 class XalanDOMStringPool; 66 class XercesCommentWrapper; 67 class XercesCDATASectionWrapper; 68 class XercesDocumentFragmentWrapper; 69 class XercesDocumentTypeWrapper; 70 class XercesEntityWrapper; 71 class XercesEntityReferenceWrapper; 72 class XercesProcessingInstructionWrapper; 73 class XercesNotationWrapper; 74 75 76 77 class XALAN_XERCESPARSERLIAISON_EXPORT XercesDocumentWrapper : public XalanDocument 78 { 79 public: 80 81 friend class XercesWrapperNavigator; 82 83 /** 84 * 85 * Constructor for XercesDocumentWrapper. 86 * 87 * If the document will be shared amongst multiple threads of execution, 88 * the parameter buildWrapper must be true. Otherwise, the bridge 89 * nodes will be built on demand, a process which is not synchronized. 90 * This could cause serious problems if multiple threads tried to visit 91 * an unbuilt node at the same time. 92 * 93 * @param theXercesDocument The Xerces document to bridge 94 * @param threadSafe If true, the tree can safely be shared amongst multiple threads. (Also implies buildWrapper == true) 95 * @param buildWrapper If true, all of the bridge nodes will be built during construction. 96 * @param buildMaps If true, a map of Xerces to Xalan nodes will be built, even if the bridge is built 97 * 98 */ 99 XercesDocumentWrapper( 100 MemoryManager& theManager, 101 const DOMDocument_Type* theXercesDocument, 102 bool threadSafe = true, 103 bool buildWrapper = true, 104 bool buildMaps = false); 105 106 static XercesDocumentWrapper* 107 create( 108 MemoryManager& theManager, 109 const DOMDocument_Type* theXercesDocument, 110 bool threadSafe, 111 bool buildWrapper, 112 bool buildMaps); 113 114 MemoryManager& getMemoryManager() const115 getMemoryManager() const 116 { 117 return m_nodeMap.getMemoryManager(); 118 } 119 120 virtual 121 ~XercesDocumentWrapper(); 122 123 // These interfaces are inherited from XalanNode... 124 125 virtual const XalanDOMString& 126 getNodeName() const; 127 128 virtual const XalanDOMString& 129 getNodeValue() const; 130 131 virtual NodeType 132 getNodeType() const; 133 134 virtual XalanNode* 135 getParentNode() const; 136 137 virtual const XalanNodeList* 138 getChildNodes() const; 139 140 virtual XalanNode* 141 getFirstChild() const; 142 143 virtual XalanNode* 144 getLastChild() const; 145 146 virtual XalanNode* 147 getPreviousSibling() const; 148 149 virtual XalanNode* 150 getNextSibling() const; 151 152 virtual const XalanNamedNodeMap* 153 getAttributes() const; 154 155 virtual XalanDocument* 156 getOwnerDocument() const; 157 158 virtual const XalanDOMString& 159 getNamespaceURI() const; 160 161 virtual const XalanDOMString& 162 getPrefix() const; 163 164 virtual const XalanDOMString& 165 getLocalName() const; 166 167 virtual bool 168 isIndexed() const; 169 170 virtual IndexType 171 getIndex() const; 172 173 virtual XalanElement* 174 getDocumentElement() const; 175 176 virtual XalanElement* 177 getElementById(const XalanDOMString& elementId) const; 178 179 // These are some special interfaces to manage relationships between 180 // our nodes and Xerces nodes. 181 182 /** 183 * Destroy the entire bridge structure that connects 184 * the Xerces document to this XercesDocumentWrapper 185 * instance. This will invalidate any pointers to 186 * any nodes in the document (except, of course, the 187 * document itself). 188 */ 189 void 190 destroyWrapper(); 191 192 /** 193 * Rebuild the entire bridge structure that connects 194 * the Xerces document to this XercesDocumentWrapper 195 * instance. This destroys the bridge before 196 * rebuilding. 197 */ 198 void 199 rebuildWrapper(); 200 201 /** 202 * Map a Xerces node to the corresponding wrapper node. 203 * If the constructor for the instance was called with 204 * the threadSafe or buildWrapper parameter equal to 205 * true, this call will fail. 206 * 207 * @param theXercesNode The Xerces instance to map 208 * 209 * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. 210 */ 211 XalanNode* 212 mapNode(const DOMNodeType* theXercesNode) const; 213 214 /** 215 * Map a Xerces node to the corresponding wrapper node. 216 * If the constructor for the instance was called with 217 * the threadSafe or buildWrapper parameter equal to 218 * true, this call will fail. 219 * 220 * @param theXercesNode The Xerces instance to map 221 * 222 * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. 223 */ 224 XalanAttr* 225 mapNode(const DOMAttrType* theXercesNode) const; 226 227 /** 228 * Map a Xerces node to the corresponding wrapper node. 229 * If the constructor for the instance was called with 230 * the threadSafe or buildWrapper parameter equal to 231 * true, this call will fail. 232 * 233 * @param theXercesNode The Xerces instance to map 234 * 235 * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. 236 */ 237 XalanElement* 238 mapNode(const DOMElementType* theXercesNode) const; 239 240 /** 241 * Map a XalanNode to the corresponding Xerces node. 242 * If the node not owned by this document, the 243 * function will throw XalanDOMException with the code 244 * WRONG_DOCUMENT_ERR. 245 * 246 * @param theXalanNode The Xalan instance to map 247 * 248 * @return The pointer to the corresponding XalanNode instance, or 0 if the node could not be mapped. 249 */ 250 const DOMNodeType* 251 mapNode(XalanNode* theXalanNode) const; 252 253 /** 254 * 255 * Get the Xerces DOMDocument that this XercesDocument represents. 256 * 257 * @return the Xerces DOMDocument instance. 258 * 259 */ 260 const DOMDocument_Type* getXercesDocument() const261 getXercesDocument() const 262 { 263 return m_xercesDocument; 264 } 265 266 /** 267 * Build the entire bridge structure. This should be done before any 268 * processing begins, if the tree will be shared amongst multiple 269 * threads. 270 */ 271 void 272 buildWrapperNodes(); 273 274 typedef XalanVector<XalanNode*> NodeVectorType; 275 276 // Helper class to walk the tree and build everything... 277 class BuildWrapperTreeWalker : public XercesDOMWalker 278 { 279 public: 280 281 typedef XercesDOMWalker ParentType; 282 283 BuildWrapperTreeWalker( 284 XercesDocumentWrapper* theDocument, 285 XercesWrapperNavigator* theDocumentNavigator, 286 IndexType theStartIndex, 287 bool theBuildMapsFlag); 288 289 virtual 290 ~BuildWrapperTreeWalker(); 291 292 struct NavigatorStackEntryType 293 { NavigatorStackEntryTypeXALAN_CPP_NAMESPACE::XercesDocumentWrapper::BuildWrapperTreeWalker::NavigatorStackEntryType294 NavigatorStackEntryType( 295 XercesWrapperNavigator* theNavigator = 0, 296 XalanNode* theNode = 0) : 297 m_navigator(theNavigator), 298 m_node(theNode) 299 { 300 } 301 302 XercesWrapperNavigator* m_navigator; 303 304 XalanNode* m_node; 305 }; 306 307 typedef XalanVector<NavigatorStackEntryType> NavigatorStackType; 308 309 protected: 310 311 virtual bool 312 startNode(const DOMNodeType* node); 313 314 virtual bool 315 endNode(const DOMNodeType* node); 316 317 using ParentType::startNode; 318 using ParentType::endNode; 319 320 private: 321 322 XercesDocumentWrapper* m_document; 323 324 IndexType m_currentIndex; 325 326 NavigatorStackType m_parentNavigatorStack; 327 328 NavigatorStackType m_siblingNavigatorStack; 329 330 const bool m_buildMaps; 331 }; 332 333 334 /** 335 * Get a pooled string. If the string is not in the pool, 336 * add it. 337 * 338 * @param theString The string to pool. 339 * @return A const reference to the pooled string. 340 */ 341 const XalanDOMString& 342 getPooledString(const XalanDOMString& theString) const; 343 344 /** 345 * Get a pooled string. If the string is not in the pool, 346 * add it. 347 * 348 * @param theString The string to pool. 349 * @param theLength The length of the string. If XalanDOMString::npos, the string is assumed to be null-terminated. 350 * @return A const reference to the pooled string. 351 */ 352 const XalanDOMString& 353 getPooledString( 354 const XalanDOMChar* theString, 355 XalanDOMString::size_type theLength = XalanDOMString::npos) const; 356 357 bool getMappingMode() const358 getMappingMode() const 359 { 360 return m_mappingMode; 361 } 362 363 private: 364 365 // Destruction API... 366 void 367 destroyWrapperNode(XalanNode* theNode); 368 369 // Not implemented... 370 XercesDocumentWrapper(const XercesDocumentWrapper& theSource); 371 372 XercesDocumentWrapper& 373 operator=(const XercesDocumentWrapper& theRHS); 374 375 bool 376 operator==(const XercesDocumentWrapper& theRHS) const; 377 378 // Private delete function... 379 void 380 destroyNode(XalanNode* theNode); 381 382 // More internal implementation stuff... 383 384 // Factory methods for our implementation nodes... 385 XalanNode* 386 createWrapperNode( 387 const DOMNodeType* theXercesNode, 388 IndexType theIndex, 389 bool mapNode, 390 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 391 392 XercesDocumentTypeWrapper* 393 createWrapperNode( 394 const DOMDocumentType_Type* theDoctype, 395 IndexType theIndex, 396 bool mapNode, 397 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 398 399 XercesElementWrapper* 400 createWrapperNode( 401 const DOMElementType* theXercesNode, 402 IndexType theIndex, 403 bool mapNode, 404 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 405 406 XercesTextWrapper* 407 createWrapperNode( 408 const DOMTextType* theXercesNode, 409 IndexType theIndex, 410 bool mapNode, 411 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 412 413 XercesCommentWrapper* 414 createWrapperNode( 415 const DOMCommentType* theXercesNode, 416 IndexType theIndex, 417 bool mapNode, 418 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 419 420 XercesCDATASectionWrapper* 421 createWrapperNode( 422 const DOMCDATASectionType* theXercesNode, 423 IndexType theIndex, 424 bool mapNode, 425 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 426 427 XercesProcessingInstructionWrapper* 428 createWrapperNode( 429 const DOMProcessingInstructionType* theXercesNode, 430 IndexType theIndex, 431 bool mapNode, 432 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 433 434 XercesAttrWrapper* 435 createWrapperNode( 436 const DOMAttrType* theXercesNode, 437 IndexType theIndex, 438 bool mapNode, 439 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 440 441 XercesEntityWrapper* 442 createWrapperNode( 443 const DOMEntityType* theXercesNode, 444 IndexType theIndex, 445 bool mapNode, 446 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 447 448 XercesEntityReferenceWrapper* 449 createWrapperNode( 450 const DOMEntityReferenceType* theXercesNode, 451 IndexType theIndex, 452 bool mapNode, 453 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 454 455 XercesNotationWrapper* 456 createWrapperNode( 457 const DOMNotationType* theXercesNode, 458 IndexType theIndex, 459 bool mapNode, 460 XercesWrapperNavigator** theWrapperNodeNavigator = 0) const; 461 462 XercesWrapperNavigator& 463 createNavigator() const; 464 465 // This is a private helper class for building the tree... 466 friend class BuildWrapperTreeWalker; 467 468 const DOMDocument_Type* const m_xercesDocument; 469 470 XalanElement* m_documentElement; 471 472 mutable XercesWrapperToXalanNodeMap m_nodeMap; 473 474 mutable XercesWrapperNavigatorAllocator m_navigatorAllocator; 475 476 // Our navigator will be the first entry in m_navigators, 477 // but we'll cache this so access is faster... 478 XercesWrapperNavigator* m_navigator; 479 480 XercesNodeListWrapper m_children; 481 482 mutable NodeVectorType m_nodes; 483 484 mutable XercesDocumentTypeWrapper* m_doctype; 485 486 bool m_mappingMode; 487 488 bool m_indexValid; 489 490 const bool m_buildMaps; 491 492 mutable XercesElementWrapperAllocator m_elementAllocator; 493 494 mutable XercesTextWrapperAllocator m_textAllocator; 495 496 mutable XercesAttrWrapperAllocator m_attributeAllocator; 497 498 const XalanMemMgrAutoPtr<XalanDOMStringPool> m_stringPool; 499 }; 500 501 502 503 } 504 505 506 507 #endif // !defined(XERCESDOCUMENTWRAPPER_HEADER_GUARD_1357924680) 508