Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <tools/debug.hxx>
30 : : #include <i18npool/mslangid.hxx>
31 : : #include <rtl/ustrbuf.hxx>
32 : :
33 : : #include <xmloff/xmlmetae.hxx>
34 : : #include <xmloff/xmlexp.hxx>
35 : : #include <xmloff/nmspmap.hxx>
36 : : #include "xmloff/xmlnmspe.hxx"
37 : :
38 : : #include <com/sun/star/beans/XPropertyAccess.hpp>
39 : : #include <com/sun/star/beans/StringPair.hpp>
40 : : #include <com/sun/star/util/Duration.hpp>
41 : : #include <com/sun/star/xml/dom/XDocument.hpp>
42 : : #include <com/sun/star/xml/sax/XSAXSerializable.hpp>
43 : :
44 : : #include <sax/tools/converter.hxx>
45 : :
46 : : #include <comphelper/sequenceasvector.hxx>
47 : : #include <unotools/docinfohelper.hxx>
48 : :
49 : : #include <string.h>
50 : :
51 : :
52 : : using namespace com::sun::star;
53 : : using namespace ::xmloff::token;
54 : :
55 : :
56 : : //-------------------------------------------------------------------------
57 : :
58 : 0 : void lcl_AddTwoDigits( rtl::OUStringBuffer& rStr, sal_Int32 nVal )
59 : : {
60 [ # # ]: 0 : if ( nVal < 10 )
61 : 0 : rStr.append( sal_Unicode('0') );
62 : 0 : rStr.append( nVal );
63 : 0 : }
64 : :
65 : : rtl::OUString
66 : 0 : SvXMLMetaExport::GetISODateTimeString( const util::DateTime& rDateTime )
67 : : {
68 : : // return ISO date string "YYYY-MM-DDThh:mm:ss"
69 : :
70 : 0 : rtl::OUStringBuffer sTmp;
71 [ # # ]: 0 : sTmp.append( (sal_Int32) rDateTime.Year );
72 [ # # ]: 0 : sTmp.append( sal_Unicode('-') );
73 [ # # ]: 0 : lcl_AddTwoDigits( sTmp, rDateTime.Month );
74 [ # # ]: 0 : sTmp.append( sal_Unicode('-') );
75 [ # # ]: 0 : lcl_AddTwoDigits( sTmp, rDateTime.Day );
76 [ # # ]: 0 : sTmp.append( sal_Unicode('T') );
77 [ # # ]: 0 : lcl_AddTwoDigits( sTmp, rDateTime.Hours );
78 [ # # ]: 0 : sTmp.append( sal_Unicode(':') );
79 [ # # ]: 0 : lcl_AddTwoDigits( sTmp, rDateTime.Minutes );
80 [ # # ]: 0 : sTmp.append( sal_Unicode(':') );
81 [ # # ]: 0 : lcl_AddTwoDigits( sTmp, rDateTime.Seconds );
82 : :
83 [ # # ]: 0 : return sTmp.makeStringAndClear();
84 : : }
85 : :
86 : : //-------------------------------------------------------------------------
87 : :
88 : 0 : void SvXMLMetaExport::SimpleStringElement( const rtl::OUString& rText,
89 : : sal_uInt16 nNamespace, enum XMLTokenEnum eElementName )
90 : : {
91 [ # # ]: 0 : if ( !rText.isEmpty() ) {
92 : : SvXMLElementExport aElem( mrExport, nNamespace, eElementName,
93 [ # # ]: 0 : sal_True, sal_False );
94 [ # # ][ # # ]: 0 : mrExport.Characters( rText );
95 : : }
96 : 0 : }
97 : :
98 : 0 : void SvXMLMetaExport::SimpleDateTimeElement( const util::DateTime & rDate,
99 : : sal_uInt16 nNamespace, enum XMLTokenEnum eElementName )
100 : : {
101 [ # # ]: 0 : if (rDate.Month != 0) { // invalid dates are 0-0-0
102 [ # # ]: 0 : rtl::OUString sValue = GetISODateTimeString( rDate );
103 [ # # ]: 0 : if ( !sValue.isEmpty() ) {
104 : : SvXMLElementExport aElem( mrExport, nNamespace, eElementName,
105 [ # # ]: 0 : sal_True, sal_False );
106 [ # # ][ # # ]: 0 : mrExport.Characters( sValue );
107 : 0 : }
108 : : }
109 : 0 : }
110 : :
111 : 0 : void SvXMLMetaExport::_MExport()
112 : : {
113 : : // generator
114 : : {
115 : : SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, XML_GENERATOR,
116 [ # # ]: 0 : sal_True, sal_True );
117 [ # # ][ # # ]: 0 : mrExport.Characters( ::utl::DocInfoHelper::GetGeneratorString() );
[ # # ]
118 : : }
119 : :
120 : : // document title
121 [ # # ]: 0 : SimpleStringElement ( mxDocProps->getTitle(),
122 [ # # ][ # # ]: 0 : XML_NAMESPACE_DC, XML_TITLE );
123 : :
124 : : // description
125 [ # # ]: 0 : SimpleStringElement ( mxDocProps->getDescription(),
126 [ # # ][ # # ]: 0 : XML_NAMESPACE_DC, XML_DESCRIPTION );
127 : :
128 : : // subject
129 [ # # ]: 0 : SimpleStringElement ( mxDocProps->getSubject(),
130 [ # # ][ # # ]: 0 : XML_NAMESPACE_DC, XML_SUBJECT );
131 : :
132 : : // created...
133 [ # # ]: 0 : SimpleStringElement ( mxDocProps->getAuthor(),
134 [ # # ][ # # ]: 0 : XML_NAMESPACE_META, XML_INITIAL_CREATOR );
135 [ # # ]: 0 : SimpleDateTimeElement( mxDocProps->getCreationDate(),
136 [ # # ][ # # ]: 0 : XML_NAMESPACE_META, XML_CREATION_DATE );
137 : :
138 : : // modified...
139 [ # # ]: 0 : SimpleStringElement ( mxDocProps->getModifiedBy(),
140 [ # # ][ # # ]: 0 : XML_NAMESPACE_DC, XML_CREATOR );
141 [ # # ]: 0 : SimpleDateTimeElement( mxDocProps->getModificationDate(),
142 [ # # ][ # # ]: 0 : XML_NAMESPACE_DC, XML_DATE );
143 : :
144 : : // printed...
145 [ # # ]: 0 : SimpleStringElement ( mxDocProps->getPrintedBy(),
146 [ # # ][ # # ]: 0 : XML_NAMESPACE_META, XML_PRINTED_BY );
147 [ # # ]: 0 : SimpleDateTimeElement( mxDocProps->getPrintDate(),
148 [ # # ][ # # ]: 0 : XML_NAMESPACE_META, XML_PRINT_DATE );
149 : :
150 : : // keywords
151 [ # # ][ # # ]: 0 : const uno::Sequence< ::rtl::OUString > keywords = mxDocProps->getKeywords();
152 [ # # ]: 0 : for (sal_Int32 i = 0; i < keywords.getLength(); ++i) {
153 : : SvXMLElementExport aKwElem( mrExport, XML_NAMESPACE_META, XML_KEYWORD,
154 [ # # ]: 0 : sal_True, sal_False );
155 [ # # ]: 0 : mrExport.Characters( keywords[i] );
156 [ # # ]: 0 : }
157 : :
158 : : // document language
159 : : {
160 [ # # ][ # # ]: 0 : const lang::Locale aLocale = mxDocProps->getLanguage();
161 : 0 : ::rtl::OUString sValue = aLocale.Language;
162 [ # # ]: 0 : if (!sValue.isEmpty()) {
163 [ # # ]: 0 : if ( !aLocale.Country.isEmpty() )
164 : : {
165 : 0 : sValue += rtl::OUString::valueOf((sal_Unicode)'-');
166 : 0 : sValue += aLocale.Country;
167 : : }
168 : : SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DC, XML_LANGUAGE,
169 [ # # ]: 0 : sal_True, sal_False );
170 [ # # ][ # # ]: 0 : mrExport.Characters( sValue );
171 : 0 : }
172 : : }
173 : :
174 : : // editing cycles
175 : : {
176 : : SvXMLElementExport aElem( mrExport,
177 : : XML_NAMESPACE_META, XML_EDITING_CYCLES,
178 [ # # ]: 0 : sal_True, sal_False );
179 : : mrExport.Characters( ::rtl::OUString::valueOf(
180 [ # # ][ # # ]: 0 : static_cast<sal_Int32>(mxDocProps->getEditingCycles()) ) );
[ # # ][ # # ]
181 : : }
182 : :
183 : : // editing duration
184 : : // property is a int32 (seconds)
185 : : {
186 [ # # ][ # # ]: 0 : sal_Int32 secs = mxDocProps->getEditingDuration();
187 : : SvXMLElementExport aElem( mrExport,
188 : : XML_NAMESPACE_META, XML_EDITING_DURATION,
189 [ # # ]: 0 : sal_True, sal_False );
190 : 0 : ::rtl::OUStringBuffer buf;
191 : : ::sax::Converter::convertDuration(buf, util::Duration(
192 [ # # ]: 0 : false, 0, 0, 0, secs/3600, (secs%3600)/60, secs%60, 0));
193 [ # # ][ # # ]: 0 : mrExport.Characters(buf.makeStringAndClear());
[ # # ]
194 : : }
195 : :
196 : : // default target
197 [ # # ][ # # ]: 0 : const ::rtl::OUString sDefTarget = mxDocProps->getDefaultTarget();
198 [ # # ]: 0 : if ( !sDefTarget.isEmpty() )
199 : : {
200 : : mrExport.AddAttribute( XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME,
201 [ # # ]: 0 : sDefTarget );
202 : :
203 : : //! define strings for xlink:show values
204 [ # # ]: 0 : const XMLTokenEnum eShow = sDefTarget == "_blank" ? XML_NEW : XML_REPLACE;
205 [ # # ]: 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, eShow );
206 : :
207 : : SvXMLElementExport aElem( mrExport,
208 : : XML_NAMESPACE_META,XML_HYPERLINK_BEHAVIOUR,
209 [ # # ][ # # ]: 0 : sal_True, sal_False );
210 : : }
211 : :
212 : : // auto-reload
213 [ # # ][ # # ]: 0 : const ::rtl::OUString sReloadURL = mxDocProps->getAutoloadURL();
214 [ # # ][ # # ]: 0 : const sal_Int32 sReloadDelay = mxDocProps->getAutoloadSecs();
215 [ # # ][ # # ]: 0 : if (sReloadDelay != 0 || !sReloadURL.isEmpty())
[ # # ]
216 : : {
217 : : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF,
218 [ # # ][ # # ]: 0 : mrExport.GetRelativeReference( sReloadURL ) );
219 : :
220 : 0 : ::rtl::OUStringBuffer buf;
221 : : ::sax::Converter::convertDuration(buf, util::Duration(false, 0, 0, 0,
222 [ # # ]: 0 : sReloadDelay/3600, (sReloadDelay%3600)/60, sReloadDelay%60, 0));
223 : : mrExport.AddAttribute( XML_NAMESPACE_META, XML_DELAY,
224 [ # # ][ # # ]: 0 : buf.makeStringAndClear());
225 : :
226 : : SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, XML_AUTO_RELOAD,
227 [ # # ][ # # ]: 0 : sal_True, sal_False );
228 : : }
229 : :
230 : : // template
231 [ # # ][ # # ]: 0 : const rtl::OUString sTplPath = mxDocProps->getTemplateURL();
232 [ # # ]: 0 : if ( !sTplPath.isEmpty() )
233 : : {
234 [ # # ]: 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
235 [ # # ]: 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
236 : :
237 : : // template URL
238 : : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF,
239 [ # # ][ # # ]: 0 : mrExport.GetRelativeReference(sTplPath) );
240 : :
241 : : // template name
242 : : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TITLE,
243 [ # # ][ # # ]: 0 : mxDocProps->getTemplateName() );
[ # # ]
244 : :
245 : : // template date
246 : : mrExport.AddAttribute( XML_NAMESPACE_META, XML_DATE,
247 [ # # ][ # # ]: 0 : GetISODateTimeString( mxDocProps->getTemplateDate() ) );
[ # # ][ # # ]
248 : :
249 : : SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META, XML_TEMPLATE,
250 [ # # ][ # # ]: 0 : sal_True, sal_False );
251 : : }
252 : :
253 : : // user defined fields
254 : : uno::Reference< beans::XPropertyAccess > xUserDefined(
255 [ # # ][ # # ]: 0 : mxDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
[ # # ]
256 : : const uno::Sequence< beans::PropertyValue > props =
257 [ # # ][ # # ]: 0 : xUserDefined->getPropertyValues();
258 [ # # ]: 0 : for (sal_Int32 i = 0; i < props.getLength(); ++i) {
259 : 0 : ::rtl::OUStringBuffer sValueBuffer;
260 : 0 : ::rtl::OUStringBuffer sType;
261 [ # # ][ # # ]: 0 : if (!::sax::Converter::convertAny(sValueBuffer, sType, props[i].Value))
262 : : {
263 : 0 : continue;
264 : : }
265 [ # # ]: 0 : mrExport.AddAttribute( XML_NAMESPACE_META, XML_NAME, props[i].Name );
266 : : mrExport.AddAttribute( XML_NAMESPACE_META, XML_VALUE_TYPE,
267 [ # # ][ # # ]: 0 : sType.makeStringAndClear() );
268 : : SvXMLElementExport aElem( mrExport, XML_NAMESPACE_META,
269 [ # # ]: 0 : XML_USER_DEFINED, sal_True, sal_False );
270 [ # # ][ # # ]: 0 : mrExport.Characters( sValueBuffer.makeStringAndClear() );
271 [ # # ][ # # ]: 0 : }
[ # # ]
272 : :
273 : : const uno::Sequence< beans::NamedValue > aDocStatistic =
274 [ # # ][ # # ]: 0 : mxDocProps->getDocumentStatistics();
275 : : // write document statistic if there is any provided
276 [ # # ]: 0 : if ( aDocStatistic.getLength() )
277 : : {
278 [ # # ]: 0 : for ( sal_Int32 nInd = 0; nInd < aDocStatistic.getLength(); nInd++ )
279 : : {
280 : 0 : sal_Int32 nValue = 0;
281 [ # # ]: 0 : if ( aDocStatistic[nInd].Value >>= nValue )
282 : : {
283 : 0 : ::rtl::OUString aValue = rtl::OUString::valueOf( nValue );
284 [ # # ]: 0 : if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
285 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "TableCount" ) ) ) )
286 : : mrExport.AddAttribute(
287 [ # # ]: 0 : XML_NAMESPACE_META, XML_TABLE_COUNT, aValue );
288 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
289 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "ObjectCount" ) ) ) )
290 : : mrExport.AddAttribute(
291 [ # # ]: 0 : XML_NAMESPACE_META, XML_OBJECT_COUNT, aValue );
292 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
293 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "ImageCount" ) ) ) )
294 : : mrExport.AddAttribute(
295 [ # # ]: 0 : XML_NAMESPACE_META, XML_IMAGE_COUNT, aValue );
296 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
297 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "PageCount" ) ) ) )
298 : : mrExport.AddAttribute(
299 [ # # ]: 0 : XML_NAMESPACE_META, XML_PAGE_COUNT, aValue );
300 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
301 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "ParagraphCount" ) ) ) )
302 : : mrExport.AddAttribute(
303 [ # # ]: 0 : XML_NAMESPACE_META, XML_PARAGRAPH_COUNT, aValue );
304 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
305 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "WordCount" ) ) ) )
306 : : mrExport.AddAttribute(
307 [ # # ]: 0 : XML_NAMESPACE_META, XML_WORD_COUNT, aValue );
308 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
309 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "CharacterCount" ) ) ) )
310 : : mrExport.AddAttribute(
311 [ # # ]: 0 : XML_NAMESPACE_META, XML_CHARACTER_COUNT, aValue );
312 [ # # ]: 0 : else if ( aDocStatistic[nInd].Name.equals( ::rtl::OUString(
313 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "CellCount" ) ) ) )
314 : : mrExport.AddAttribute(
315 [ # # ]: 0 : XML_NAMESPACE_META, XML_CELL_COUNT, aValue );
316 : : else
317 : : {
318 : : DBG_ASSERT( sal_False, "Unknown statistic value!\n" );
319 : 0 : }
320 : : }
321 : : }
322 : : SvXMLElementExport aElem( mrExport,
323 [ # # ][ # # ]: 0 : XML_NAMESPACE_META, XML_DOCUMENT_STATISTIC, sal_True, sal_True );
324 [ # # ][ # # ]: 0 : }
[ # # ]
325 : 0 : }
326 : :
327 : : //-------------------------------------------------------------------------
328 : :
329 : : static const char *s_xmlns = "xmlns";
330 : : static const char *s_xmlns2 = "xmlns:";
331 : : static const char *s_meta = "meta:";
332 : : static const char *s_href = "xlink:href";
333 : :
334 : 50 : SvXMLMetaExport::SvXMLMetaExport(
335 : : SvXMLExport& i_rExp,
336 : : const uno::Reference<document::XDocumentProperties>& i_rDocProps ) :
337 : : mrExport( i_rExp ),
338 : : mxDocProps( i_rDocProps ),
339 : : m_level( 0 ),
340 [ + - ]: 50 : m_preservedNSs()
341 : : {
342 : : DBG_ASSERT( mxDocProps.is(), "no document properties" );
343 : 50 : }
344 : :
345 : 50 : SvXMLMetaExport::~SvXMLMetaExport()
346 : : {
347 [ - + ]: 100 : }
348 : :
349 : 50 : void SvXMLMetaExport::Export()
350 : : {
351 : : uno::Reference< xml::sax::XSAXSerializable> xSAXable(mxDocProps,
352 [ + - ]: 50 : uno::UNO_QUERY);
353 [ + - ]: 50 : if (xSAXable.is()) {
354 [ + - ]: 50 : ::comphelper::SequenceAsVector< beans::StringPair > namespaces;
355 : 50 : const SvXMLNamespaceMap & rNsMap(mrExport.GetNamespaceMap());
356 [ + - ][ + + ]: 519 : for (sal_uInt16 key = rNsMap.GetFirstKey();
[ + - ]
357 : 469 : key != USHRT_MAX; key = rNsMap.GetNextKey(key)) {
358 : 469 : beans::StringPair ns;
359 [ + - ]: 469 : const ::rtl::OUString attrname = rNsMap.GetAttrNameByKey(key);
360 [ + - ]: 469 : if (attrname.matchAsciiL(s_xmlns2, strlen(s_xmlns2))) {
361 : 469 : ns.First = attrname.copy(strlen(s_xmlns2));
362 : 0 : } else if (attrname.equalsAsciiL(s_xmlns, strlen(s_xmlns))) {
363 : : // default initialized empty string
364 : : } else {
365 : : OSL_FAIL("namespace attribute not starting with xmlns unexpected");
366 : : }
367 [ + - ]: 469 : ns.Second = rNsMap.GetNameByKey(key);
368 [ + - ]: 469 : namespaces.push_back(ns);
369 : 469 : }
370 [ + - ][ + - ]: 50 : xSAXable->serialize(this, namespaces.getAsConstList());
[ + - ][ + - ]
[ + - ]
371 : : } else {
372 : : // office:meta
373 : : SvXMLElementExport aElem( mrExport, XML_NAMESPACE_OFFICE, XML_META,
374 [ # # ]: 0 : sal_True, sal_True );
375 : : // fall back to using public interface of XDocumentProperties
376 [ # # ][ # # ]: 0 : _MExport();
377 : 50 : }
378 : 50 : }
379 : :
380 : : // ::com::sun::star::xml::sax::XDocumentHandler:
381 : : void SAL_CALL
382 : 50 : SvXMLMetaExport::startDocument()
383 : : throw (uno::RuntimeException, xml::sax::SAXException)
384 : : {
385 : : // ignore: has already been done by SvXMLExport::exportDoc
386 : : DBG_ASSERT( m_level == 0, "SvXMLMetaExport: level error" );
387 : 50 : }
388 : :
389 : : void SAL_CALL
390 : 50 : SvXMLMetaExport::endDocument()
391 : : throw (uno::RuntimeException, xml::sax::SAXException)
392 : : {
393 : : // ignore: will be done by SvXMLExport::exportDoc
394 : : DBG_ASSERT( m_level == 0, "SvXMLMetaExport: level error" );
395 : 50 : }
396 : :
397 : : // unfortunately, this method contains far too much ugly namespace mangling.
398 : : void SAL_CALL
399 : 404 : SvXMLMetaExport::startElement(const ::rtl::OUString & i_rName,
400 : : const uno::Reference< xml::sax::XAttributeList > & i_xAttribs)
401 : : throw (uno::RuntimeException, xml::sax::SAXException)
402 : : {
403 : :
404 [ + + ]: 404 : if (m_level == 0) {
405 : : // namepace decls: default ones have been written at the root element
406 : : // non-default ones must be preserved here
407 : 50 : const sal_Int16 nCount = i_xAttribs->getLength();
408 [ + + ]: 573 : for (sal_Int16 i = 0; i < nCount; ++i) {
409 [ + - ][ + - ]: 523 : const ::rtl::OUString name(i_xAttribs->getNameByIndex(i));
410 [ + + ]: 523 : if (name.matchAsciiL(s_xmlns, strlen(s_xmlns))) {
411 : 469 : bool found(false);
412 : 469 : const SvXMLNamespaceMap & rNsMap(mrExport.GetNamespaceMap());
413 [ + - ][ + - ]: 4265 : for (sal_uInt16 key = rNsMap.GetFirstKey();
[ + - ]
414 : 3796 : key != USHRT_MAX; key = rNsMap.GetNextKey(key)) {
415 [ + - ][ + + ]: 4265 : if (name.equals(rNsMap.GetAttrNameByKey(key))) {
416 : 469 : found = true;
417 : 469 : break;
418 : : }
419 : : }
420 [ - + ]: 469 : if (!found) {
421 : : m_preservedNSs.push_back(beans::StringPair(name,
422 [ # # ][ # # ]: 0 : i_xAttribs->getValueByIndex(i)));
[ # # ]
423 : : }
424 : : }
425 : 523 : }
426 : : // ignore the root: it has been written already
427 : 50 : ++m_level;
428 : 404 : return;
429 : : }
430 : :
431 [ + + ]: 354 : if (m_level == 1) {
432 : : // attach preserved namespace decls from root node here
433 [ + - ][ - + ]: 100 : for (std::vector<beans::StringPair>::const_iterator iter =
434 [ + - ]: 100 : m_preservedNSs.begin(); iter != m_preservedNSs.end(); ++iter) {
435 : 0 : const ::rtl::OUString ns(iter->First);
436 : 0 : bool found(false);
437 : : // but only if it is not already there
438 [ # # ][ # # ]: 0 : const sal_Int16 nCount = i_xAttribs->getLength();
439 [ # # ]: 0 : for (sal_Int16 i = 0; i < nCount; ++i) {
440 [ # # ][ # # ]: 0 : const ::rtl::OUString name(i_xAttribs->getNameByIndex(i));
441 [ # # ]: 0 : if (ns.equals(name)) {
442 : 0 : found = true;
443 : : break;
444 : : }
445 [ # # ]: 0 : }
446 [ # # ]: 0 : if (!found) {
447 [ # # ]: 0 : mrExport.AddAttribute(ns, iter->Second);
448 : : }
449 : 0 : }
450 : : }
451 : :
452 : : // attach the attributes
453 [ + + ]: 354 : if (i_rName.matchAsciiL(s_meta, strlen(s_meta))) {
454 : : // special handling for all elements that may have
455 : : // xlink:href attributes; these must be made relative
456 : 250 : const sal_Int16 nLength = i_xAttribs->getLength();
457 [ + + ]: 555 : for (sal_Int16 i = 0; i < nLength; ++i) {
458 [ + - ][ + - ]: 305 : const ::rtl::OUString name (i_xAttribs->getNameByIndex (i));
459 [ + - ][ + - ]: 305 : ::rtl::OUString value(i_xAttribs->getValueByIndex(i));
460 [ + + ]: 305 : if (name.matchAsciiL(s_href, strlen(s_href))) {
461 [ + - ]: 7 : value = mrExport.GetRelativeReference(value);
462 : : }
463 [ + - ]: 305 : mrExport.AddAttribute(name, value);
464 : 305 : }
465 : : } else {
466 : 104 : const sal_Int16 nLength = i_xAttribs->getLength();
467 [ + + ]: 110 : for (sal_Int16 i = 0; i < nLength; ++i) {
468 [ + - ][ + - ]: 6 : const ::rtl::OUString name (i_xAttribs->getNameByIndex(i));
469 [ + - ][ + - ]: 6 : const ::rtl::OUString value (i_xAttribs->getValueByIndex(i));
470 [ + - ]: 6 : mrExport.AddAttribute(name, value);
471 : 6 : }
472 : : }
473 : :
474 : : // finally, start the element
475 : : // #i107240# no whitespace here, because the DOM may already contain
476 : : // whitespace, which is not cleared when loading and thus accumulates.
477 : 354 : mrExport.StartElement(i_rName, (m_level > 1) ? sal_False : sal_True);
478 : 354 : ++m_level;
479 : : }
480 : :
481 : : void SAL_CALL
482 : 404 : SvXMLMetaExport::endElement(const ::rtl::OUString & i_rName)
483 : : throw (uno::RuntimeException, xml::sax::SAXException)
484 : : {
485 : 404 : --m_level;
486 [ + + ]: 404 : if (m_level == 0) {
487 : : // ignore the root; see startElement
488 : 404 : return;
489 : : }
490 : : DBG_ASSERT( m_level >= 0, "SvXMLMetaExport: level error" );
491 : 354 : mrExport.EndElement(i_rName, sal_False);
492 : : }
493 : :
494 : : void SAL_CALL
495 : 244 : SvXMLMetaExport::characters(const ::rtl::OUString & i_rChars)
496 : : throw (uno::RuntimeException, xml::sax::SAXException)
497 : : {
498 : 244 : mrExport.Characters(i_rChars);
499 : 244 : }
500 : :
501 : : void SAL_CALL
502 : 0 : SvXMLMetaExport::ignorableWhitespace(const ::rtl::OUString & /*i_rWhitespaces*/)
503 : : throw (uno::RuntimeException, xml::sax::SAXException)
504 : : {
505 : 0 : mrExport.IgnorableWhitespace(/*i_rWhitespaces*/);
506 : 0 : }
507 : :
508 : : void SAL_CALL
509 : 0 : SvXMLMetaExport::processingInstruction(const ::rtl::OUString & i_rTarget,
510 : : const ::rtl::OUString & i_rData)
511 : : throw (uno::RuntimeException, xml::sax::SAXException)
512 : : {
513 : : // ignore; the exporter cannot handle these
514 : : (void) i_rTarget;
515 : : (void) i_rData;
516 : 0 : }
517 : :
518 : : void SAL_CALL
519 : 0 : SvXMLMetaExport::setDocumentLocator(const uno::Reference<xml::sax::XLocator>&)
520 : : throw (uno::RuntimeException, xml::sax::SAXException)
521 : : {
522 : : // nothing to do here, move along...
523 : 0 : }
524 : :
525 : :
526 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|