xref: /AOO41X/main/oox/inc/oox/core/contexthandler2.hxx (revision e35081216278e1848f1c12af2e117a766f306f4b)
1*e3508121SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*e3508121SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*e3508121SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*e3508121SAndrew Rist  * distributed with this work for additional information
6*e3508121SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*e3508121SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*e3508121SAndrew Rist  * "License"); you may not use this file except in compliance
9*e3508121SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*e3508121SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*e3508121SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*e3508121SAndrew Rist  * software distributed under the License is distributed on an
15*e3508121SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*e3508121SAndrew Rist  * KIND, either express or implied.  See the License for the
17*e3508121SAndrew Rist  * specific language governing permissions and limitations
18*e3508121SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*e3508121SAndrew Rist  *************************************************************/
21*e3508121SAndrew Rist 
22*e3508121SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef OOX_CORE_CONTEXTHANDLER2_HXX
25cdf0e10cSrcweir #define OOX_CORE_CONTEXTHANDLER2_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <vector>
28cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
29cdf0e10cSrcweir #include "oox/helper/attributelist.hxx"
30cdf0e10cSrcweir #include "oox/helper/binaryinputstream.hxx"
31cdf0e10cSrcweir #include "oox/core/contexthandler.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace oox {
34cdf0e10cSrcweir namespace core {
35cdf0e10cSrcweir 
36cdf0e10cSrcweir // ============================================================================
37cdf0e10cSrcweir 
38cdf0e10cSrcweir const sal_Int32 XML_ROOT_CONTEXT    = SAL_MAX_INT32;
39cdf0e10cSrcweir 
40cdf0e10cSrcweir // ============================================================================
41cdf0e10cSrcweir 
42cdf0e10cSrcweir struct ElementInfo;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir /** Helper class that provides a context stack.
45cdf0e10cSrcweir 
46cdf0e10cSrcweir     Fragment handlers and context handlers derived from this helper class will
47cdf0e10cSrcweir     track the identifiers of the visited elements in a stack. The idea is to
48cdf0e10cSrcweir     use the same instance of a fragment handler or context handler to process
49cdf0e10cSrcweir     several nested elements in an XML stream. For that, the abstract function
50cdf0e10cSrcweir     onCreateContext() has to return 'this' for the passed element.
51cdf0e10cSrcweir 
52cdf0e10cSrcweir     Derived classes have to implement the createFastChildContext(),
53cdf0e10cSrcweir     startFastElement(), characters(), and endFastElement() functions from the
54cdf0e10cSrcweir     com.sun.star.xml.sax.XFastContextHandler interface by simply forwarding
55cdf0e10cSrcweir     them to the respective implCreateChildContext(), implStartElement(),
56cdf0e10cSrcweir     implCharacters(), and implEndElement() functions of this helper. This is
57cdf0e10cSrcweir     implemented already in the classes ContextHandler2 and FragmentHandler2.
58cdf0e10cSrcweir     The new abstract functions have to be implemented according to the elements
59cdf0e10cSrcweir     to be processed.
60cdf0e10cSrcweir 
61cdf0e10cSrcweir     Similarly, for binary import, derived classes have to forward the
62cdf0e10cSrcweir     createRecordContext(), startRecord(), and endRecord() functions from the
63cdf0e10cSrcweir     ContextHandler class to the implCreateRecordContext(), implStartRecord(),
64cdf0e10cSrcweir     and implEndRecord() functions of this helper. Again, this is implemented
65cdf0e10cSrcweir     already in the classes ContextHandler2 and FragmentHandler2.
66cdf0e10cSrcweir  */
67cdf0e10cSrcweir class ContextHandler2Helper
68cdf0e10cSrcweir {
69cdf0e10cSrcweir public:
70cdf0e10cSrcweir     explicit            ContextHandler2Helper( bool bEnableTrimSpace );
71cdf0e10cSrcweir     explicit            ContextHandler2Helper( const ContextHandler2Helper& rParent );
72cdf0e10cSrcweir     virtual             ~ContextHandler2Helper();
73cdf0e10cSrcweir 
74cdf0e10cSrcweir     // allow instances to be stored in ::rtl::Reference
75cdf0e10cSrcweir     virtual void SAL_CALL acquire() throw() = 0;
76cdf0e10cSrcweir     virtual void SAL_CALL release() throw() = 0;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     // interface --------------------------------------------------------------
79cdf0e10cSrcweir 
80cdf0e10cSrcweir     /** Will be called to create a context handler for the passed element.
81cdf0e10cSrcweir 
82cdf0e10cSrcweir         Usually 'this' can be returned to improve performance by reusing the
83cdf0e10cSrcweir         same instance to process several elements. Used by OOXML import only.
84cdf0e10cSrcweir      */
85cdf0e10cSrcweir     virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) = 0;
86cdf0e10cSrcweir 
87cdf0e10cSrcweir     /** Will be called when a new element has been started.
88cdf0e10cSrcweir 
89cdf0e10cSrcweir         This function is called at the context handler returned from
90cdf0e10cSrcweir         onCreateContext(), or, for root elements of an XML stream, at the
91cdf0e10cSrcweir         fragment handler itself.
92cdf0e10cSrcweir 
93cdf0e10cSrcweir         The current element identifier can be accessed with getCurrentElement()
94cdf0e10cSrcweir         or isCurrentElement(). Used by OOXML import only.
95cdf0e10cSrcweir      */
96cdf0e10cSrcweir     virtual void        onStartElement( const AttributeList& rAttribs ) = 0;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     /** Will be called before a new child element starts, or if the current
99cdf0e10cSrcweir         element is about to be left.
100cdf0e10cSrcweir 
101cdf0e10cSrcweir         This helper function collects all text fragments received by the
102cdf0e10cSrcweir         characters() function (such as encoded characters which are passed in
103cdf0e10cSrcweir         separate calls to the characters() function), and passes the
104cdf0e10cSrcweir         concatenated and trimmed string.
105cdf0e10cSrcweir 
106cdf0e10cSrcweir         The current element identifier can be accessed with getCurrentElement()
107cdf0e10cSrcweir         or isCurrentElement(). Used by OOXML import only.
108cdf0e10cSrcweir      */
109cdf0e10cSrcweir     virtual void        onCharacters( const ::rtl::OUString& rChars ) = 0;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     /** Will be called when the current element is about to be left.
112cdf0e10cSrcweir 
113cdf0e10cSrcweir         The current element identifier can be accessed with getCurrentElement()
114cdf0e10cSrcweir         or isCurrentElement(). Used by OOXML import only.
115cdf0e10cSrcweir      */
116cdf0e10cSrcweir     virtual void        onEndElement() = 0;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     /** Will be called to create a context handler for the passed record.
119cdf0e10cSrcweir 
120cdf0e10cSrcweir         Usually 'this' can be returned to improve performance by reusing the
121cdf0e10cSrcweir         same instance to process several records. Used by BIFF import only.
122cdf0e10cSrcweir      */
123cdf0e10cSrcweir     virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) = 0;
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     /** Will be called when a new record block in a binary stream has been
126cdf0e10cSrcweir         started.
127cdf0e10cSrcweir 
128cdf0e10cSrcweir         The current record identifier can be accessed with getCurrentElement()
129cdf0e10cSrcweir         or isCurrentElement(). Used by BIFF import only.
130cdf0e10cSrcweir      */
131cdf0e10cSrcweir     virtual void        onStartRecord( SequenceInputStream& rStrm ) = 0;
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     /** Will be called when the current record block is about to be left.
134cdf0e10cSrcweir 
135cdf0e10cSrcweir         The current record identifier can be accessed with getCurrentElement()
136cdf0e10cSrcweir         or isCurrentElement(). Used by BIFF import only.
137cdf0e10cSrcweir      */
138cdf0e10cSrcweir     virtual void        onEndRecord() = 0;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir     // helpers ----------------------------------------------------------------
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     /** Returns the identifier of the currently processed element. */
143cdf0e10cSrcweir     sal_Int32           getCurrentElement() const;
144cdf0e10cSrcweir 
145cdf0e10cSrcweir     /** Returns true, if nElement contains the identifier of the currently
146cdf0e10cSrcweir         processed element. */
isCurrentElement(sal_Int32 nElement) const147cdf0e10cSrcweir     inline bool         isCurrentElement( sal_Int32 nElement ) const
148cdf0e10cSrcweir                             { return getCurrentElement() == nElement; }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     /** Returns true, if either nElement1 or nElement2 contain the identifier
151cdf0e10cSrcweir         of the currently processed element. */
isCurrentElement(sal_Int32 nElement1,sal_Int32 nElement2) const152cdf0e10cSrcweir     inline bool         isCurrentElement( sal_Int32 nElement1, sal_Int32 nElement2 ) const
153cdf0e10cSrcweir                             { return isCurrentElement( nElement1 ) || isCurrentElement( nElement2 ); }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir     /** Returns the identifier of the specified parent element. */
156cdf0e10cSrcweir     sal_Int32           getParentElement( sal_Int32 nCountBack = 1 ) const;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     /** Returns true, if nElement contains the identifier of the specified
159cdf0e10cSrcweir         parent element. */
isParentElement(sal_Int32 nElement,sal_Int32 nCountBack=1) const160cdf0e10cSrcweir     inline sal_Int32    isParentElement( sal_Int32 nElement, sal_Int32 nCountBack = 1 ) const
161cdf0e10cSrcweir                             { return getParentElement( nCountBack ) == nElement; }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir     /** Returns true, if the element currently processed is the root element of
164cdf0e10cSrcweir         the context or fragment handler. */
165cdf0e10cSrcweir     bool                isRootElement() const;
166cdf0e10cSrcweir 
167cdf0e10cSrcweir     // implementation ---------------------------------------------------------
168cdf0e10cSrcweir 
169cdf0e10cSrcweir protected:
170cdf0e10cSrcweir     /** Must be called from createFastChildContext() in derived classes. */
171cdf0e10cSrcweir     ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler >
172cdf0e10cSrcweir                         implCreateChildContext(
173cdf0e10cSrcweir                             sal_Int32 nElement,
174cdf0e10cSrcweir                             const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs );
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     /** Must be called from startFastElement() in derived classes. */
177cdf0e10cSrcweir     void                implStartElement(
178cdf0e10cSrcweir                             sal_Int32 nElement,
179cdf0e10cSrcweir                             const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs );
180cdf0e10cSrcweir 
181cdf0e10cSrcweir     /** Must be called from characters() in derived classes. */
182cdf0e10cSrcweir     void                implCharacters( const ::rtl::OUString& rChars );
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     /** Must be called from endFastElement() in derived classes. */
185cdf0e10cSrcweir     void                implEndElement( sal_Int32 nElement );
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     /** Must be called from createRecordContext() in derived classes. */
188cdf0e10cSrcweir     ContextHandlerRef   implCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir     /** Must be called from startRecord() in derived classes. */
191cdf0e10cSrcweir     void                implStartRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
192cdf0e10cSrcweir 
193cdf0e10cSrcweir     /** Must be called from endRecord() in derived classes. */
194cdf0e10cSrcweir     void                implEndRecord( sal_Int32 nRecId );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir private:
197cdf0e10cSrcweir     ContextHandler2Helper& operator=( const ContextHandler2Helper& );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     ElementInfo&        pushElementInfo( sal_Int32 nElement );
200cdf0e10cSrcweir     void                popElementInfo();
201cdf0e10cSrcweir     void                processCollectedChars();
202cdf0e10cSrcweir 
203cdf0e10cSrcweir private:
204cdf0e10cSrcweir     typedef ::std::vector< ElementInfo >        ContextStack;
205cdf0e10cSrcweir     typedef ::boost::shared_ptr< ContextStack > ContextStackRef;
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     ContextStackRef     mxContextStack;     /// Stack of all processed elements.
208cdf0e10cSrcweir     size_t              mnRootStackSize;    /// Stack size on construction time.
209cdf0e10cSrcweir     bool                mbEnableTrimSpace;  /// True = trim whitespace in characters().
210cdf0e10cSrcweir };
211cdf0e10cSrcweir 
212cdf0e10cSrcweir // ============================================================================
213cdf0e10cSrcweir 
214cdf0e10cSrcweir class ContextHandler2 : public ContextHandler, public ContextHandler2Helper
215cdf0e10cSrcweir {
216cdf0e10cSrcweir public:
217cdf0e10cSrcweir     explicit            ContextHandler2( ContextHandler2Helper& rParent );
218cdf0e10cSrcweir     virtual             ~ContextHandler2();
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     // resolve ambiguity from base classes
acquire()221cdf0e10cSrcweir     virtual void SAL_CALL acquire() throw() { ContextHandler::acquire(); }
release()222cdf0e10cSrcweir     virtual void SAL_CALL release() throw() { ContextHandler::release(); }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir     // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
225cdf0e10cSrcweir 
226cdf0e10cSrcweir     virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL
227cdf0e10cSrcweir                         createFastChildContext(
228cdf0e10cSrcweir                             sal_Int32 nElement,
229cdf0e10cSrcweir                             const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
230cdf0e10cSrcweir                             throw(  ::com::sun::star::xml::sax::SAXException,
231cdf0e10cSrcweir                                     ::com::sun::star::uno::RuntimeException );
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     virtual void SAL_CALL startFastElement(
234cdf0e10cSrcweir                             sal_Int32 nElement,
235cdf0e10cSrcweir                             const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs )
236cdf0e10cSrcweir                             throw(  ::com::sun::star::xml::sax::SAXException,
237cdf0e10cSrcweir                                     ::com::sun::star::uno::RuntimeException );
238cdf0e10cSrcweir 
239cdf0e10cSrcweir     virtual void SAL_CALL characters( const ::rtl::OUString& rChars )
240cdf0e10cSrcweir                             throw(  ::com::sun::star::xml::sax::SAXException,
241cdf0e10cSrcweir                                     ::com::sun::star::uno::RuntimeException );
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     virtual void SAL_CALL endFastElement( sal_Int32 nElement )
244cdf0e10cSrcweir                             throw(  ::com::sun::star::xml::sax::SAXException,
245cdf0e10cSrcweir                                     ::com::sun::star::uno::RuntimeException );
246cdf0e10cSrcweir 
247cdf0e10cSrcweir     // oox.core.ContextHandler interface --------------------------------------
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     virtual ContextHandlerRef createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
250cdf0e10cSrcweir     virtual void        startRecord( sal_Int32 nRecId, SequenceInputStream& rStrm );
251cdf0e10cSrcweir     virtual void        endRecord( sal_Int32 nRecId );
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     // oox.core.ContextHandler2Helper interface -------------------------------
254cdf0e10cSrcweir 
255cdf0e10cSrcweir     virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs );
256cdf0e10cSrcweir     virtual void        onStartElement( const AttributeList& rAttribs );
257cdf0e10cSrcweir     virtual void        onCharacters( const ::rtl::OUString& rChars );
258cdf0e10cSrcweir     virtual void        onEndElement();
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm );
261cdf0e10cSrcweir     virtual void        onStartRecord( SequenceInputStream& rStrm );
262cdf0e10cSrcweir     virtual void        onEndRecord();
263cdf0e10cSrcweir };
264cdf0e10cSrcweir 
265cdf0e10cSrcweir // ============================================================================
266cdf0e10cSrcweir 
267cdf0e10cSrcweir } // namespace core
268cdf0e10cSrcweir } // namespace oox
269cdf0e10cSrcweir 
270cdf0e10cSrcweir #endif
271