1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
30 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
31 #include <com/sun/star/xml/dom/XSAXDocumentBuilder.hpp>
32 #include <com/sun/star/xml/xpath/XXPathAPI.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <xmloff/xmlmetai.hxx>
37 #include <xmloff/xmlimp.hxx>
38 #include <xmloff/nmspmap.hxx>
39 #include <xmloff/xmltoken.hxx>
40 #include "xmloff/xmlnmspe.hxx"
43 using ::rtl::OUString
;
44 using ::rtl::OUStringBuffer
;
45 using namespace com::sun::star
;
46 using namespace ::xmloff::token
;
49 //===========================================================================
51 /// builds a DOM tree from SAX events, by forwarding to SAXDocumentBuilder
52 class XMLDocumentBuilderContext
: public SvXMLImportContext
55 ::com::sun::star::uno::Reference
<
56 ::com::sun::star::xml::sax::XDocumentHandler
> mxDocBuilder
;
59 XMLDocumentBuilderContext(SvXMLImport
& rImport
, sal_uInt16 nPrfx
,
60 const ::rtl::OUString
& rLName
,
61 const ::com::sun::star::uno::Reference
<
62 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
,
63 const ::com::sun::star::uno::Reference
<
64 ::com::sun::star::xml::sax::XDocumentHandler
>& rDocBuilder
);
66 virtual ~XMLDocumentBuilderContext();
68 virtual SvXMLImportContext
*CreateChildContext( sal_uInt16 nPrefix
,
69 const rtl::OUString
& rLocalName
,
70 const ::com::sun::star::uno::Reference
<
71 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
);
73 virtual void StartElement( const ::com::sun::star::uno::Reference
<
74 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
);
76 virtual void Characters( const ::rtl::OUString
& rChars
);
78 virtual void EndElement();
81 XMLDocumentBuilderContext::XMLDocumentBuilderContext(SvXMLImport
& rImport
,
82 sal_uInt16 nPrfx
, const ::rtl::OUString
& rLName
,
83 const uno::Reference
<xml::sax::XAttributeList
>&,
84 const uno::Reference
<xml::sax::XDocumentHandler
>& rDocBuilder
) :
85 SvXMLImportContext( rImport
, nPrfx
, rLName
),
86 mxDocBuilder(rDocBuilder
)
90 XMLDocumentBuilderContext::~XMLDocumentBuilderContext()
95 XMLDocumentBuilderContext::CreateChildContext( sal_uInt16 nPrefix
,
96 const rtl::OUString
& rLocalName
,
97 const uno::Reference
< xml::sax::XAttributeList
>& rAttrs
)
99 return new XMLDocumentBuilderContext(
100 GetImport(), nPrefix
, rLocalName
, rAttrs
, mxDocBuilder
);
103 void XMLDocumentBuilderContext::StartElement(
104 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
106 mxDocBuilder
->startElement(
107 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()),
111 void XMLDocumentBuilderContext::Characters( const ::rtl::OUString
& rChars
)
113 mxDocBuilder
->characters(rChars
);
116 void XMLDocumentBuilderContext::EndElement()
118 mxDocBuilder
->endElement(
119 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()));
123 //===========================================================================
126 lcl_initDocumentProperties(SvXMLImport
& rImport
,
127 uno::Reference
<xml::sax::XDocumentHandler
> const& xDocBuilder
,
128 uno::Reference
<document::XDocumentProperties
> const& xDocProps
)
130 uno::Sequence
< uno::Any
> aSeq(1);
131 uno::Reference
< xml::dom::XSAXDocumentBuilder
> const xDB(xDocBuilder
,
132 uno::UNO_QUERY_THROW
);
133 aSeq
[0] <<= xDB
->getDocument();
134 uno::Reference
< lang::XInitialization
> const xInit(xDocProps
,
135 uno::UNO_QUERY_THROW
);
137 xInit
->initialize(aSeq
);
138 rImport
.SetStatistics(xDocProps
->getDocumentStatistics());
139 // convert all URLs from relative to absolute
140 xDocProps
->setTemplateURL(rImport
.GetAbsoluteReference(
141 xDocProps
->getTemplateURL()));
142 xDocProps
->setAutoloadURL(rImport
.GetAbsoluteReference(
143 xDocProps
->getAutoloadURL()));
144 SvXMLMetaDocumentContext::setBuildId(
145 xDocProps
->getGenerator(), rImport
.getImportInfo());
146 } catch (const uno::RuntimeException
&) {
148 } catch (const uno::Exception
& e
) {
149 throw lang::WrappedTargetRuntimeException(
151 "SvXMLMetaDocumentContext::initDocumentProperties: "
152 "properties init exception"),
153 rImport
, makeAny(e
));
158 lcl_initGenerator(SvXMLImport
& rImport
,
159 uno::Reference
<xml::sax::XDocumentHandler
> const& xDocBuilder
)
161 uno::Reference
< xml::dom::XSAXDocumentBuilder
> const xDB(xDocBuilder
,
162 uno::UNO_QUERY_THROW
);
163 uno::Reference
< xml::dom::XDocument
> const xDoc(xDB
->getDocument(),
166 uno::Reference
< xml::xpath::XXPathAPI
> const xPath(
167 rImport
.getServiceFactory()->createInstance(
169 "com.sun.star.xml.xpath.XPathAPI")),
170 uno::UNO_QUERY_THROW
);
171 xPath
->registerNS(GetXMLToken(XML_NP_OFFICE
),GetXMLToken(XML_N_OFFICE
));
172 xPath
->registerNS(GetXMLToken(XML_NP_META
), GetXMLToken(XML_N_META
));
174 ::rtl::OUString
const expr( "string(/office:document-meta/office:meta/meta:generator)");
175 uno::Reference
< xml::xpath::XXPathObject
> const xObj(
176 xPath
->eval(xDoc
.get(), expr
), uno::UNO_SET_THROW
);
177 OUString
const value(xObj
->getString());
178 SvXMLMetaDocumentContext::setBuildId(value
, rImport
.getImportInfo());
179 } catch (const uno::RuntimeException
&) {
181 } catch (const uno::Exception
& e
) {
182 throw lang::WrappedTargetRuntimeException(
184 "SvXMLMetaDocumentContext::initGenerator: exception"),
185 rImport
, makeAny(e
));
189 SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport
& rImport
,
190 sal_uInt16 nPrfx
, const rtl::OUString
& rLName
,
191 const uno::Reference
<document::XDocumentProperties
>& xDocProps
,
192 const uno::Reference
<xml::sax::XDocumentHandler
>& xDocBuilder
) :
193 SvXMLImportContext( rImport
, nPrfx
, rLName
),
194 mxDocProps(xDocProps
),
195 mxDocBuilder(xDocBuilder
)
197 // #i103539#: must always read meta.xml for generator, xDocProps unwanted then
198 // OSL_ENSURE(xDocProps.is(), "SvXMLMetaDocumentContext: no document props");
199 OSL_ENSURE(xDocBuilder
.is(), "SvXMLMetaDocumentContext: no document hdlr");
200 // here are no attributes
203 SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext()
207 SvXMLImportContext
*SvXMLMetaDocumentContext::CreateChildContext(
208 sal_uInt16 nPrefix
, const rtl::OUString
& rLocalName
,
209 const uno::Reference
<xml::sax::XAttributeList
>& rAttrs
)
211 if ( (XML_NAMESPACE_OFFICE
== nPrefix
) &&
212 IsXMLToken(rLocalName
, XML_META
) )
214 return new XMLDocumentBuilderContext(
215 GetImport(), nPrefix
, rLocalName
, rAttrs
, mxDocBuilder
);
219 return new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
224 void SvXMLMetaDocumentContext::StartElement(
225 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
227 mxDocBuilder
->startDocument();
228 // hardcode office:document-meta (necessary in case of flat file ODF)
229 mxDocBuilder
->startElement(
230 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
231 GetXMLToken(XML_DOCUMENT_META
)), xAttrList
);
235 void SvXMLMetaDocumentContext::EndElement()
237 // hardcode office:document-meta (necessary in case of flat file ODF)
238 mxDocBuilder
->endElement(
239 GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
240 GetXMLToken(XML_DOCUMENT_META
)));
241 mxDocBuilder
->endDocument();
244 lcl_initDocumentProperties(GetImport(), mxDocBuilder
, mxDocProps
);
248 lcl_initGenerator(GetImport(), mxDocBuilder
);
252 void SvXMLMetaDocumentContext::setBuildId(::rtl::OUString
const& i_rBuildId
, const uno::Reference
<beans::XPropertySet
>& xImportInfo
)
255 // skip to second product
256 sal_Int32 nBegin
= i_rBuildId
.indexOf( ' ' );
259 // skip to build information
260 nBegin
= i_rBuildId
.indexOf( '/', nBegin
);
263 sal_Int32 nEnd
= i_rBuildId
.indexOf( 'm', nBegin
);
266 OUStringBuffer
sBuffer(
267 i_rBuildId
.copy( nBegin
+1, nEnd
-nBegin
-1 ) );
268 const OUString
sBuildCompare(
270 nBegin
= i_rBuildId
.indexOf( sBuildCompare
, nEnd
);
273 sBuffer
.append( (sal_Unicode
)'$' );
274 sBuffer
.append( i_rBuildId
.copy(
275 nBegin
+ sBuildCompare
.getLength() ) );
276 sBuildId
= sBuffer
.makeStringAndClear();
282 if ( sBuildId
.isEmpty() )
284 if ((i_rBuildId
.compareToAscii(
285 RTL_CONSTASCII_STRINGPARAM("StarOffice 7") ) == 0) ||
286 (i_rBuildId
.compareToAscii(
287 RTL_CONSTASCII_STRINGPARAM("StarSuite 7") ) == 0) ||
288 (i_rBuildId
.compareToAscii(
289 RTL_CONSTASCII_STRINGPARAM("OpenOffice.org 1") ) == 0))
291 sBuildId
= OUString("645$8687");
293 if ((i_rBuildId
.compareToAscii( RTL_CONSTASCII_STRINGPARAM("NeoOffice/2") ) == 0) )
295 sBuildId
= OUString("680$9134"); // fake NeoOffice as OpenOffice.org 2.2 release
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: */