bump product version to 4.1.6.2
[LibreOffice.git] / xmloff / source / meta / xmlmetai.cxx
blob28a49edcfb0a3bc920158d3170cbe69c14256bd9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
22 #include <com/sun/star/xml/dom/SAXDocumentBuilder.hpp>
23 #include <com/sun/star/xml/dom/XSAXDocumentBuilder2.hpp>
24 #include <com/sun/star/xml/xpath/XPathAPI.hpp>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/beans/XPropertySetInfo.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <xmloff/xmlmetai.hxx>
29 #include <xmloff/xmlimp.hxx>
30 #include <xmloff/nmspmap.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include "xmloff/xmlnmspe.hxx"
35 using namespace com::sun::star;
36 using namespace ::xmloff::token;
39 //===========================================================================
41 /// builds a DOM tree from SAX events, by forwarding to SAXDocumentBuilder
42 class XMLDocumentBuilderContext : public SvXMLImportContext
44 private:
45 ::com::sun::star::uno::Reference<
46 ::com::sun::star::xml::dom::XSAXDocumentBuilder2> mxDocBuilder;
48 public:
49 XMLDocumentBuilderContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
50 const OUString& rLName,
51 const ::com::sun::star::uno::Reference<
52 ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
53 const ::com::sun::star::uno::Reference<
54 ::com::sun::star::xml::dom::XSAXDocumentBuilder2>& rDocBuilder);
56 virtual ~XMLDocumentBuilderContext();
58 virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
59 const OUString& rLocalName,
60 const ::com::sun::star::uno::Reference<
61 ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
63 virtual void StartElement( const ::com::sun::star::uno::Reference<
64 ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
66 virtual void Characters( const OUString& rChars );
68 virtual void EndElement();
71 XMLDocumentBuilderContext::XMLDocumentBuilderContext(SvXMLImport& rImport,
72 sal_uInt16 nPrfx, const OUString& rLName,
73 const uno::Reference<xml::sax::XAttributeList>&,
74 const uno::Reference<xml::dom::XSAXDocumentBuilder2>& rDocBuilder) :
75 SvXMLImportContext( rImport, nPrfx, rLName ),
76 mxDocBuilder(rDocBuilder)
80 XMLDocumentBuilderContext::~XMLDocumentBuilderContext()
84 SvXMLImportContext *
85 XMLDocumentBuilderContext::CreateChildContext( sal_uInt16 nPrefix,
86 const OUString& rLocalName,
87 const uno::Reference< xml::sax::XAttributeList>& rAttrs)
89 return new XMLDocumentBuilderContext(
90 GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder);
93 void XMLDocumentBuilderContext::StartElement(
94 const uno::Reference< xml::sax::XAttributeList >& xAttrList )
96 mxDocBuilder->startElement(
97 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()),
98 xAttrList);
101 void XMLDocumentBuilderContext::Characters( const OUString& rChars )
103 mxDocBuilder->characters(rChars);
106 void XMLDocumentBuilderContext::EndElement()
108 mxDocBuilder->endElement(
109 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()));
113 //===========================================================================
115 static void
116 lcl_initDocumentProperties(SvXMLImport & rImport,
117 uno::Reference<xml::dom::XSAXDocumentBuilder2> const& xDocBuilder,
118 uno::Reference<document::XDocumentProperties> const& xDocProps)
120 uno::Sequence< uno::Any > aSeq(1);
121 aSeq[0] <<= xDocBuilder->getDocument();
122 uno::Reference< lang::XInitialization > const xInit(xDocProps,
123 uno::UNO_QUERY_THROW);
124 try {
125 xInit->initialize(aSeq);
126 rImport.SetStatistics(xDocProps->getDocumentStatistics());
127 // convert all URLs from relative to absolute
128 xDocProps->setTemplateURL(rImport.GetAbsoluteReference(
129 xDocProps->getTemplateURL()));
130 xDocProps->setAutoloadURL(rImport.GetAbsoluteReference(
131 xDocProps->getAutoloadURL()));
132 SvXMLMetaDocumentContext::setBuildId(
133 xDocProps->getGenerator(), rImport.getImportInfo());
134 } catch (const uno::RuntimeException&) {
135 throw;
136 } catch (const uno::Exception& e) {
137 throw lang::WrappedTargetRuntimeException(
138 OUString(
139 "SvXMLMetaDocumentContext::initDocumentProperties: "
140 "properties init exception"),
141 rImport, makeAny(e));
145 static void
146 lcl_initGenerator(SvXMLImport & rImport,
147 uno::Reference<xml::dom::XSAXDocumentBuilder2> const& xDocBuilder)
149 uno::Reference< xml::dom::XDocument > const xDoc(xDocBuilder->getDocument(),
150 uno::UNO_SET_THROW);
151 try {
152 uno::Reference< xml::xpath::XXPathAPI > const xPath = xml::xpath::XPathAPI::create(
153 rImport.GetComponentContext() );
154 xPath->registerNS(GetXMLToken(XML_NP_OFFICE),GetXMLToken(XML_N_OFFICE));
155 xPath->registerNS(GetXMLToken(XML_NP_META), GetXMLToken(XML_N_META));
157 OUString const expr( "string(/office:document-meta/office:meta/meta:generator)");
158 uno::Reference< xml::xpath::XXPathObject > const xObj(
159 xPath->eval(xDoc.get(), expr), uno::UNO_SET_THROW);
160 OUString const value(xObj->getString());
161 SvXMLMetaDocumentContext::setBuildId(value, rImport.getImportInfo());
162 } catch (const uno::RuntimeException&) {
163 throw;
164 } catch (const uno::Exception& e) {
165 throw lang::WrappedTargetRuntimeException(
166 OUString(
167 "SvXMLMetaDocumentContext::initGenerator: exception"),
168 rImport, makeAny(e));
172 SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport,
173 sal_uInt16 nPrfx, const OUString& rLName,
174 const uno::Reference<document::XDocumentProperties>& xDocProps) :
175 SvXMLImportContext( rImport, nPrfx, rLName ),
176 mxDocProps(xDocProps),
177 mxDocBuilder(
178 xml::dom::SAXDocumentBuilder::create(
179 comphelper::getProcessComponentContext()))
181 // #i103539#: must always read meta.xml for generator, xDocProps unwanted then
182 // OSL_ENSURE(xDocProps.is(), "SvXMLMetaDocumentContext: no document props");
185 SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext()
189 SvXMLImportContext *SvXMLMetaDocumentContext::CreateChildContext(
190 sal_uInt16 nPrefix, const OUString& rLocalName,
191 const uno::Reference<xml::sax::XAttributeList>& rAttrs)
193 if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
194 IsXMLToken(rLocalName, XML_META) )
196 return new XMLDocumentBuilderContext(
197 GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder);
199 else
201 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
206 void SvXMLMetaDocumentContext::StartElement(
207 const uno::Reference< xml::sax::XAttributeList >& xAttrList )
209 mxDocBuilder->startDocument();
210 // hardcode office:document-meta (necessary in case of flat file ODF)
211 mxDocBuilder->startElement(
212 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
213 GetXMLToken(XML_DOCUMENT_META)), xAttrList);
217 void SvXMLMetaDocumentContext::EndElement()
219 // hardcode office:document-meta (necessary in case of flat file ODF)
220 mxDocBuilder->endElement(
221 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
222 GetXMLToken(XML_DOCUMENT_META)));
223 mxDocBuilder->endDocument();
224 if (mxDocProps.is())
226 lcl_initDocumentProperties(GetImport(), mxDocBuilder, mxDocProps);
228 else
230 lcl_initGenerator(GetImport(), mxDocBuilder);
234 void SvXMLMetaDocumentContext::setBuildId(OUString const& i_rBuildId, const uno::Reference<beans::XPropertySet>& xImportInfo )
236 OUString sBuildId;
237 // skip to second product
238 sal_Int32 nBegin = i_rBuildId.indexOf( ' ' );
239 if ( nBegin != -1 )
241 // skip to build information
242 nBegin = i_rBuildId.indexOf( '/', nBegin );
243 if ( nBegin != -1 )
245 sal_Int32 nEnd = i_rBuildId.indexOf( 'm', nBegin );
246 if ( nEnd != -1 )
248 OUStringBuffer sBuffer(
249 i_rBuildId.copy( nBegin+1, nEnd-nBegin-1 ) );
250 const OUString sBuildCompare(
251 "$Build-" );
252 nBegin = i_rBuildId.indexOf( sBuildCompare, nEnd );
253 if ( nBegin != -1 )
255 sBuffer.append( (sal_Unicode)'$' );
256 sBuffer.append( i_rBuildId.copy(
257 nBegin + sBuildCompare.getLength() ) );
258 sBuildId = sBuffer.makeStringAndClear();
264 if ( sBuildId.isEmpty() )
266 if ( i_rBuildId.startsWith("StarOffice 7")
267 || i_rBuildId.startsWith("StarSuite 7")
268 || i_rBuildId.startsWith("OpenOffice.org 1"))
270 sBuildId = OUString("645$8687");
272 else if (i_rBuildId.startsWith("NeoOffice/2"))
274 sBuildId = OUString("680$9134"); // fake NeoOffice as OpenOffice.org 2.2 release
278 if (i_rBuildId.startsWith("LibreOffice/"))
280 OUStringBuffer sNumber;
281 for (sal_Int32 i = sizeof("LibreOffice/") - 1;
282 i < i_rBuildId.getLength(); ++i)
284 if (isdigit(i_rBuildId[i]))
286 sNumber.append(i_rBuildId[i]);
288 else if ('.' != i_rBuildId[i])
290 break;
293 if (sNumber.getLength())
295 sBuildId += (";" + sNumber.makeStringAndClear());
299 if ( !sBuildId.isEmpty() ) try
301 if( xImportInfo.is() )
303 const OUString aPropName("BuildId");
304 uno::Reference< beans::XPropertySetInfo > xSetInfo(
305 xImportInfo->getPropertySetInfo());
306 if( xSetInfo.is() && xSetInfo->hasPropertyByName( aPropName ) )
307 xImportInfo->setPropertyValue( aPropName, uno::makeAny( sBuildId ) );
310 catch(const uno::Exception&)
315 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */