1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_OOX_CORE_CONTEXTHANDLER2_HXX
21 #define INCLUDED_OOX_CORE_CONTEXTHANDLER2_HXX
25 #include <oox/helper/attributelist.hxx>
26 #include <oox/helper/binaryinputstream.hxx>
27 #include <oox/core/contexthandler.hxx>
28 #include <oox/dllapi.h>
33 const sal_Int32 XML_ROOT_CONTEXT
= SAL_MAX_INT32
;
37 /** Helper class that provides a context stack.
39 Fragment handlers and context handlers derived from this helper class will
40 track the identifiers of the visited elements in a stack. The idea is to
41 use the same instance of a fragment handler or context handler to process
42 several nested elements in an XML stream. For that, the abstract function
43 onCreateContext() has to return 'this' for the passed element.
45 Derived classes have to implement the createFastChildContext(),
46 startFastElement(), characters(), and endFastElement() functions from the
47 com.sun.star.xml.sax.XFastContextHandler interface by simply forwarding
48 them to the respective implCreateChildContext(), implStartElement(),
49 implCharacters(), and implEndElement() functions of this helper. This is
50 implemented already in the classes ContextHandler2 and FragmentHandler2.
51 The new abstract functions have to be implemented according to the elements
54 Similarly, for binary import, derived classes have to forward the
55 createRecordContext(), startRecord(), and endRecord() functions from the
56 ContextHandler class to the implCreateRecordContext(), implStartRecord(),
57 and implEndRecord() functions of this helper. Again, this is implemented
58 already in the classes ContextHandler2 and FragmentHandler2.
60 class OOX_DLLPUBLIC ContextHandler2Helper
63 explicit ContextHandler2Helper( bool bEnableTrimSpace
);
64 explicit ContextHandler2Helper( const ContextHandler2Helper
& rParent
);
65 virtual ~ContextHandler2Helper();
67 // allow instances to be stored in ::rtl::Reference
68 virtual void SAL_CALL
acquire() throw() = 0;
69 virtual void SAL_CALL
release() throw() = 0;
71 // interface --------------------------------------------------------------
73 /** Will be called to create a context handler for the passed element.
75 Usually 'this' can be returned to improve performance by reusing the
76 same instance to process several elements. Used by OOXML import only.
78 virtual ContextHandlerRef
onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
) = 0;
80 /** Will be called when a new element has been started.
82 This function is called at the context handler returned from
83 onCreateContext(), or, for root elements of an XML stream, at the
84 fragment handler itself.
86 The current element identifier can be accessed with getCurrentElement()
87 or isCurrentElement(). Used by OOXML import only.
89 virtual void onStartElement( const AttributeList
& rAttribs
) = 0;
91 /** Will be called before a new child element starts, or if the current
92 element is about to be left.
94 This helper function collects all text fragments received by the
95 characters() function (such as encoded characters which are passed in
96 separate calls to the characters() function), and passes the
97 concatenated and trimmed string.
99 The current element identifier can be accessed with getCurrentElement()
100 or isCurrentElement(). Used by OOXML import only.
102 virtual void onCharacters( const OUString
& rChars
) = 0;
104 /** Will be called when the current element is about to be left.
106 The current element identifier can be accessed with getCurrentElement()
107 or isCurrentElement(). Used by OOXML import only.
109 virtual void onEndElement() = 0;
111 /** Will be called to create a context handler for the passed record.
113 Usually 'this' can be returned to improve performance by reusing the
114 same instance to process several records. Used by BIFF import only.
116 virtual ContextHandlerRef
onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
) = 0;
118 /** Will be called when a new record block in a binary stream has been
121 The current record identifier can be accessed with getCurrentElement()
122 or isCurrentElement(). Used by BIFF import only.
124 virtual void onStartRecord( SequenceInputStream
& rStrm
) = 0;
126 /** Will be called when the current record block is about to be left.
128 The current record identifier can be accessed with getCurrentElement()
129 or isCurrentElement(). Used by BIFF import only.
131 virtual void onEndRecord() = 0;
133 // helpers ----------------------------------------------------------------
135 /** Returns the identifier of the currently processed element. Ignores MCE elements in stack */
136 sal_Int32
getCurrentElement() const;
138 /** Returns the identifier of the currently processed element - Including MCE root elements */
139 sal_Int32
getCurrentElementWithMce() const;
141 /** Returns true, if nElement contains the identifier of the currently
142 processed element. */
143 bool isCurrentElement( sal_Int32 nElement
) const
144 { return getCurrentElement() == nElement
; }
146 /** Returns true, if either nElement1 or nElement2 contain the identifier
147 of the currently processed element. */
148 bool isCurrentElement( sal_Int32 nElement1
, sal_Int32 nElement2
) const
149 { return isCurrentElement( nElement1
) || isCurrentElement( nElement2
); }
151 /** Returns the identifier of the specified parent element. */
152 sal_Int32
getParentElement( sal_Int32 nCountBack
= 1 ) const;
154 /** Returns true, if nElement contains the identifier of the specified
156 bool isParentElement( sal_Int32 nElement
, sal_Int32 nCountBack
= 1 ) const
157 { return getParentElement( nCountBack
) == nElement
; }
159 /** Returns true, if the element currently processed is the root element of
160 the context or fragment handler. */
161 bool isRootElement() const;
163 // implementation ---------------------------------------------------------
166 /** Must be called from createFastChildContext() in derived classes. */
167 ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XFastContextHandler
>
168 implCreateChildContext(
170 const ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XFastAttributeList
>& rxAttribs
);
172 /** Must be called from startFastElement() in derived classes. */
173 void implStartElement(
175 const ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XFastAttributeList
>& rxAttribs
);
177 /** Must be called from characters() in derived classes. */
178 void implCharacters( const OUString
& rChars
);
180 /** Must be called from endFastElement() in derived classes. */
181 void implEndElement( sal_Int32 nElement
);
183 /** Must be called from createRecordContext() in derived classes. */
184 ContextHandlerRef
implCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
);
186 /** Must be called from startRecord() in derived classes. */
187 void implStartRecord( sal_Int32 nRecId
, SequenceInputStream
& rStrm
);
189 /** Must be called from endRecord() in derived classes. */
190 void implEndRecord( sal_Int32 nRecId
);
193 ContextHandler2Helper
& operator=( const ContextHandler2Helper
& ) SAL_DELETED_FUNCTION
;
195 ElementInfo
& pushElementInfo( sal_Int32 nElement
);
196 void popElementInfo();
197 void processCollectedChars();
200 typedef std::vector
< ElementInfo
> ContextStack
;
201 typedef std::shared_ptr
< ContextStack
> ContextStackRef
;
203 ContextStackRef mxContextStack
; ///< Stack of all processed elements.
204 size_t mnRootStackSize
; ///< Stack size on construction time.
207 bool mbEnableTrimSpace
; ///< True = trim whitespace in characters().
210 class OOX_DLLPUBLIC ContextHandler2
: public ContextHandler
, public ContextHandler2Helper
213 explicit ContextHandler2( ContextHandler2Helper
& rParent
);
214 virtual ~ContextHandler2();
216 // resolve ambiguity from base classes
217 virtual void SAL_CALL
acquire() throw() SAL_OVERRIDE
{ ContextHandler::acquire(); }
218 virtual void SAL_CALL
release() throw() SAL_OVERRIDE
{ ContextHandler::release(); }
220 // com.sun.star.xml.sax.XFastContextHandler interface ---------------------
222 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XFastContextHandler
> SAL_CALL
223 createFastChildContext(
225 const ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XFastAttributeList
>& rxAttribs
)
226 throw( ::com::sun::star::xml::sax::SAXException
,
227 ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_FINAL SAL_OVERRIDE
;
229 virtual void SAL_CALL
startFastElement(
231 const ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XFastAttributeList
>& rxAttribs
)
232 throw( ::com::sun::star::xml::sax::SAXException
,
233 ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_FINAL SAL_OVERRIDE
;
235 virtual void SAL_CALL
characters( const OUString
& rChars
)
236 throw( ::com::sun::star::xml::sax::SAXException
,
237 ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_FINAL SAL_OVERRIDE
;
239 virtual void SAL_CALL
endFastElement( sal_Int32 nElement
)
240 throw( ::com::sun::star::xml::sax::SAXException
,
241 ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_FINAL SAL_OVERRIDE
;
243 // oox.core.ContextHandler interface --------------------------------------
245 virtual ContextHandlerRef
createRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
) SAL_OVERRIDE
;
246 virtual void startRecord( sal_Int32 nRecId
, SequenceInputStream
& rStrm
) SAL_OVERRIDE
;
247 virtual void endRecord( sal_Int32 nRecId
) SAL_OVERRIDE
;
249 // oox.core.ContextHandler2Helper interface -------------------------------
251 virtual ContextHandlerRef
onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
) SAL_OVERRIDE
;
252 virtual void onStartElement( const AttributeList
& rAttribs
) SAL_OVERRIDE
;
253 virtual void onCharacters( const OUString
& rChars
) SAL_OVERRIDE
;
254 virtual void onEndElement() SAL_OVERRIDE
;
256 virtual ContextHandlerRef
onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
) SAL_OVERRIDE
;
257 virtual void onStartRecord( SequenceInputStream
& rStrm
) SAL_OVERRIDE
;
258 virtual void onEndRecord() SAL_OVERRIDE
;
266 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */