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 : :
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>
35 : :
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"
41 : :
42 : :
43 : : using ::rtl::OUString;
44 : : using ::rtl::OUStringBuffer;
45 : : using namespace com::sun::star;
46 : : using namespace ::xmloff::token;
47 : :
48 : :
49 : : //===========================================================================
50 : :
51 : : /// builds a DOM tree from SAX events, by forwarding to SAXDocumentBuilder
52 : : class XMLDocumentBuilderContext : public SvXMLImportContext
53 : : {
54 : : private:
55 : : ::com::sun::star::uno::Reference<
56 : : ::com::sun::star::xml::sax::XDocumentHandler> mxDocBuilder;
57 : :
58 : : public:
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);
65 : :
66 : : virtual ~XMLDocumentBuilderContext();
67 : :
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 );
72 : :
73 : : virtual void StartElement( const ::com::sun::star::uno::Reference<
74 : : ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
75 : :
76 : : virtual void Characters( const ::rtl::OUString& rChars );
77 : :
78 : : virtual void EndElement();
79 : : };
80 : :
81 : 1739 : 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 : 1739 : mxDocBuilder(rDocBuilder)
87 : : {
88 : 1739 : }
89 : :
90 : 1739 : XMLDocumentBuilderContext::~XMLDocumentBuilderContext()
91 : : {
92 [ - + ]: 3478 : }
93 : :
94 : : SvXMLImportContext *
95 : 1544 : XMLDocumentBuilderContext::CreateChildContext( sal_uInt16 nPrefix,
96 : : const rtl::OUString& rLocalName,
97 : : const uno::Reference< xml::sax::XAttributeList>& rAttrs)
98 : : {
99 : : return new XMLDocumentBuilderContext(
100 [ + - ]: 1544 : GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder);
101 : : }
102 : :
103 : 1739 : void XMLDocumentBuilderContext::StartElement(
104 : : const uno::Reference< xml::sax::XAttributeList >& xAttrList )
105 : : {
106 : 1739 : mxDocBuilder->startElement(
107 : 1739 : GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()),
108 [ + - ]: 1739 : xAttrList);
109 : 1739 : }
110 : :
111 : 1259 : void XMLDocumentBuilderContext::Characters( const ::rtl::OUString& rChars )
112 : : {
113 : 1259 : mxDocBuilder->characters(rChars);
114 : 1259 : }
115 : :
116 : 1739 : void XMLDocumentBuilderContext::EndElement()
117 : : {
118 : 1739 : mxDocBuilder->endElement(
119 [ + - ]: 1739 : GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()));
120 : 1739 : }
121 : :
122 : :
123 : : //===========================================================================
124 : :
125 : : static void
126 : 195 : lcl_initDocumentProperties(SvXMLImport & rImport,
127 : : uno::Reference<xml::sax::XDocumentHandler> const& xDocBuilder,
128 : : uno::Reference<document::XDocumentProperties> const& xDocProps)
129 : : {
130 [ + - ]: 195 : uno::Sequence< uno::Any > aSeq(1);
131 : : uno::Reference< xml::dom::XSAXDocumentBuilder > const xDB(xDocBuilder,
132 [ + - ]: 195 : uno::UNO_QUERY_THROW);
133 [ + - ][ + - ]: 195 : aSeq[0] <<= xDB->getDocument();
[ + - ][ + - ]
134 : : uno::Reference< lang::XInitialization > const xInit(xDocProps,
135 [ + - ]: 195 : uno::UNO_QUERY_THROW);
136 : : try {
137 [ + - ][ + - ]: 195 : xInit->initialize(aSeq);
138 [ + - ][ + - ]: 195 : rImport.SetStatistics(xDocProps->getDocumentStatistics());
[ + - ][ + - ]
139 : : // convert all URLs from relative to absolute
140 [ + - ]: 195 : xDocProps->setTemplateURL(rImport.GetAbsoluteReference(
141 [ + - ][ + - ]: 195 : xDocProps->getTemplateURL()));
[ + - ][ + - ]
142 [ + - ]: 195 : xDocProps->setAutoloadURL(rImport.GetAbsoluteReference(
143 [ + - ][ + - ]: 195 : xDocProps->getAutoloadURL()));
[ + - ][ + - ]
144 : : SvXMLMetaDocumentContext::setBuildId(
145 [ + - ][ + - ]: 195 : xDocProps->getGenerator(), rImport.getImportInfo());
[ + - ][ + - ]
146 : 0 : } catch (const uno::RuntimeException&) {
147 : 0 : throw;
148 [ # # # ]: 0 : } catch (const uno::Exception& e) {
149 : : throw lang::WrappedTargetRuntimeException(
150 : : ::rtl::OUString(
151 : : "SvXMLMetaDocumentContext::initDocumentProperties: "
152 : : "properties init exception"),
153 [ # # # # : 0 : rImport, makeAny(e));
# # ]
154 [ + - ]: 195 : }
155 : 195 : }
156 : :
157 : : static void
158 : 2 : lcl_initGenerator(SvXMLImport & rImport,
159 : : uno::Reference<xml::sax::XDocumentHandler> const& xDocBuilder)
160 : : {
161 : : uno::Reference< xml::dom::XSAXDocumentBuilder > const xDB(xDocBuilder,
162 [ + - ]: 2 : uno::UNO_QUERY_THROW);
163 [ + - ]: 2 : uno::Reference< xml::dom::XDocument > const xDoc(xDB->getDocument(),
164 [ + - ][ + - ]: 2 : uno::UNO_SET_THROW);
165 : : try {
166 : : uno::Reference< xml::xpath::XXPathAPI > const xPath(
167 [ + - ][ + - ]: 4 : rImport.getServiceFactory()->createInstance(
168 : : ::rtl::OUString(
169 : 2 : "com.sun.star.xml.xpath.XPathAPI")),
170 [ + - ][ + - ]: 2 : uno::UNO_QUERY_THROW );
171 [ + - ][ + - ]: 2 : xPath->registerNS(GetXMLToken(XML_NP_OFFICE),GetXMLToken(XML_N_OFFICE));
[ + - ][ + - ]
172 [ + - ][ + - ]: 2 : xPath->registerNS(GetXMLToken(XML_NP_META), GetXMLToken(XML_N_META));
[ + - ][ + - ]
173 : :
174 : 2 : ::rtl::OUString const expr( "string(/office:document-meta/office:meta/meta:generator)");
175 : : uno::Reference< xml::xpath::XXPathObject > const xObj(
176 [ + - ][ + - ]: 2 : xPath->eval(xDoc.get(), expr), uno::UNO_SET_THROW);
[ + - ][ + - ]
[ + - ]
177 [ + - ][ + - ]: 2 : OUString const value(xObj->getString());
178 [ + - ][ + - ]: 2 : SvXMLMetaDocumentContext::setBuildId(value, rImport.getImportInfo());
179 : 0 : } catch (const uno::RuntimeException&) {
180 : 0 : throw;
181 [ # # # ]: 0 : } catch (const uno::Exception& e) {
182 : : throw lang::WrappedTargetRuntimeException(
183 : : ::rtl::OUString(
184 : : "SvXMLMetaDocumentContext::initGenerator: exception"),
185 [ # # # # : 0 : rImport, makeAny(e));
# # ]
186 : 2 : }
187 : 2 : }
188 : :
189 : 197 : 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 : 197 : mxDocBuilder(xDocBuilder)
196 : : {
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
201 : 197 : }
202 : :
203 : 392 : SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext()
204 : : {
205 [ + - ][ - + ]: 587 : }
[ - + ][ - + ]
206 : :
207 : 195 : SvXMLImportContext *SvXMLMetaDocumentContext::CreateChildContext(
208 : : sal_uInt16 nPrefix, const rtl::OUString& rLocalName,
209 : : const uno::Reference<xml::sax::XAttributeList>& rAttrs)
210 : : {
211 [ + - + - ]: 390 : if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
[ + - ]
212 : 195 : IsXMLToken(rLocalName, XML_META) )
213 : : {
214 : : return new XMLDocumentBuilderContext(
215 [ + - ]: 195 : GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder);
216 : : }
217 : : else
218 : : {
219 [ # # ]: 195 : return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
220 : : }
221 : : }
222 : :
223 : :
224 : 197 : void SvXMLMetaDocumentContext::StartElement(
225 : : const uno::Reference< xml::sax::XAttributeList >& xAttrList )
226 : : {
227 : 197 : mxDocBuilder->startDocument();
228 : : // hardcode office:document-meta (necessary in case of flat file ODF)
229 : 197 : mxDocBuilder->startElement(
230 : 197 : GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
231 [ + - ]: 394 : GetXMLToken(XML_DOCUMENT_META)), xAttrList);
232 : :
233 : 197 : }
234 : :
235 : 197 : void SvXMLMetaDocumentContext::EndElement()
236 : : {
237 : : // hardcode office:document-meta (necessary in case of flat file ODF)
238 : 197 : mxDocBuilder->endElement(
239 : 197 : GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
240 [ + - ]: 394 : GetXMLToken(XML_DOCUMENT_META)));
241 : 197 : mxDocBuilder->endDocument();
242 [ + + ]: 197 : if (mxDocProps.is())
243 : : {
244 : 195 : lcl_initDocumentProperties(GetImport(), mxDocBuilder, mxDocProps);
245 : : }
246 : : else
247 : : {
248 : 2 : lcl_initGenerator(GetImport(), mxDocBuilder);
249 : : }
250 : 197 : }
251 : :
252 : 197 : void SvXMLMetaDocumentContext::setBuildId(::rtl::OUString const& i_rBuildId, const uno::Reference<beans::XPropertySet>& xImportInfo )
253 : : {
254 : 197 : OUString sBuildId;
255 : : // skip to second product
256 : 197 : sal_Int32 nBegin = i_rBuildId.indexOf( ' ' );
257 [ + + ]: 197 : if ( nBegin != -1 )
258 : : {
259 : : // skip to build information
260 : 193 : nBegin = i_rBuildId.indexOf( '/', nBegin );
261 [ + + ]: 193 : if ( nBegin != -1 )
262 : : {
263 : 188 : sal_Int32 nEnd = i_rBuildId.indexOf( 'm', nBegin );
264 [ + + ]: 188 : if ( nEnd != -1 )
265 : : {
266 : : OUStringBuffer sBuffer(
267 [ + - ]: 85 : i_rBuildId.copy( nBegin+1, nEnd-nBegin-1 ) );
268 : : const OUString sBuildCompare(
269 : 85 : "$Build-" );
270 : 85 : nBegin = i_rBuildId.indexOf( sBuildCompare, nEnd );
271 [ + - ]: 85 : if ( nBegin != -1 )
272 : : {
273 [ + - ]: 85 : sBuffer.append( (sal_Unicode)'$' );
274 : : sBuffer.append( i_rBuildId.copy(
275 [ + - ]: 85 : nBegin + sBuildCompare.getLength() ) );
276 [ + - ]: 85 : sBuildId = sBuffer.makeStringAndClear();
277 : 85 : }
278 : : }
279 : : }
280 : : }
281 : :
282 [ + + ]: 197 : if ( sBuildId.isEmpty() )
283 : : {
284 [ - + ][ + - : 336 : if ((i_rBuildId.compareToAscii(
+ - - + ]
285 : 112 : RTL_CONSTASCII_STRINGPARAM("StarOffice 7") ) == 0) ||
286 : : (i_rBuildId.compareToAscii(
287 : 112 : RTL_CONSTASCII_STRINGPARAM("StarSuite 7") ) == 0) ||
288 : : (i_rBuildId.compareToAscii(
289 : 112 : RTL_CONSTASCII_STRINGPARAM("OpenOffice.org 1") ) == 0))
290 : : {
291 : 0 : sBuildId = OUString("645$8687");
292 : : }
293 [ - + ]: 112 : if ((i_rBuildId.compareToAscii( RTL_CONSTASCII_STRINGPARAM("NeoOffice/2") ) == 0) )
294 : : {
295 : 0 : sBuildId = OUString("680$9134"); // fake NeoOffice as OpenOffice.org 2.2 release
296 : : }
297 : : }
298 : :
299 [ + + ]: 197 : if ( !sBuildId.isEmpty() ) try
300 : : {
301 [ + - ]: 85 : if( xImportInfo.is() )
302 : : {
303 : 85 : const OUString aPropName("BuildId");
304 : : uno::Reference< beans::XPropertySetInfo > xSetInfo(
305 [ + - ][ + - ]: 85 : xImportInfo->getPropertySetInfo());
306 [ + - ][ + - ]: 85 : if( xSetInfo.is() && xSetInfo->hasPropertyByName( aPropName ) )
[ + - ][ + + ]
[ + + ]
307 [ + - ][ + - ]: 85 : xImportInfo->setPropertyValue( aPropName, uno::makeAny( sBuildId ) );
[ + - ][ # # ]
308 : : }
309 : : }
310 [ # # ]: 0 : catch(const uno::Exception&)
311 : : {
312 : 197 : }
313 : 197 : }
314 : :
315 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|