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