1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: contexthandler2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/core/contexthandler2.hxx"
32 #include <rtl/ustrbuf.hxx>
34 using ::rtl::OUString
;
35 using ::rtl::OUStringBuffer
;
36 using ::com::sun::star::uno::Reference
;
37 using ::com::sun::star::uno::RuntimeException
;
38 using ::com::sun::star::xml::sax::SAXException
;
39 using ::com::sun::star::xml::sax::XFastAttributeList
;
40 using ::com::sun::star::xml::sax::XFastContextHandler
;
45 // ============================================================================
47 /** Information about a processed context element. */
50 OUStringBuffer maCurrChars
; /// Collected characters from context.
51 OUStringBuffer maFinalChars
; /// Finalized (stipped) characters.
52 sal_Int32 mnElement
; /// The element identifier.
53 bool mbTrimSpaces
; /// True = trims leading/trailing spaces from text data.
55 explicit ContextInfo();
58 ContextInfo::ContextInfo() :
59 mnElement( XML_TOKEN_INVALID
),
64 // ============================================================================
66 ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace
) :
67 mxContextStack( new ContextStack
),
69 mbEnableTrimSpace( bEnableTrimSpace
)
71 pushContextInfo( XML_ROOT_CONTEXT
);
74 ContextHandler2Helper::ContextHandler2Helper( const ContextHandler2Helper
& rParent
) :
75 mxContextStack( rParent
.mxContextStack
),
76 mnRootStackSize( rParent
.mxContextStack
->size() ),
77 mbEnableTrimSpace( rParent
.mbEnableTrimSpace
)
81 ContextHandler2Helper::~ContextHandler2Helper()
85 sal_Int32
ContextHandler2Helper::getCurrentElement() const
87 return mxContextStack
->empty() ? XML_ROOT_CONTEXT
: mxContextStack
->back().mnElement
;
90 sal_Int32
ContextHandler2Helper::getPreviousElement( sal_Int32 nCountBack
) const
92 if( (nCountBack
< 0) || (mxContextStack
->size() < static_cast< size_t >( nCountBack
)) )
93 return XML_TOKEN_INVALID
;
94 return (mxContextStack
->size() == static_cast< size_t >( nCountBack
)) ?
95 XML_ROOT_CONTEXT
: (*mxContextStack
)[ mxContextStack
->size() - nCountBack
- 1 ].mnElement
;
98 bool ContextHandler2Helper::isRootElement() const
100 return mxContextStack
->size() == mnRootStackSize
+ 1;
103 Reference
< XFastContextHandler
> ContextHandler2Helper::implCreateChildContext( sal_Int32 nElement
, const Reference
< XFastAttributeList
>& rxAttribs
)
105 appendCollectedChars();
106 ContextHandlerRef xContext
= onCreateContext( nElement
, AttributeList( rxAttribs
) );
107 return Reference
< XFastContextHandler
>( xContext
.get() );
110 void ContextHandler2Helper::implStartCurrentContext( sal_Int32 nElement
, const Reference
< XFastAttributeList
>& rxAttribs
)
112 AttributeList
aAttribs( rxAttribs
);
113 pushContextInfo( nElement
).mbTrimSpaces
= aAttribs
.getToken( NMSP_XML
| XML_space
, XML_TOKEN_INVALID
) != XML_preserve
;
114 onStartElement( aAttribs
);
117 void ContextHandler2Helper::implCharacters( const OUString
& rChars
)
119 // #i76091# collect characters until context ends
120 if( !mxContextStack
->empty() )
121 mxContextStack
->back().maCurrChars
.append( rChars
);
124 void ContextHandler2Helper::implEndCurrentContext( sal_Int32 nElement
)
126 (void)nElement
; // prevent "unused parameter" warning in product build
127 OSL_ENSURE( getCurrentElement() == nElement
, "ContextHandler2Helper::implEndCurrentContext - context stack broken" );
128 if( !mxContextStack
->empty() )
130 // #i76091# process collected characters
131 appendCollectedChars();
132 // finalize the current context and pop context info from stack
133 onEndElement( mxContextStack
->back().maFinalChars
.makeStringAndClear() );
138 ContextHandlerRef
ContextHandler2Helper::implCreateRecordContext( sal_Int32 nRecId
, RecordInputStream
& rStrm
)
140 return onCreateRecordContext( nRecId
, rStrm
);
143 void ContextHandler2Helper::implStartRecord( sal_Int32 nRecId
, RecordInputStream
& rStrm
)
145 pushContextInfo( nRecId
);
146 onStartRecord( rStrm
);
149 void ContextHandler2Helper::implEndRecord( sal_Int32 nRecId
)
151 (void)nRecId
; // prevent "unused parameter" warning in product build
152 OSL_ENSURE( getCurrentElement() == nRecId
, "ContextHandler2Helper::implEndRecord - context stack broken" );
153 if( !mxContextStack
->empty() )
155 // finalize the current context and pop context info from stack
161 ContextInfo
& ContextHandler2Helper::pushContextInfo( sal_Int32 nElement
)
163 mxContextStack
->resize( mxContextStack
->size() + 1 );
164 ContextInfo
& rInfo
= mxContextStack
->back();
165 rInfo
.mnElement
= nElement
;
169 void ContextHandler2Helper::popContextInfo()
171 OSL_ENSURE( !mxContextStack
->empty(), "ContextHandler2Helper::popContextInfo - context stack broken" );
172 if( !mxContextStack
->empty() )
173 mxContextStack
->pop_back();
176 void ContextHandler2Helper::appendCollectedChars()
178 OSL_ENSURE( !mxContextStack
->empty(), "ContextHandler2Helper::appendCollectedChars - no context info" );
179 ContextInfo
& rInfo
= mxContextStack
->back();
180 if( rInfo
.maCurrChars
.getLength() > 0 )
182 OUString aChars
= rInfo
.maCurrChars
.makeStringAndClear();
183 rInfo
.maFinalChars
.append( (mbEnableTrimSpace
&& rInfo
.mbTrimSpaces
) ? aChars
.trim() : aChars
);
187 // ============================================================================
189 ContextHandler2::ContextHandler2( ContextHandler2Helper
& rParent
) :
190 ContextHandler( rParent
.queryContextHandler() ),
191 ContextHandler2Helper( rParent
)
195 ContextHandler2::~ContextHandler2()
199 ContextHandler
& ContextHandler2::queryContextHandler()
204 // com.sun.star.xml.sax.XFastContextHandler interface -------------------------
206 Reference
< XFastContextHandler
> SAL_CALL
ContextHandler2::createFastChildContext(
207 sal_Int32 nElement
, const Reference
< XFastAttributeList
>& rxAttribs
) throw( SAXException
, RuntimeException
)
209 return implCreateChildContext( nElement
, rxAttribs
);
212 void SAL_CALL
ContextHandler2::startFastElement(
213 sal_Int32 nElement
, const Reference
< XFastAttributeList
>& rxAttribs
) throw( SAXException
, RuntimeException
)
215 implStartCurrentContext( nElement
, rxAttribs
);
218 void SAL_CALL
ContextHandler2::characters( const OUString
& rChars
) throw( SAXException
, RuntimeException
)
220 implCharacters( rChars
);
223 void SAL_CALL
ContextHandler2::endFastElement( sal_Int32 nElement
) throw( SAXException
, RuntimeException
)
225 implEndCurrentContext( nElement
);
228 // oox.core.RecordContext interface -------------------------------------------
230 ContextHandlerRef
ContextHandler2::createRecordContext( sal_Int32 nRecId
, RecordInputStream
& rStrm
)
232 return implCreateRecordContext( nRecId
, rStrm
);
235 void ContextHandler2::startRecord( sal_Int32 nRecId
, RecordInputStream
& rStrm
)
237 implStartRecord( nRecId
, rStrm
);
240 void ContextHandler2::endRecord( sal_Int32 nRecId
)
242 implEndRecord( nRecId
);
245 // oox.core.ContextHandler2Helper interface -----------------------------------
247 ContextHandlerRef
ContextHandler2::onCreateContext( sal_Int32
, const AttributeList
& )
252 void ContextHandler2::onStartElement( const AttributeList
& )
256 void ContextHandler2::onEndElement( const OUString
& )
260 ContextHandlerRef
ContextHandler2::onCreateRecordContext( sal_Int32
, RecordInputStream
& )
265 void ContextHandler2::onStartRecord( RecordInputStream
& )
269 void ContextHandler2::onEndRecord()
273 // ============================================================================