Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / chart2 / source / model / filter / XMLFilter.cxx
blobf9ca9cdcd40a7baae1b916ca820284b1bc747fa6
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 .
20 #include <XMLFilter.hxx>
21 #include <MediaDescriptorHelper.hxx>
23 #include <svtools/sfxecode.hxx>
24 #include <unotools/saveopt.hxx>
25 #include <comphelper/genericpropertyset.hxx>
26 #include <comphelper/propertysetinfo.hxx>
27 #include <comphelper/documentconstants.hxx>
28 #include <cppuhelper/supportsservice.hxx>
29 #include <comphelper/sequence.hxx>
31 #include <sot/storage.hxx>
32 #include <osl/diagnose.h>
33 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/xml/sax/InputSource.hpp>
36 #include <com/sun/star/xml/sax/Writer.hpp>
37 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
38 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
39 #include <com/sun/star/embed/ElementModes.hpp>
40 #include <com/sun/star/embed/XStorage.hpp>
41 #include <com/sun/star/embed/StorageFactory.hpp>
42 #include <com/sun/star/embed/XTransactedObject.hpp>
43 #include <com/sun/star/frame/XModel.hpp>
44 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
45 #include <com/sun/star/xml/sax/Parser.hpp>
46 #include <com/sun/star/xml/sax/SAXParseException.hpp>
47 #include <com/sun/star/packages/zip/ZipIOException.hpp>
48 #include <com/sun/star/document/GraphicStorageHandler.hpp>
49 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
50 #include <com/sun/star/container/XNameAccess.hpp>
51 #include <tools/diagnose_ex.h>
53 using namespace ::com::sun::star;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::uno::Sequence;
57 using ::osl::MutexGuard;
59 namespace
61 char const sXML_metaStreamName[] = "meta.xml";
62 char const sXML_styleStreamName[] = "styles.xml";
63 char const sXML_contentStreamName[] = "content.xml";
66 uno::Reference< embed::XStorage > lcl_getWriteStorage(
67 const Sequence< beans::PropertyValue >& rMediaDescriptor,
68 const uno::Reference< uno::XComponentContext >& xContext,const OUString& _sMediaType)
70 uno::Reference< embed::XStorage > xStorage;
71 try
73 apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
74 if( aMDHelper.ISSET_Storage )
76 xStorage = aMDHelper.Storage;
78 else
80 Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
82 std::vector< beans::PropertyValue > aPropertiesForStorage;
84 for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
86 // properties understood by storage factory
87 // (see package/source/xstor/xfactory.cxx for details)
88 if ( rMediaDescriptor[i].Name == "InteractionHandler" || rMediaDescriptor[i].Name == "Password" || rMediaDescriptor[i].Name == "RepairPackage" )
90 aPropertiesForStorage.push_back( rMediaDescriptor[i] );
94 if( aMDHelper.ISSET_Storage )
95 xStorage.set( aMDHelper.Storage );
96 else
98 Sequence< uno::Any > aStorageArgs( 3 );
99 if( aMDHelper.ISSET_OutputStream )
100 aStorageArgs[0] <<= aMDHelper.OutputStream;
101 else
102 aStorageArgs[0] <<= aMDHelper.URL;
103 aStorageArgs[1] <<= (embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE);
104 aStorageArgs[2] <<= comphelper::containerToSequence( aPropertiesForStorage );
106 xStorage.set(
107 xStorageFact->createInstanceWithArguments( aStorageArgs ),
108 uno::UNO_QUERY_THROW );
112 // set correct media type at storage
113 uno::Reference<beans::XPropertySet> xProp(xStorage,uno::UNO_QUERY);
114 OUString aMediaType;
115 if ( ! xProp.is() ||
116 ! ( xProp->getPropertyValue( "MediaType") >>= aMediaType ) ||
117 ( aMediaType.isEmpty() ))
119 xProp->setPropertyValue( "MediaType", uno::Any( _sMediaType ));
122 catch (const uno::Exception&)
124 DBG_UNHANDLED_EXCEPTION("chart2");
126 return xStorage;
129 uno::Reference< embed::XStorage > lcl_getReadStorage(
130 const Sequence< beans::PropertyValue >& rMediaDescriptor,
131 const uno::Reference< uno::XComponentContext >& xContext)
133 uno::Reference< embed::XStorage > xStorage;
137 apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
138 if( aMDHelper.ISSET_Storage )
140 xStorage = aMDHelper.Storage;
142 else
144 // get XStream from MediaDescriptor
145 uno::Reference< io::XInputStream > xStream;
146 std::vector< beans::PropertyValue > aPropertiesForStorage;
147 for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
149 if( rMediaDescriptor[i].Name == "InputStream" )
150 xStream.set( rMediaDescriptor[i].Value, uno::UNO_QUERY );
152 // properties understood by storage factory
153 // (see package/source/xstor/xfactory.cxx for details)
154 if ( rMediaDescriptor[i].Name == "InteractionHandler" || rMediaDescriptor[i].Name == "Password" || rMediaDescriptor[i].Name == "RepairPackage" )
156 aPropertiesForStorage.push_back( rMediaDescriptor[i] );
159 OSL_ENSURE( xStream.is(), "No Stream" );
160 if( ! xStream.is())
161 return xStorage;
163 // convert XInputStream to XStorage via the storage factory
164 Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
165 Sequence< uno::Any > aStorageArgs( 3 );
166 aStorageArgs[0] <<= xStream;
167 aStorageArgs[1] <<= (embed::ElementModes::READ | embed::ElementModes::NOCREATE);
168 aStorageArgs[2] <<= comphelper::containerToSequence( aPropertiesForStorage );
169 xStorage.set(
170 xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
173 OSL_ENSURE( xStorage.is(), "No Storage" );
175 catch (const uno::Exception&)
177 DBG_UNHANDLED_EXCEPTION("chart2");
180 return xStorage;
183 } // anonymous namespace
185 namespace chart
188 XMLFilter::XMLFilter( Reference< uno::XComponentContext > const & xContext ) :
189 m_xContext( xContext ),
190 m_bCancelOperation( false )
193 XMLFilter::~XMLFilter()
196 // ____ XFilter ____
197 sal_Bool SAL_CALL XMLFilter::filter(
198 const Sequence< beans::PropertyValue >& aDescriptor )
200 bool bResult = false;
202 MutexGuard aGuard( m_aMutex );
204 // ignore cancel flag at start of function
205 // note: is currently ignored during import/export
206 if( m_bCancelOperation )
207 m_bCancelOperation = false;
209 if( m_xSourceDoc.is())
211 OSL_ENSURE( ! m_xTargetDoc.is(), "source doc is set -> target document should not be set" );
212 if( impl_Export( m_xSourceDoc,
213 aDescriptor ) == ERRCODE_NONE )
215 m_xSourceDoc = nullptr;
216 bResult = true;
219 else if( m_xTargetDoc.is())
221 if( impl_Import( m_xTargetDoc,
222 aDescriptor ) == ERRCODE_NONE )
224 m_xTargetDoc = nullptr;
225 bResult = true;
228 else
230 OSL_FAIL( "filter() called with no document set" );
233 return bResult;
236 void SAL_CALL XMLFilter::cancel()
238 // if mutex is locked set "cancel state"
239 // note: is currently ignored in filter-method
240 if( ! m_aMutex.tryToAcquire())
242 m_bCancelOperation = true;
246 // ____ XImporter ____
247 void SAL_CALL XMLFilter::setTargetDocument(
248 const Reference< lang::XComponent >& Document )
250 MutexGuard aGuard( m_aMutex );
251 OSL_ENSURE( ! m_xSourceDoc.is(), "Setting target doc while source doc is set" );
253 m_xTargetDoc = Document;
256 // ____ XExporter ____
257 void SAL_CALL XMLFilter::setSourceDocument(
258 const Reference< lang::XComponent >& Document )
260 MutexGuard aGuard( m_aMutex );
261 OSL_ENSURE( ! m_xTargetDoc.is(), "Setting source doc while target doc is set" );
263 m_xSourceDoc = Document;
266 ErrCode XMLFilter::impl_Import(
267 const Reference< lang::XComponent > & xDocumentComp,
268 const Sequence< beans::PropertyValue > & rMediaDescriptor )
270 ErrCode nWarning = ERRCODE_NONE;
272 OSL_ENSURE( xDocumentComp.is(), "Import: No Model" );
273 OSL_ENSURE( m_xContext.is(), "Import: No ComponentContext" );
275 if( ! (xDocumentComp.is() &&
276 m_xContext.is()))
277 return nWarning;
281 Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
282 if( ! xServInfo->supportsService( "com.sun.star.chart2.ChartDocument"))
284 OSL_FAIL( "Import: No ChartDocument" );
285 return ERRCODE_SFX_GENERAL;
288 Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
289 OSL_ENSURE( xFactory.is(), "Import: No Factory" );
290 if( ! xFactory.is())
291 return ERRCODE_SFX_GENERAL;
293 // create a sax parser
294 Reference< xml::sax::XParser > xSaxParser = xml::sax::Parser::create(m_xContext);
296 bool bOasis = true;
297 isOasisFormat( rMediaDescriptor, bOasis );
298 Reference< embed::XStorage > xStorage( lcl_getReadStorage( rMediaDescriptor, m_xContext));
299 if( ! xStorage.is())
300 return ERRCODE_SFX_GENERAL;
302 uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler;
303 uno::Reference<lang::XMultiServiceFactory> xServiceFactory(xFactory, uno::UNO_QUERY);
304 if (xServiceFactory.is())
306 uno::Sequence<uno::Any> aArgs(1);
307 aArgs[0] <<= xStorage;
308 xGraphicStorageHandler.set(
309 xServiceFactory->createInstanceWithArguments(
310 "com.sun.star.comp.Svx.GraphicImportHelper", aArgs), uno::UNO_QUERY);
313 // create XPropertySet with extra informatio for the filter
314 /** property map for import info set */
315 comphelper::PropertyMapEntry const aImportInfoMap[] =
317 // necessary properties for XML progress bar at load time
318 { OUString("ProgressRange"), 0, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},
319 { OUString("ProgressMax"), 0, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},
320 { OUString("ProgressCurrent"), 0, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},
321 { OUString("PrivateData"), 0, cppu::UnoType<XInterface>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
322 { OUString("BaseURI"), 0, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
323 { OUString("StreamRelPath"), 0, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
324 { OUString("StreamName"), 0, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
325 { OUString("BuildId"), 0, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
326 { OUString(), 0, css::uno::Type(), 0, 0 }
328 uno::Reference< beans::XPropertySet > xImportInfo(
329 comphelper::GenericPropertySet_CreateInstance(
330 new comphelper::PropertySetInfo( aImportInfoMap ) ) );
332 // Set base URI and Hierarchical Name
333 OUString aHierarchName, aBaseUri;
334 // why retrieve this from the model when it's available as rMediaDescriptor?
335 uno::Reference<frame::XModel> const xModel(m_xTargetDoc, uno::UNO_QUERY);
336 if( xModel.is() )
338 uno::Sequence< beans::PropertyValue > aModProps = xModel->getArgs();
339 for( sal_Int32 nInd = 0; nInd < aModProps.getLength(); nInd++ )
341 if( aModProps[nInd].Name == "HierarchicalDocumentName" )
343 // Actually this argument only has meaning for embedded documents
344 aModProps[nInd].Value >>= aHierarchName;
346 else if( aModProps[nInd].Name == "DocumentBaseURL" )
348 aModProps[nInd].Value >>= aBaseUri;
353 // needed for relative URLs, but in clipboard copy/paste there may be none
354 SAL_INFO_IF(aBaseUri.isEmpty(), "chart2", "chart::XMLFilter: no base URL");
355 if( !aBaseUri.isEmpty() )
356 xImportInfo->setPropertyValue( "BaseURI", uno::Any( aBaseUri ) );
358 if( !aHierarchName.isEmpty() )
359 xImportInfo->setPropertyValue( "StreamRelPath", uno::Any( aHierarchName ) );
361 // import meta information
362 if( bOasis )
363 nWarning = impl_ImportStream(
364 sXML_metaStreamName,
365 "com.sun.star.comp.Chart.XMLOasisMetaImporter",
366 xStorage, xSaxParser, xFactory, xGraphicStorageHandler, xImportInfo );
368 // import styles
369 ErrCode nTmpErr = impl_ImportStream(
370 sXML_styleStreamName,
371 bOasis
372 ? OUString("com.sun.star.comp.Chart.XMLOasisStylesImporter")
373 : OUString("com.sun.star.comp.Chart.XMLStylesImporter"),
374 xStorage, xSaxParser, xFactory, xGraphicStorageHandler, xImportInfo );
375 nWarning = nWarning != ERRCODE_NONE ? nWarning : nTmpErr;
377 // import content
378 ErrCode nContentWarning = impl_ImportStream(
379 sXML_contentStreamName,
380 bOasis
381 ? OUString("com.sun.star.comp.Chart.XMLOasisContentImporter")
382 : OUString("com.sun.star.comp.Chart.XMLContentImporter"),
383 xStorage, xSaxParser, xFactory, xGraphicStorageHandler, xImportInfo );
384 nWarning = nWarning != ERRCODE_NONE ? nWarning : nContentWarning;
386 // import of "content.xml" didn't work - try old "Content.xml" stream
387 if( nContentWarning != ERRCODE_NONE )
389 nWarning = impl_ImportStream(
390 "Content.xml", // old content stream name
391 "com.sun.star.office.sax.importer.Chart",
392 xStorage, xSaxParser, xFactory, xGraphicStorageHandler, xImportInfo );
395 catch (const uno::Exception&)
397 DBG_UNHANDLED_EXCEPTION("chart2");
399 // something went awry
400 nWarning = ERRCODE_SFX_GENERAL;
403 return nWarning;
406 ErrCode XMLFilter::impl_ImportStream(
407 const OUString & rStreamName,
408 const OUString & rServiceName,
409 const Reference< embed::XStorage > & xStorage,
410 const Reference< xml::sax::XParser > & xParser,
411 const Reference< lang::XMultiComponentFactory > & xFactory,
412 const Reference< document::XGraphicStorageHandler > & xGraphicStorageHandler,
413 uno::Reference< beans::XPropertySet > const & xImportInfo )
415 ErrCode nWarning = ERRCODE_SFX_GENERAL;
417 Reference< container::XNameAccess > xNameAcc( xStorage, uno::UNO_QUERY );
418 if( ! (xNameAcc.is() &&
419 xNameAcc->hasByName( rStreamName )))
420 return ERRCODE_NONE;
422 if( xImportInfo.is() )
423 xImportInfo->setPropertyValue( "StreamName", uno::Any( rStreamName ) );
425 if( xStorage.is() &&
426 xStorage->isStreamElement( rStreamName ) )
430 xml::sax::InputSource aParserInput;
431 aParserInput.aInputStream.set(
432 xStorage->openStreamElement(
433 rStreamName,
434 embed::ElementModes::READ | embed::ElementModes::NOCREATE ),
435 uno::UNO_QUERY );
437 // todo: encryption
439 if( aParserInput.aInputStream.is())
441 sal_Int32 nArgs = 0;
442 if( xGraphicStorageHandler.is())
443 nArgs++;
444 if( xImportInfo.is())
445 nArgs++;
447 uno::Sequence< uno::Any > aFilterCompArgs( nArgs );
449 nArgs = 0;
450 if( xGraphicStorageHandler.is())
451 aFilterCompArgs[nArgs++] <<= xGraphicStorageHandler;
452 if( xImportInfo.is())
453 aFilterCompArgs[ nArgs++ ] <<= xImportInfo;
455 Reference< xml::sax::XDocumentHandler > xDocHandler(
456 xFactory->createInstanceWithArgumentsAndContext( rServiceName, aFilterCompArgs, m_xContext ),
457 uno::UNO_QUERY_THROW );
459 Reference< document::XImporter > xImporter( xDocHandler, uno::UNO_QUERY_THROW );
460 xImporter->setTargetDocument( Reference< lang::XComponent >( m_xTargetDoc, uno::UNO_QUERY_THROW ));
462 if ( !m_sDocumentHandler.isEmpty() )
466 uno::Sequence< uno::Any > aArgs(2);
467 beans::NamedValue aValue;
468 aValue.Name = "DocumentHandler";
469 aValue.Value <<= xDocHandler;
470 aArgs[0] <<= aValue;
471 aValue.Name = "Model";
472 aValue.Value <<= m_xTargetDoc;
473 aArgs[1] <<= aValue;
475 xDocHandler.set(xFactory->createInstanceWithArgumentsAndContext(m_sDocumentHandler,aArgs,m_xContext), uno::UNO_QUERY );
476 xImporter.set(xDocHandler,uno::UNO_QUERY);
478 catch (const uno::Exception&)
480 OSL_FAIL("Exception caught!");
483 xParser->setDocumentHandler( xDocHandler );
484 xParser->parseStream( aParserInput );
487 // load was successful
488 nWarning = ERRCODE_NONE;
490 catch (const xml::sax::SAXParseException&)
492 // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
494 catch (const xml::sax::SAXException&)
496 // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
498 catch (const packages::zip::ZipIOException&)
500 nWarning = ERRCODE_IO_BROKENPACKAGE;
502 catch (const io::IOException&)
505 catch (const uno::Exception&)
507 DBG_UNHANDLED_EXCEPTION("chart2");
511 return nWarning;
514 ErrCode XMLFilter::impl_Export(
515 const Reference< lang::XComponent > & xDocumentComp,
516 const Sequence< beans::PropertyValue > & rMediaDescriptor )
518 m_aMediaDescriptor = rMediaDescriptor;
519 //save
521 ErrCode nWarning = ERRCODE_NONE;
523 OSL_ENSURE( xDocumentComp.is(), "Export: No Model" );
524 OSL_ENSURE( m_xContext.is(), "Export: No ComponentContext" );
526 if( !xDocumentComp.is() || !m_xContext.is() )
527 return nWarning;
531 Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
532 if( ! xServInfo->supportsService( "com.sun.star.chart2.ChartDocument"))
534 OSL_FAIL( "Export: No ChartDocument" );
535 return ERRCODE_SFX_GENERAL;
538 Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
539 OSL_ENSURE( xFactory.is(), "Export: No Factory" );
540 if( ! xFactory.is())
541 return ERRCODE_SFX_GENERAL;
542 uno::Reference< lang::XMultiServiceFactory > xServiceFactory( m_xContext->getServiceManager(), uno::UNO_QUERY);
543 if( ! xServiceFactory.is())
544 return ERRCODE_SFX_GENERAL;
546 uno::Reference< xml::sax::XWriter > xSaxWriter = xml::sax::Writer::create(m_xContext);
548 bool bOasis = true;
549 isOasisFormat( rMediaDescriptor, bOasis );
551 uno::Reference< embed::XStorage > xStorage( lcl_getWriteStorage( rMediaDescriptor, m_xContext, getMediaType(bOasis) ) );
552 OSL_ENSURE( xStorage.is(), "No Storage" );
553 if( ! xStorage.is())
554 return ERRCODE_SFX_GENERAL;
556 uno::Reference< xml::sax::XDocumentHandler> xDocHandler( xSaxWriter, uno::UNO_QUERY );
558 if ( !m_sDocumentHandler.isEmpty() )
562 uno::Sequence< uno::Any > aArgs(2);
563 beans::NamedValue aValue;
564 aValue.Name = "DocumentHandler";
565 aValue.Value <<= xDocHandler;
566 aArgs[0] <<= aValue;
567 aValue.Name = "Model";
568 aValue.Value <<= xDocumentComp;
569 aArgs[1] <<= aValue;
571 xDocHandler.set(xServiceFactory->createInstanceWithArguments(m_sDocumentHandler,aArgs), uno::UNO_QUERY );
572 xSaxWriter.set(xDocHandler,uno::UNO_QUERY);
574 catch (const uno::Exception&)
576 OSL_FAIL("Exception caught!");
580 Reference<document::XGraphicStorageHandler> xGraphicStorageHandler;
581 xGraphicStorageHandler.set(document::GraphicStorageHandler::createWithStorage(m_xContext, xStorage));
583 // property map for export info set
584 comphelper::PropertyMapEntry const aExportInfoMap[] =
586 { OUString("UsePrettyPrinting"), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::MAYBEVOID, 0},
587 { OUString("BaseURI"), 0, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
588 { OUString("StreamRelPath"), 0, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
589 { OUString("StreamName"), 0, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
590 { OUString("ExportTableNumberList"), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
591 { OUString(), 0, css::uno::Type(), 0, 0 }
594 uno::Reference< beans::XPropertySet > xInfoSet =
595 comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) );
597 SvtSaveOptions aSaveOpt;
598 bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
599 xInfoSet->setPropertyValue( "UsePrettyPrinting", uno::Any( bUsePrettyPrinting ) );
600 if( ! bOasis )
601 xInfoSet->setPropertyValue( "ExportTableNumberList", uno::Any( true ));
603 sal_Int32 nArgs = 2;
604 if( xGraphicStorageHandler.is())
605 nArgs++;
607 uno::Sequence< uno::Any > aFilterProperties( nArgs );
609 nArgs = 0;
610 aFilterProperties[ nArgs++ ] <<= xInfoSet;
611 aFilterProperties[ nArgs++ ] <<= xDocHandler;
612 if( xGraphicStorageHandler.is())
613 aFilterProperties[ nArgs++ ] <<= xGraphicStorageHandler;
616 // export meta information
617 if( bOasis )
618 nWarning = impl_ExportStream(
619 sXML_metaStreamName,
620 "com.sun.star.comp.Chart.XMLOasisMetaExporter",
621 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
623 // export styles
624 ErrCode nTmp = impl_ExportStream(
625 sXML_styleStreamName,
626 bOasis
627 ? OUString("com.sun.star.comp.Chart.XMLOasisStylesExporter")
628 : OUString("com.sun.star.comp.Chart.XMLStylesExporter"), // soffice 6/7
629 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
630 nWarning = nWarning != ERRCODE_NONE ? nWarning : nTmp;
632 // export content
633 ErrCode nContentWarning = impl_ExportStream(
634 sXML_contentStreamName,
635 bOasis
636 ? OUString("com.sun.star.comp.Chart.XMLOasisContentExporter")
637 : OUString("com.sun.star.comp.Chart.XMLContentExporter"),
638 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
639 nWarning = nWarning != ERRCODE_NONE ? nWarning : nContentWarning;
641 Reference< lang::XComponent > xComp(xGraphicStorageHandler, uno::UNO_QUERY);
642 if (xComp.is())
643 xComp->dispose();
645 uno::Reference<embed::XTransactedObject> xTransact( xStorage ,uno::UNO_QUERY);
646 if ( xTransact.is() )
647 xTransact->commit();
649 catch (const uno::Exception&)
651 DBG_UNHANDLED_EXCEPTION("chart2");
653 // something went awry
654 nWarning = ERRCODE_SFX_GENERAL;
657 return nWarning;
660 ErrCode XMLFilter::impl_ExportStream(
661 const OUString & rStreamName,
662 const OUString & rServiceName,
663 const Reference< embed::XStorage > & xStorage,
664 const uno::Reference< xml::sax::XWriter >& xActiveDataSource,
665 const Reference< lang::XMultiServiceFactory >& xServiceFactory,
666 const Sequence< uno::Any > & rFilterProperties )
670 if( !xServiceFactory.is() )
671 return ERRCODE_SFX_GENERAL;
672 if( !xStorage.is() )
673 return ERRCODE_SFX_GENERAL;
674 if ( !xActiveDataSource.is() )
675 return ERRCODE_SFX_GENERAL;
677 uno::Reference< io::XStream > xStream( xStorage->openStreamElement(
678 rStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ) );
679 if ( !xStream.is() )
680 return ERRCODE_SFX_GENERAL;
681 uno::Reference< io::XOutputStream > xOutputStream( xStream->getOutputStream() );
682 if ( !xOutputStream.is() )
683 return ERRCODE_SFX_GENERAL;
685 uno::Reference< beans::XPropertySet > xStreamProp( xOutputStream, uno::UNO_QUERY );
686 if(xStreamProp.is()) try
688 xStreamProp->setPropertyValue( "MediaType", uno::Any( OUString("text/xml") ) );
689 xStreamProp->setPropertyValue( "Compressed", uno::Any( true ) );//@todo?
690 xStreamProp->setPropertyValue( "UseCommonStoragePasswordEncryption", uno::Any( true ) );
692 catch (const uno::Exception&)
694 DBG_UNHANDLED_EXCEPTION("chart2");
697 xActiveDataSource->setOutputStream(xOutputStream);
699 // set Base URL
701 uno::Reference< beans::XPropertySet > xInfoSet;
702 if( rFilterProperties.getLength() > 0 )
703 rFilterProperties.getConstArray()[0] >>= xInfoSet;
704 OSL_ENSURE( xInfoSet.is(), "missing infoset for export" );
705 if( xInfoSet.is() )
706 xInfoSet->setPropertyValue( "StreamName", uno::Any( rStreamName ) );
709 Reference< XExporter > xExporter( xServiceFactory->createInstanceWithArguments(
710 rServiceName, rFilterProperties ), uno::UNO_QUERY);
711 if ( !xExporter.is() )
712 return ERRCODE_SFX_GENERAL;
714 xExporter->setSourceDocument( m_xSourceDoc );
716 uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY );
717 if ( !xFilter.is() )
718 return ERRCODE_SFX_GENERAL;
720 xFilter->filter(m_aMediaDescriptor);
722 catch (const uno::Exception&)
724 DBG_UNHANDLED_EXCEPTION("chart2");
726 return ERRCODE_NONE;
729 void XMLFilter::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
731 apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
732 if( aMDHelper.ISSET_FilterName )
733 rOutOASIS = aMDHelper.FilterName == "chart8";
735 OUString XMLFilter::getMediaType(bool _bOasis)
737 return _bOasis ? OUString(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII) : OUString(MIMETYPE_VND_SUN_XML_CHART_ASCII);
740 OUString SAL_CALL XMLFilter::getImplementationName()
742 return OUString("com.sun.star.comp.chart2.XMLFilter");
745 sal_Bool SAL_CALL XMLFilter::supportsService( const OUString& rServiceName )
747 return cppu::supportsService(this, rServiceName);
750 css::uno::Sequence< OUString > SAL_CALL XMLFilter::getSupportedServiceNames()
752 return {
753 "com.sun.star.document.ImportFilter",
754 "com.sun.star.document.ExportFilter"
756 // todo: services are incomplete. Missing:
757 // XInitialization, XNamed
760 void XMLReportFilterHelper::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
762 apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
763 if( aMDHelper.ISSET_FilterName )
764 rOutOASIS = aMDHelper.FilterName == "StarOffice XML (Base) Report Chart";
766 OUString XMLReportFilterHelper::getMediaType(bool )
768 return OUString(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII);
771 } // namespace chart
773 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
774 com_sun_star_comp_chart2_XMLFilter_get_implementation(css::uno::XComponentContext *context,
775 css::uno::Sequence<css::uno::Any> const &)
777 return cppu::acquire(new ::chart::XMLFilter(context));
780 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
781 com_sun_star_comp_chart2_report_XMLFilter_get_implementation(css::uno::XComponentContext *context,
782 css::uno::Sequence<css::uno::Any> const &)
784 return cppu::acquire(new ::chart::XMLReportFilterHelper(context));
787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */