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(FORMATTERTOSOURCETREE_HEADER_GUARD_1357924680)
19 #define FORMATTERTOSOURCETREE_HEADER_GUARD_1357924680
20 
21 
22 
23 // Base include file.  Must be first.
24 #include <xalanc/XalanSourceTree/XalanSourceTreeDefinitions.hpp>
25 
26 
27 
28 #include <xalanc/Include/XalanVector.hpp>
29 
30 
31 
32 // Base class header file.
33 #include <xalanc/PlatformSupport/FormatterListener.hpp>
34 
35 
36 
37 #include <xalanc/XalanDOM/XalanDOMString.hpp>
38 
39 
40 
41 namespace XALAN_CPP_NAMESPACE {
42 
43 
44 
45 class PrefixResolver;
46 class XalanNode;
47 class XalanSourceTreeDocument;
48 class XalanSourceTreeDocumentFragment;
49 class XalanSourceTreeElement;
50 
51 
52 
53 /**
54  * This class takes SAX events (in addition to some extra events that SAX
55  * doesn't handle yet) and adds the result to a document or document fragment.
56  */
57 class XALAN_XALANSOURCETREE_EXPORT FormatterToSourceTree : public FormatterListener
58 {
59 public:
60 
61     typedef XalanVector<XalanSourceTreeElement*>            ElementStackType;
62     typedef XalanVector<XalanNode*>                         LastChildStackType;
63 
64     enum { eDefaultStackSize = 50, eDefaultTextBufferSize = 100 };
65 
66     /**
67      * Perform static initialization.  See class XalanSourceTreeInit.
68      */
69     static void
70     initialize(MemoryManager& theManager);
71 
72     /**
73      * Perform static shut down.  See class XalanSourceTreeInit.
74      */
75     static void
76     terminate();
77 
78 
79     /**
80      * Construct a FormatterToSourceTree instance.  it will add the nodes
81      * to the document.
82      *
83      * @param theDocument The document for nodes
84      */
85     explicit
86     FormatterToSourceTree(
87             MemoryManager&          theManager XALAN_DEFAULT_CONSTRUCTOR_MEMMGR,
88             XalanSourceTreeDocument*    theDocument = 0);
89 
90     /**
91      * Construct a FormatterToSourceTree instance.  it will add the nodes
92      * to the document fragment.
93      *
94      * @param theDocument The document for nodes
95      * @param theDocumentFragment The document fragment for nodes
96      */
97     FormatterToSourceTree(
98             XalanSourceTreeDocument*            theDocument,
99             XalanSourceTreeDocumentFragment*    theDocumentFragment,
100             MemoryManager&                  theManager XALAN_DEFAULT_MEMMGR);
101 
102     virtual
103     ~FormatterToSourceTree();
104 
105 
106     XalanSourceTreeDocument*
getDocument() const107     getDocument() const
108     {
109         return m_document;
110     }
111 
112     void
setDocument(XalanSourceTreeDocument * theDocument)113     setDocument(XalanSourceTreeDocument*    theDocument)
114     {
115         m_document = theDocument;
116     }
117 
118     XalanSourceTreeDocumentFragment*
getDocumentFragment() const119     getDocumentFragment() const
120     {
121         return m_documentFragment;
122     }
123 
124     void
setDocumentFragment(XalanSourceTreeDocumentFragment * theDocumentFragment)125     setDocumentFragment(XalanSourceTreeDocumentFragment*    theDocumentFragment)
126     {
127         m_documentFragment = theDocumentFragment;
128     }
129 
130     XalanSourceTreeElement*
getCurrentElement() const131     getCurrentElement() const
132     {
133         return m_currentElement;
134     }
135 
136     void
setCurrentElement(XalanSourceTreeElement * theElement)137     setCurrentElement(XalanSourceTreeElement*   theElement)
138     {
139         m_currentElement = theElement;
140     }
141 
142     // These methods are inherited from DocumentHandler ...
143 
144     virtual void
145     charactersRaw(
146             const XMLCh* const  chars,
147             const size_type     length);
148 
149     virtual void
150     comment(const XMLCh* const  data);
151 
152     virtual void
153     cdata(
154             const XMLCh* const  ch,
155             const size_type     length);
156 
157     virtual void
158     entityReference(const XMLCh* const  name);
159 
160     virtual void
161     setDocumentLocator(const Locator* const     locator);
162 
163     virtual void
164     startDocument();
165 
166     virtual void
167     endDocument();
168 
169     virtual void
170     startElement(
171                 const XMLCh* const  name,
172                 AttributeListType&  attrs);
173 
174     virtual void
175     endElement(const XMLCh* const   name);
176 
177     virtual void
178     characters(
179                 const XMLCh* const  chars,
180                 const size_type     length);
181 
182     virtual void
183     ignorableWhitespace(
184                 const XMLCh* const  chars,
185                 const size_type     length);
186 
187     virtual void
188     processingInstruction(
189             const XMLCh* const  target,
190             const XMLCh* const  data);
191 
192     virtual void
193     resetDocument();
194 
195 private:
196 
197     // Some utility functions...
198     void
199     processAccumulatedText();
200 
201     XalanSourceTreeElement*
202     createElementNode(
203             const XalanDOMChar*         name,
204             AttributeListType&          attrs,
205             XalanSourceTreeElement*     theParentElement);
206 
207     void
208     doCharacters(
209             const XalanDOMChar*     chars,
210             size_type               length);
211 
212     void
213     doProcessingInstruction(
214             const XalanDOMChar*     target,
215             const XalanDOMChar*     data);
216 
217 
218     // Data members...
219     XalanSourceTreeDocument*            m_document;
220 
221     XalanSourceTreeDocumentFragment*    m_documentFragment;
222 
223     XalanSourceTreeElement*             m_currentElement;
224 
225     ElementStackType                    m_elementStack;
226 
227     // The last child appended to the current element.  This is
228     // an important optimization, because XalanSourceTreeElement
229     // does not have a pointer to it's last child.  Without this,
230     // appending a child becomes a linear search.
231     XalanNode*                          m_lastChild;
232 
233     // Stack of last children appended.  There is a one-to-one
234     // correspondance to the entries in m_elementStack.
235     LastChildStackType                  m_lastChildStack;
236 
237     XalanDOMString                      m_textBuffer;
238 };
239 
240 
241 
242 }
243 
244 
245 
246 #endif  // FORMATTERTOSOURCETREE_HEADER_GUARD_1357924680
247