Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "XMLFilter.hxx"
21 : #include "macros.hxx"
22 : #include "MediaDescriptorHelper.hxx"
23 : #include "ContainerHelper.hxx"
24 :
25 : #include <svtools/sfxecode.hxx>
26 : #include <unotools/saveopt.hxx>
27 : #include <comphelper/genericpropertyset.hxx>
28 : #include <comphelper/propertysetinfo.hxx>
29 : #include <comphelper/documentconstants.hxx>
30 : #include <cppuhelper/supportsservice.hxx>
31 :
32 : #include <sot/storage.hxx>
33 : #include <osl/diagnose.h>
34 : #include <com/sun/star/beans/NamedValue.hpp>
35 : #include <com/sun/star/beans/PropertyAttribute.hpp>
36 : #include <com/sun/star/xml/sax/InputSource.hpp>
37 : #include <com/sun/star/xml/sax/Writer.hpp>
38 : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
39 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
40 : #include <com/sun/star/embed/ElementModes.hpp>
41 : #include <com/sun/star/embed/XStorage.hpp>
42 : #include <com/sun/star/embed/StorageFactory.hpp>
43 : #include <com/sun/star/embed/XTransactedObject.hpp>
44 : #include <com/sun/star/frame/XModel.hpp>
45 : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
46 : #include <com/sun/star/xml/sax/Parser.hpp>
47 : #include <com/sun/star/xml/sax/SAXParseException.hpp>
48 : #include <com/sun/star/packages/zip/ZipIOException.hpp>
49 : #include <com/sun/star/document/GraphicObjectResolver.hpp>
50 : #include <com/sun/star/container/XNameAccess.hpp>
51 :
52 : using namespace ::com::sun::star;
53 :
54 : using ::com::sun::star::uno::Reference;
55 : using ::com::sun::star::uno::Sequence;
56 : using ::osl::MutexGuard;
57 :
58 : namespace
59 : {
60 : char const sXML_metaStreamName[] = "meta.xml";
61 : char const sXML_styleStreamName[] = "styles.xml";
62 : char const sXML_contentStreamName[] = "content.xml";
63 : char const sXML_oldContentStreamName[] = "Content.xml";
64 :
65 : // soffice 6/7
66 : char const sXML_export_chart_styles_service[] = "com.sun.star.comp.Chart.XMLStylesExporter";
67 : char const sXML_export_chart_content_service[] = "com.sun.star.comp.Chart.XMLContentExporter";
68 :
69 : char const sXML_import_chart_styles_service[] = "com.sun.star.comp.Chart.XMLStylesImporter";
70 : char const sXML_import_chart_content_service[] = "com.sun.star.comp.Chart.XMLContentImporter";
71 : char const sXML_import_chart_old_content_service[] = "com.sun.star.office.sax.importer.Chart";
72 :
73 : // Oasis
74 : char const sXML_export_chart_oasis_styles_service[] = "com.sun.star.comp.Chart.XMLOasisStylesExporter";
75 : char const sXML_export_chart_oasis_content_service[] = "com.sun.star.comp.Chart.XMLOasisContentExporter";
76 : char const sXML_export_chart_oasis_meta_service[] = "com.sun.star.comp.Chart.XMLOasisMetaExporter";
77 :
78 : char const sXML_import_chart_oasis_styles_service[] = "com.sun.star.comp.Chart.XMLOasisStylesImporter";
79 : char const sXML_import_chart_oasis_content_service[] = "com.sun.star.comp.Chart.XMLOasisContentImporter";
80 : char const sXML_import_chart_oasis_meta_service[] = "com.sun.star.comp.Chart.XMLOasisMetaImporter";
81 :
82 269 : uno::Reference< embed::XStorage > lcl_getWriteStorage(
83 : const Sequence< beans::PropertyValue >& rMediaDescriptor,
84 : const uno::Reference< uno::XComponentContext >& xContext,const OUString& _sMediaType)
85 : {
86 269 : uno::Reference< embed::XStorage > xStorage;
87 : try
88 : {
89 269 : apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
90 269 : if( aMDHelper.ISSET_Storage )
91 : {
92 269 : xStorage = aMDHelper.Storage;
93 : }
94 : else
95 : {
96 0 : Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
97 :
98 0 : ::std::vector< beans::PropertyValue > aPropertiesForStorage;
99 :
100 0 : for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
101 : {
102 : // properties understood by storage factory
103 : // (see package/source/xstor/xfactory.cxx for details)
104 0 : if ( rMediaDescriptor[i].Name == "InteractionHandler" || rMediaDescriptor[i].Name == "Password" || rMediaDescriptor[i].Name == "RepairPackage" )
105 : {
106 0 : aPropertiesForStorage.push_back( rMediaDescriptor[i] );
107 : }
108 : }
109 :
110 0 : if( aMDHelper.ISSET_Storage )
111 0 : xStorage.set( aMDHelper.Storage );
112 : else
113 : {
114 0 : Sequence< uno::Any > aStorageArgs( 3 );
115 0 : if( aMDHelper.ISSET_OutputStream )
116 0 : aStorageArgs[0] <<= aMDHelper.OutputStream;
117 : else
118 0 : aStorageArgs[0] <<= aMDHelper.URL;
119 0 : aStorageArgs[1] <<= (embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE);
120 0 : aStorageArgs[2] <<= ::chart::ContainerHelper::ContainerToSequence( aPropertiesForStorage );
121 :
122 : xStorage.set(
123 0 : xStorageFact->createInstanceWithArguments( aStorageArgs ),
124 0 : uno::UNO_QUERY_THROW );
125 0 : }
126 : }
127 :
128 : // set correct media type at storage
129 538 : uno::Reference<beans::XPropertySet> xProp(xStorage,uno::UNO_QUERY);
130 538 : OUString aMediaType;
131 1345 : if ( ! xProp.is() ||
132 1614 : ! ( xProp->getPropertyValue( "MediaType") >>= aMediaType ) ||
133 269 : ( aMediaType.isEmpty() ))
134 : {
135 269 : xProp->setPropertyValue( "MediaType", uno::makeAny( _sMediaType ));
136 269 : }
137 : }
138 0 : catch (const uno::Exception& ex)
139 : {
140 : ASSERT_EXCEPTION( ex );
141 : }
142 269 : return xStorage;
143 : }
144 :
145 85 : uno::Reference< embed::XStorage > lcl_getReadStorage(
146 : const Sequence< beans::PropertyValue >& rMediaDescriptor,
147 : const uno::Reference< uno::XComponentContext >& xContext)
148 : {
149 85 : uno::Reference< embed::XStorage > xStorage;
150 :
151 : try
152 : {
153 85 : apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
154 85 : if( aMDHelper.ISSET_Storage )
155 : {
156 85 : xStorage = aMDHelper.Storage;
157 : }
158 : else
159 : {
160 : // get XStream from MediaDescriptor
161 0 : uno::Reference< io::XInputStream > xStream;
162 0 : ::std::vector< beans::PropertyValue > aPropertiesForStorage;
163 0 : for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
164 : {
165 0 : if( rMediaDescriptor[i].Name == "InputStream" )
166 0 : xStream.set( rMediaDescriptor[i].Value, uno::UNO_QUERY );
167 :
168 : // properties understood by storage factory
169 : // (see package/source/xstor/xfactory.cxx for details)
170 0 : if ( rMediaDescriptor[i].Name == "InteractionHandler" || rMediaDescriptor[i].Name == "Password" || rMediaDescriptor[i].Name == "RepairPackage" )
171 : {
172 0 : aPropertiesForStorage.push_back( rMediaDescriptor[i] );
173 : }
174 : }
175 : OSL_ENSURE( xStream.is(), "No Stream" );
176 0 : if( ! xStream.is())
177 0 : return xStorage;
178 :
179 : // convert XInputStream to XStorage via the storage factory
180 0 : Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
181 0 : Sequence< uno::Any > aStorageArgs( 3 );
182 0 : aStorageArgs[0] <<= xStream;
183 0 : aStorageArgs[1] <<= (embed::ElementModes::READ | embed::ElementModes::NOCREATE);
184 0 : aStorageArgs[2] <<= ::chart::ContainerHelper::ContainerToSequence( aPropertiesForStorage );
185 : xStorage.set(
186 0 : xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
187 : }
188 :
189 85 : OSL_ENSURE( xStorage.is(), "No Storage" );
190 : }
191 0 : catch (const uno::Exception& ex)
192 : {
193 : ASSERT_EXCEPTION( ex );
194 : }
195 :
196 85 : return xStorage;
197 : }
198 :
199 : } // anonymous namespace
200 :
201 : namespace chart
202 : {
203 :
204 356 : XMLFilter::XMLFilter( Reference< uno::XComponentContext > const & xContext ) :
205 : m_xContext( xContext ),
206 356 : m_bCancelOperation( false )
207 356 : {}
208 :
209 711 : XMLFilter::~XMLFilter()
210 711 : {}
211 :
212 : // ____ XFilter ____
213 354 : sal_Bool SAL_CALL XMLFilter::filter(
214 : const Sequence< beans::PropertyValue >& aDescriptor )
215 : throw (uno::RuntimeException, std::exception)
216 : {
217 354 : bool bResult = false;
218 :
219 354 : MutexGuard aGuard( m_aMutex );
220 :
221 : // ignore cancel flag at start of function
222 : // note: is currently ignored during import/export
223 354 : if( m_bCancelOperation )
224 0 : m_bCancelOperation = false;
225 :
226 354 : if( m_xSourceDoc.is())
227 : {
228 : OSL_ENSURE( ! m_xTargetDoc.is(), "source doc is set -> target document should not be set" );
229 269 : if( impl_Export( m_xSourceDoc,
230 269 : aDescriptor ) == 0 )
231 : {
232 269 : m_xSourceDoc = NULL;
233 269 : bResult = true;
234 : }
235 : }
236 85 : else if( m_xTargetDoc.is())
237 : {
238 85 : if( impl_Import( m_xTargetDoc,
239 85 : aDescriptor ) == 0 )
240 : {
241 85 : m_xTargetDoc = NULL;
242 85 : bResult = true;
243 : }
244 : }
245 : else
246 : {
247 : OSL_FAIL( "filter() called with no document set" );
248 : }
249 :
250 354 : return bResult;
251 : }
252 :
253 0 : void SAL_CALL XMLFilter::cancel()
254 : throw (uno::RuntimeException, std::exception)
255 : {
256 : // if mutex is locked set "cancel state"
257 : // note: is currently ignored in filter-method
258 0 : if( ! m_aMutex.tryToAcquire())
259 : {
260 0 : m_bCancelOperation = true;
261 : }
262 0 : }
263 :
264 : // ____ XImporter ____
265 85 : void SAL_CALL XMLFilter::setTargetDocument(
266 : const Reference< lang::XComponent >& Document )
267 : throw (lang::IllegalArgumentException,
268 : uno::RuntimeException, std::exception)
269 : {
270 85 : MutexGuard aGuard( m_aMutex );
271 : OSL_ENSURE( ! m_xSourceDoc.is(), "Setting target doc while source doc is set" );
272 :
273 85 : m_xTargetDoc = Document;
274 85 : }
275 :
276 : // ____ XExporter ____
277 269 : void SAL_CALL XMLFilter::setSourceDocument(
278 : const Reference< lang::XComponent >& Document )
279 : throw (lang::IllegalArgumentException,
280 : uno::RuntimeException, std::exception)
281 : {
282 269 : MutexGuard aGuard( m_aMutex );
283 : OSL_ENSURE( ! m_xTargetDoc.is(), "Setting source doc while target doc is set" );
284 :
285 269 : m_xSourceDoc = Document;
286 269 : }
287 :
288 85 : sal_Int32 XMLFilter::impl_Import(
289 : const Reference< lang::XComponent > & xDocumentComp,
290 : const Sequence< beans::PropertyValue > & rMediaDescriptor )
291 : {
292 85 : sal_Int32 nWarning = 0;
293 :
294 : OSL_ENSURE( xDocumentComp.is(), "Import: No Model" );
295 : OSL_ENSURE( m_xContext.is(), "Import: No ComponentContext" );
296 :
297 170 : if( ! (xDocumentComp.is() &&
298 85 : m_xContext.is()))
299 0 : return nWarning;
300 :
301 : try
302 : {
303 85 : Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
304 85 : if( ! xServInfo->supportsService( "com.sun.star.chart2.ChartDocument"))
305 : {
306 : OSL_FAIL( "Import: No ChartDocument" );
307 0 : return ERRCODE_SFX_GENERAL;
308 : }
309 :
310 170 : Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
311 : OSL_ENSURE( xFactory.is(), "Import: No Factory" );
312 85 : if( ! xFactory.is())
313 0 : return ERRCODE_SFX_GENERAL;
314 :
315 : // create a sax parser
316 170 : Reference< xml::sax::XParser > xSaxParser = xml::sax::Parser::create(m_xContext);
317 :
318 85 : bool bOasis = true;
319 85 : isOasisFormat( rMediaDescriptor, bOasis );
320 170 : Reference< embed::XStorage > xStorage( lcl_getReadStorage( rMediaDescriptor, m_xContext));
321 85 : if( ! xStorage.is())
322 0 : return ERRCODE_SFX_GENERAL;
323 :
324 170 : Reference< document::XGraphicObjectResolver > xGraphicObjectResolver;
325 170 : uno::Reference< lang::XMultiServiceFactory > xServiceFactory( xFactory, uno::UNO_QUERY);
326 85 : if( xServiceFactory.is())
327 : {
328 85 : uno::Sequence< uno::Any > aArgs(1);
329 85 : aArgs[0] <<= xStorage;
330 : xGraphicObjectResolver.set(
331 85 : xServiceFactory->createInstanceWithArguments(
332 85 : "com.sun.star.comp.Svx.GraphicImportHelper", aArgs ), uno::UNO_QUERY );
333 : }
334 :
335 : // create XPropertySet with extra informatio for the filter
336 : /** property map for import info set */
337 : comphelper::PropertyMapEntry const aImportInfoMap[] =
338 : {
339 : // necessary properties for XML progress bar at load time
340 85 : { OUString("ProgressRange"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
341 85 : { OUString("ProgressMax"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
342 85 : { OUString("ProgressCurrent"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
343 : { OUString("PrivateData"), 0,
344 85 : cppu::UnoType<XInterface>::get(),
345 : ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
346 : { OUString("BaseURI"), 0,
347 85 : ::cppu::UnoType<OUString>::get(),
348 : ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
349 : { OUString("StreamRelPath"), 0,
350 85 : ::cppu::UnoType<OUString>::get(),
351 : ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
352 : { OUString("StreamName"), 0,
353 85 : ::cppu::UnoType<OUString>::get(),
354 : ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
355 : { OUString("BuildId"), 0,
356 85 : ::cppu::UnoType<OUString>::get(),
357 : ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
358 : { OUString(), 0, css::uno::Type(), 0, 0 }
359 850 : };
360 : uno::Reference< beans::XPropertySet > xImportInfo(
361 : comphelper::GenericPropertySet_CreateInstance(
362 170 : new comphelper::PropertySetInfo( aImportInfoMap ) ) );
363 :
364 : // Set base URI and Hierarchical Name
365 170 : OUString aHierarchName, aBaseUri;
366 170 : uno::Reference< frame::XModel > xModel( m_xSourceDoc, uno::UNO_QUERY );
367 85 : if( xModel.is() )
368 : {
369 0 : uno::Sequence< beans::PropertyValue > aModProps = xModel->getArgs();
370 0 : for( sal_Int32 nInd = 0; nInd < aModProps.getLength(); nInd++ )
371 : {
372 0 : if( aModProps[nInd].Name == "HierarchicalDocumentName" )
373 : {
374 : // Actually this argument only has meaning for embedded documents
375 0 : aModProps[nInd].Value >>= aHierarchName;
376 : }
377 0 : else if( aModProps[nInd].Name == "DocumentBaseURL" )
378 : {
379 0 : aModProps[nInd].Value >>= aBaseUri;
380 : }
381 0 : }
382 : }
383 :
384 85 : if( !aBaseUri.isEmpty() )
385 0 : xImportInfo->setPropertyValue( "BaseURI", uno::makeAny( aBaseUri ) );
386 :
387 85 : if( !aHierarchName.isEmpty() )
388 0 : xImportInfo->setPropertyValue( "StreamRelPath", uno::makeAny( aHierarchName ) );
389 :
390 : // import meta information
391 85 : if( bOasis )
392 : nWarning |= impl_ImportStream(
393 : sXML_metaStreamName,
394 : sXML_import_chart_oasis_meta_service,
395 82 : xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
396 :
397 : // import styles
398 : nWarning |= impl_ImportStream(
399 : sXML_styleStreamName,
400 : bOasis
401 : ? OUString(sXML_import_chart_oasis_styles_service)
402 : : OUString(sXML_import_chart_styles_service),
403 85 : xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
404 :
405 : // import content
406 : sal_Int32 nContentWarning = impl_ImportStream(
407 : sXML_contentStreamName,
408 : bOasis
409 : ? OUString(sXML_import_chart_oasis_content_service)
410 : : OUString(sXML_import_chart_content_service),
411 85 : xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
412 85 : nWarning |= nContentWarning;
413 :
414 : // import of "content.xml" didn't work - try old "Content.xml" stream
415 85 : if( nContentWarning != 0 )
416 : {
417 : nWarning = impl_ImportStream(
418 : sXML_oldContentStreamName,
419 : sXML_import_chart_old_content_service,
420 0 : xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
421 85 : }
422 : }
423 0 : catch (const uno::Exception& ex)
424 : {
425 : ASSERT_EXCEPTION( ex );
426 :
427 : // something went awry
428 0 : nWarning = ERRCODE_SFX_GENERAL;
429 : }
430 :
431 85 : return nWarning;
432 : }
433 :
434 252 : sal_Int32 XMLFilter::impl_ImportStream(
435 : const OUString & rStreamName,
436 : const OUString & rServiceName,
437 : const Reference< embed::XStorage > & xStorage,
438 : const Reference< xml::sax::XParser > & xParser,
439 : const Reference< lang::XMultiComponentFactory > & xFactory,
440 : const Reference< document::XGraphicObjectResolver > & xGraphicObjectResolver,
441 : uno::Reference< beans::XPropertySet >& xImportInfo )
442 : {
443 252 : sal_Int32 nWarning = ERRCODE_SFX_GENERAL;
444 :
445 252 : Reference< container::XNameAccess > xNameAcc( xStorage, uno::UNO_QUERY );
446 504 : if( ! (xNameAcc.is() &&
447 252 : xNameAcc->hasByName( rStreamName )))
448 0 : return 0;
449 :
450 252 : if( xImportInfo.is() )
451 252 : xImportInfo->setPropertyValue( "StreamName", uno::makeAny( rStreamName ) );
452 :
453 504 : if( xStorage.is() &&
454 252 : xStorage->isStreamElement( rStreamName ) )
455 : {
456 : try
457 : {
458 252 : xml::sax::InputSource aParserInput;
459 : aParserInput.aInputStream.set(
460 252 : xStorage->openStreamElement(
461 : rStreamName,
462 252 : embed::ElementModes::READ | embed::ElementModes::NOCREATE ),
463 252 : uno::UNO_QUERY );
464 :
465 : // todo: encryption
466 :
467 252 : if( aParserInput.aInputStream.is())
468 : {
469 252 : sal_Int32 nArgs = 0;
470 252 : if( xGraphicObjectResolver.is())
471 243 : nArgs++;
472 252 : if( xImportInfo.is())
473 252 : nArgs++;
474 :
475 252 : uno::Sequence< uno::Any > aFilterCompArgs( nArgs );
476 :
477 252 : nArgs = 0;
478 252 : if( xGraphicObjectResolver.is())
479 243 : aFilterCompArgs[nArgs++] <<= xGraphicObjectResolver;
480 252 : if( xImportInfo.is())
481 252 : aFilterCompArgs[ nArgs++ ] <<= xImportInfo;
482 :
483 : Reference< xml::sax::XDocumentHandler > xDocHandler(
484 252 : xFactory->createInstanceWithArgumentsAndContext( rServiceName, aFilterCompArgs, m_xContext ),
485 504 : uno::UNO_QUERY_THROW );
486 :
487 504 : Reference< document::XImporter > xImporter( xDocHandler, uno::UNO_QUERY_THROW );
488 252 : xImporter->setTargetDocument( Reference< lang::XComponent >( m_xTargetDoc, uno::UNO_QUERY_THROW ));
489 :
490 252 : if ( !m_sDocumentHandler.isEmpty() )
491 : {
492 : try
493 : {
494 0 : uno::Sequence< uno::Any > aArgs(2);
495 0 : beans::NamedValue aValue;
496 0 : aValue.Name = "DocumentHandler";
497 0 : aValue.Value <<= xDocHandler;
498 0 : aArgs[0] <<= aValue;
499 0 : aValue.Name = "Model";
500 0 : aValue.Value <<= m_xTargetDoc;
501 0 : aArgs[1] <<= aValue;
502 :
503 0 : xDocHandler.set(xFactory->createInstanceWithArgumentsAndContext(m_sDocumentHandler,aArgs,m_xContext), uno::UNO_QUERY );
504 0 : xImporter.set(xDocHandler,uno::UNO_QUERY);
505 : }
506 0 : catch (const uno::Exception&)
507 : {
508 : OSL_FAIL("Exception caught!");
509 : }
510 : }
511 252 : xParser->setDocumentHandler( xDocHandler );
512 504 : xParser->parseStream( aParserInput );
513 : }
514 :
515 : // load was successful
516 252 : nWarning = 0;
517 : }
518 0 : catch (const xml::sax::SAXParseException&)
519 : {
520 : // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
521 : }
522 0 : catch (const xml::sax::SAXException&)
523 : {
524 : // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
525 : }
526 0 : catch (const packages::zip::ZipIOException&)
527 : {
528 0 : nWarning = ERRCODE_IO_BROKENPACKAGE;
529 : }
530 0 : catch (const io::IOException&)
531 : {
532 : }
533 0 : catch (const uno::Exception& rEx)
534 : {
535 : ASSERT_EXCEPTION(rEx);
536 : }
537 : }
538 :
539 252 : return nWarning;
540 : }
541 :
542 269 : sal_Int32 XMLFilter::impl_Export(
543 : const Reference< lang::XComponent > & xDocumentComp,
544 : const Sequence< beans::PropertyValue > & rMediaDescriptor )
545 : {
546 269 : m_aMediaDescriptor = rMediaDescriptor;
547 : //save
548 :
549 269 : sal_Int32 nWarning = 0;
550 :
551 : OSL_ENSURE( xDocumentComp.is(), "Export: No Model" );
552 : OSL_ENSURE( m_xContext.is(), "Export: No ComponentContext" );
553 :
554 269 : if( !xDocumentComp.is() || !m_xContext.is() )
555 0 : return nWarning;
556 :
557 : try
558 : {
559 269 : Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
560 269 : if( ! xServInfo->supportsService( "com.sun.star.chart2.ChartDocument"))
561 : {
562 : OSL_FAIL( "Export: No ChartDocument" );
563 0 : return ERRCODE_SFX_GENERAL;
564 : }
565 :
566 538 : Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
567 : OSL_ENSURE( xFactory.is(), "Export: No Factory" );
568 269 : if( ! xFactory.is())
569 0 : return ERRCODE_SFX_GENERAL;
570 538 : uno::Reference< lang::XMultiServiceFactory > xServiceFactory( m_xContext->getServiceManager(), uno::UNO_QUERY);
571 269 : if( ! xServiceFactory.is())
572 0 : return ERRCODE_SFX_GENERAL;
573 :
574 538 : uno::Reference< xml::sax::XWriter > xSaxWriter = xml::sax::Writer::create(m_xContext);
575 :
576 269 : bool bOasis = true;
577 269 : isOasisFormat( rMediaDescriptor, bOasis );
578 :
579 538 : uno::Reference< embed::XStorage > xStorage( lcl_getWriteStorage( rMediaDescriptor, m_xContext, getMediaType(bOasis) ) );
580 : OSL_ENSURE( xStorage.is(), "No Storage" );
581 269 : if( ! xStorage.is())
582 0 : return ERRCODE_SFX_GENERAL;
583 :
584 538 : uno::Reference< xml::sax::XDocumentHandler> xDocHandler( xSaxWriter, uno::UNO_QUERY );
585 :
586 269 : if ( !m_sDocumentHandler.isEmpty() )
587 : {
588 : try
589 : {
590 0 : uno::Sequence< uno::Any > aArgs(2);
591 0 : beans::NamedValue aValue;
592 0 : aValue.Name = "DocumentHandler";
593 0 : aValue.Value <<= xDocHandler;
594 0 : aArgs[0] <<= aValue;
595 0 : aValue.Name = "Model";
596 0 : aValue.Value <<= xDocumentComp;
597 0 : aArgs[1] <<= aValue;
598 :
599 0 : xDocHandler.set(xServiceFactory->createInstanceWithArguments(m_sDocumentHandler,aArgs), uno::UNO_QUERY );
600 0 : xSaxWriter.set(xDocHandler,uno::UNO_QUERY);
601 : }
602 0 : catch (const uno::Exception&)
603 : {
604 : OSL_FAIL("Exception caught!");
605 : }
606 : }
607 :
608 : Reference< document::XGraphicObjectResolver > xGraphicObjectResolver = document::GraphicObjectResolver::createWithStorage(
609 538 : m_xContext, xStorage );
610 :
611 : // property map for export info set
612 : comphelper::PropertyMapEntry const aExportInfoMap[] =
613 : {
614 269 : { OUString("UsePrettyPrinting"), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::MAYBEVOID, 0},
615 269 : { OUString("BaseURI"), 0, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
616 269 : { OUString("StreamRelPath"), 0, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
617 269 : { OUString("StreamName"), 0, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
618 269 : { OUString("ExportTableNumberList"), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
619 : { OUString(), 0, css::uno::Type(), 0, 0 }
620 1883 : };
621 :
622 : uno::Reference< beans::XPropertySet > xInfoSet =
623 538 : comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) );
624 :
625 538 : SvtSaveOptions aSaveOpt;
626 538 : OUString sUsePrettyPrinting( "UsePrettyPrinting" );
627 269 : bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
628 269 : xInfoSet->setPropertyValue( sUsePrettyPrinting, uno::makeAny( bUsePrettyPrinting ) );
629 269 : if( ! bOasis )
630 0 : xInfoSet->setPropertyValue( "ExportTableNumberList", uno::makeAny( true ));
631 :
632 269 : sal_Int32 nArgs = 2;
633 269 : if( xGraphicObjectResolver.is())
634 269 : nArgs++;
635 :
636 538 : uno::Sequence< uno::Any > aFilterProperties( nArgs );
637 : {
638 269 : nArgs = 0;
639 269 : aFilterProperties[ nArgs++ ] <<= xInfoSet;
640 269 : aFilterProperties[ nArgs++ ] <<= xDocHandler;
641 269 : if( xGraphicObjectResolver.is())
642 269 : aFilterProperties[ nArgs++ ] <<= xGraphicObjectResolver;
643 : }
644 :
645 : // export meta information
646 269 : if( bOasis )
647 : nWarning |= impl_ExportStream(
648 : sXML_metaStreamName,
649 : sXML_export_chart_oasis_meta_service,
650 269 : xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
651 :
652 : // export styles
653 : nWarning |= impl_ExportStream(
654 : sXML_styleStreamName,
655 : bOasis
656 : ? OUString(sXML_export_chart_oasis_styles_service)
657 : : OUString(sXML_export_chart_styles_service),
658 269 : xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
659 :
660 : // export content
661 : sal_Int32 nContentWarning = impl_ExportStream(
662 : sXML_contentStreamName,
663 : bOasis
664 : ? OUString(sXML_export_chart_oasis_content_service)
665 : : OUString(sXML_export_chart_content_service),
666 269 : xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
667 269 : nWarning |= nContentWarning;
668 :
669 538 : Reference< lang::XComponent > xComp( xGraphicObjectResolver, uno::UNO_QUERY );
670 269 : if( xComp.is())
671 269 : xComp->dispose();
672 :
673 538 : uno::Reference<embed::XTransactedObject> xTransact( xStorage ,uno::UNO_QUERY);
674 269 : if ( xTransact.is() )
675 538 : xTransact->commit();
676 : }
677 0 : catch (const uno::Exception& ex)
678 : {
679 : ASSERT_EXCEPTION( ex );
680 :
681 : // something went awry
682 0 : nWarning = ERRCODE_SFX_GENERAL;
683 : }
684 :
685 269 : return nWarning;
686 : }
687 :
688 807 : sal_Int32 XMLFilter::impl_ExportStream(
689 : const OUString & rStreamName,
690 : const OUString & rServiceName,
691 : const Reference< embed::XStorage > & xStorage,
692 : const uno::Reference< xml::sax::XWriter >& xActiveDataSource,
693 : const Reference< lang::XMultiServiceFactory >& xServiceFactory,
694 : const Sequence< uno::Any > & rFilterProperties )
695 : {
696 807 : sal_Int32 nWarning = 0;
697 :
698 : try
699 : {
700 807 : if( !xServiceFactory.is() )
701 0 : return ERRCODE_SFX_GENERAL;
702 807 : if( !xStorage.is() )
703 0 : return ERRCODE_SFX_GENERAL;
704 807 : if ( !xActiveDataSource.is() )
705 0 : return ERRCODE_SFX_GENERAL;
706 :
707 807 : uno::Reference< io::XStream > xStream( xStorage->openStreamElement(
708 807 : rStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ) );
709 807 : if ( !xStream.is() )
710 0 : return ERRCODE_SFX_GENERAL;
711 1614 : uno::Reference< io::XOutputStream > xOutputStream( xStream->getOutputStream() );
712 807 : if ( !xOutputStream.is() )
713 0 : return ERRCODE_SFX_GENERAL;
714 :
715 1614 : uno::Reference< beans::XPropertySet > xStreamProp( xOutputStream, uno::UNO_QUERY );
716 807 : if(xStreamProp.is()) try
717 : {
718 807 : xStreamProp->setPropertyValue( "MediaType", uno::makeAny( OUString("text/xml") ) );
719 807 : xStreamProp->setPropertyValue( "Compressed", uno::makeAny( sal_True ) );//@todo?
720 807 : xStreamProp->setPropertyValue( "UseCommonStoragePasswordEncryption", uno::makeAny( sal_True ) );
721 : }
722 0 : catch (const uno::Exception& rEx)
723 : {
724 : ASSERT_EXCEPTION( rEx );
725 : }
726 :
727 807 : xActiveDataSource->setOutputStream(xOutputStream);
728 :
729 : // set Base URL
730 : {
731 807 : uno::Reference< beans::XPropertySet > xInfoSet;
732 807 : if( rFilterProperties.getLength() > 0 )
733 807 : rFilterProperties.getConstArray()[0] >>= xInfoSet;
734 : OSL_ENSURE( xInfoSet.is(), "missing infoset for export" );
735 807 : if( xInfoSet.is() )
736 807 : xInfoSet->setPropertyValue( "StreamName", uno::makeAny( rStreamName ) );
737 : }
738 :
739 807 : Reference< XExporter > xExporter( xServiceFactory->createInstanceWithArguments(
740 1614 : rServiceName, rFilterProperties ), uno::UNO_QUERY);
741 807 : if ( !xExporter.is() )
742 0 : return ERRCODE_SFX_GENERAL;
743 :
744 807 : xExporter->setSourceDocument( m_xSourceDoc );
745 :
746 1614 : uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY );
747 807 : if ( !xFilter.is() )
748 0 : return ERRCODE_SFX_GENERAL;
749 :
750 1614 : xFilter->filter(m_aMediaDescriptor);
751 : }
752 0 : catch (const uno::Exception& rEx)
753 : {
754 : ASSERT_EXCEPTION( rEx );
755 : }
756 807 : return nWarning;
757 : }
758 :
759 2 : Sequence< OUString > XMLFilter::getSupportedServiceNames_Static()
760 : {
761 2 : Sequence< OUString > aServices( 2 );
762 2 : aServices[ 0 ] = "com.sun.star.document.ImportFilter";
763 2 : aServices[ 1 ] = "com.sun.star.document.ExportFilter";
764 :
765 : // todo: services are incomplete. Missing:
766 : // XInitialization, XNamed
767 2 : return aServices;
768 : }
769 :
770 354 : void XMLFilter::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
771 : {
772 354 : apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
773 354 : if( aMDHelper.ISSET_FilterName )
774 354 : rOutOASIS = aMDHelper.FilterName == "chart8";
775 354 : }
776 269 : OUString XMLFilter::getMediaType(bool _bOasis)
777 : {
778 269 : return _bOasis ? OUString(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII) : OUString(MIMETYPE_VND_SUN_XML_CHART_ASCII);
779 : }
780 :
781 1 : OUString SAL_CALL XMLFilter::getImplementationName()
782 : throw( css::uno::RuntimeException, std::exception )
783 : {
784 1 : return getImplementationName_Static();
785 : }
786 :
787 1 : OUString XMLFilter::getImplementationName_Static()
788 : {
789 1 : return OUString("com.sun.star.comp.chart2.XMLFilter");
790 : }
791 :
792 0 : sal_Bool SAL_CALL XMLFilter::supportsService( const OUString& rServiceName )
793 : throw( css::uno::RuntimeException, std::exception )
794 : {
795 0 : return cppu::supportsService(this, rServiceName);
796 : }
797 :
798 2 : css::uno::Sequence< OUString > SAL_CALL XMLFilter::getSupportedServiceNames()
799 : throw( css::uno::RuntimeException, std::exception )
800 : {
801 2 : return getSupportedServiceNames_Static();
802 : }
803 :
804 0 : void XMLReportFilterHelper::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
805 : {
806 0 : apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
807 0 : if( aMDHelper.ISSET_FilterName )
808 0 : rOutOASIS = aMDHelper.FilterName == "StarOffice XML (Base) Report Chart";
809 0 : }
810 0 : OUString XMLReportFilterHelper::getMediaType(bool )
811 : {
812 0 : return OUString(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII);
813 : }
814 :
815 : } // namespace chart
816 :
817 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
818 355 : com_sun_star_comp_chart2_XMLFilter_get_implementation(css::uno::XComponentContext *context,
819 : css::uno::Sequence<css::uno::Any> const &)
820 : {
821 355 : return cppu::acquire(new ::chart::XMLFilter(context));
822 : }
823 :
824 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
825 1 : com_sun_star_comp_chart2_report_XMLFilter_get_implementation(css::uno::XComponentContext *context,
826 : css::uno::Sequence<css::uno::Any> const &)
827 : {
828 1 : return cppu::acquire(new ::chart::XMLReportFilterHelper(context));
829 : }
830 :
831 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|