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