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