merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / model / filter / XMLFilter.cxx
blob1b615f6cc1479c6bdb6c05e4df2c52e12db0240d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLFilter.cxx,v $
10 * $Revision: 1.5.44.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "XMLFilter.hxx"
35 #include "macros.hxx"
36 #include "MediaDescriptorHelper.hxx"
37 #include "ContainerHelper.hxx"
38 #include <comphelper/mediadescriptor.hxx>
40 // for ERRCODE_SFX_GENERAL etc.
41 // header contains only macros
42 #include <svtools/sfxecode.hxx>
43 // header for class SvtSaveOptions
44 #include <svtools/saveopt.hxx>
45 #include <comphelper/genericpropertyset.hxx>
46 // header for struct PropertyMapEntry
47 #include <comphelper/propertysetinfo.hxx>
48 #include <comphelper/documentconstants.hxx>
50 // header for class SotStorage
51 #include <sot/storage.hxx>
52 #include <com/sun/star/beans/PropertyAttribute.hpp>
53 #include <com/sun/star/xml/sax/InputSource.hpp>
54 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
55 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
56 #include <com/sun/star/embed/ElementModes.hpp>
57 #include <com/sun/star/embed/XStorage.hpp>
58 #include <com/sun/star/embed/XTransactedObject.hpp>
59 #include <com/sun/star/frame/XModel.hpp>
60 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
61 #include <com/sun/star/xml/sax/XParser.hpp>
62 #include <com/sun/star/xml/sax/SAXParseException.hpp>
63 #include <com/sun/star/packages/zip/ZipIOException.hpp>
64 #include <com/sun/star/document/XGraphicObjectResolver.hpp>
65 #include <com/sun/star/container/XNameAccess.hpp>
67 using namespace ::com::sun::star;
69 using ::com::sun::star::uno::Reference;
70 using ::com::sun::star::uno::Sequence;
71 using ::rtl::OUString;
72 using ::osl::MutexGuard;
74 // ----------------------------------------
75 namespace
77 #define LOCAL_CONST_STR(i, x) sal_Char __READONLY_DATA i[sizeof(x)] = x
78 #define MAP_LEN(x) x, sizeof(x) - 1
80 LOCAL_CONST_STR( sXML_metaStreamName, "meta.xml");
81 LOCAL_CONST_STR( sXML_styleStreamName, "styles.xml" );
82 LOCAL_CONST_STR( sXML_contentStreamName, "content.xml" );
83 LOCAL_CONST_STR( sXML_oldContentStreamName, "Content.xml" );
85 // soffice 6/7
86 // LOCAL_CONST_STR( sXML_export_chart_meta_service, "com.sun.star.comp.Chart.XMLMetaExporter" );
87 LOCAL_CONST_STR( sXML_export_chart_styles_service, "com.sun.star.comp.Chart.XMLStylesExporter" );
88 LOCAL_CONST_STR( sXML_export_chart_content_service, "com.sun.star.comp.Chart.XMLContentExporter" );
90 // LOCAL_CONST_STR( sXML_import_chart_meta_service, "com.sun.star.comp.Chart.XMLMetaImporter" );
91 LOCAL_CONST_STR( sXML_import_chart_styles_service, "com.sun.star.comp.Chart.XMLStylesImporter" );
92 LOCAL_CONST_STR( sXML_import_chart_content_service, "com.sun.star.comp.Chart.XMLContentImporter" );
93 LOCAL_CONST_STR( sXML_import_chart_old_content_service, "com.sun.star.office.sax.importer.Chart" );
95 // Oasis
96 LOCAL_CONST_STR( sXML_export_chart_oasis_styles_service, "com.sun.star.comp.Chart.XMLOasisStylesExporter" );
97 LOCAL_CONST_STR( sXML_export_chart_oasis_content_service, "com.sun.star.comp.Chart.XMLOasisContentExporter" );
98 LOCAL_CONST_STR( sXML_export_chart_oasis_meta_service, "com.sun.star.comp.Chart.XMLOasisMetaExporter" );
100 LOCAL_CONST_STR( sXML_import_chart_oasis_styles_service, "com.sun.star.comp.Chart.XMLOasisStylesImporter" );
101 LOCAL_CONST_STR( sXML_import_chart_oasis_content_service, "com.sun.star.comp.Chart.XMLOasisContentImporter" );
102 LOCAL_CONST_STR( sXML_import_chart_oasis_meta_service, "com.sun.star.comp.Chart.XMLOasisMetaImporter" );
104 uno::Reference< embed::XStorage > lcl_getWriteStorage(
105 const Sequence< beans::PropertyValue >& rMediaDescriptor,
106 const uno::Reference< uno::XComponentContext >& xContext,const ::rtl::OUString& _sMediaType)
108 uno::Reference< embed::XStorage > xStorage;
111 apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
112 if( aMDHelper.ISSET_Storage )
114 xStorage = aMDHelper.Storage;
116 else
118 Reference< lang::XSingleServiceFactory > xStorageFact(
119 xContext->getServiceManager()->createInstanceWithContext(
120 C2U("com.sun.star.embed.StorageFactory"),
121 xContext ), uno::UNO_QUERY_THROW );
123 ::std::vector< beans::PropertyValue > aPropertiesForStorage;
125 for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
127 // properties understood by storage factory
128 // (see package/source/xstor/xfactory.cxx for details)
129 if ( rMediaDescriptor[i].Name.equalsAsciiL(
130 RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ))
131 || rMediaDescriptor[i].Name.equalsAsciiL(
132 RTL_CONSTASCII_STRINGPARAM( "Password" ))
133 || rMediaDescriptor[i].Name.equalsAsciiL(
134 RTL_CONSTASCII_STRINGPARAM( "RepairPackage" ))
135 // || rMediaDescriptor[i].Name.equalsAsciiL(
136 // RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ))
137 // || rMediaDescriptor[i].Name.equalsAsciiL(
138 // RTL_CONSTASCII_STRINGPARAM( "Unpacked" ))
141 aPropertiesForStorage.push_back( rMediaDescriptor[i] );
145 if( aMDHelper.ISSET_Storage )
146 xStorage.set( aMDHelper.Storage );
147 else
149 Sequence< uno::Any > aStorageArgs( 3 );
150 if( aMDHelper.ISSET_OutputStream )
151 aStorageArgs[0] <<= aMDHelper.OutputStream;
152 else
153 aStorageArgs[0] <<= aMDHelper.URL;
154 aStorageArgs[1] <<= (embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE);
155 aStorageArgs[2] <<= ::chart::ContainerHelper::ContainerToSequence( aPropertiesForStorage );
157 xStorage.set(
158 xStorageFact->createInstanceWithArguments( aStorageArgs ),
159 uno::UNO_QUERY_THROW );
163 // set correct media type at storage
164 uno::Reference<beans::XPropertySet> xProp(xStorage,uno::UNO_QUERY);
165 OUString aMediaType;
166 if ( ! xProp.is() ||
167 ! ( xProp->getPropertyValue( C2U("MediaType")) >>= aMediaType ) ||
168 ( aMediaType.getLength() == 0 ))
170 xProp->setPropertyValue( C2U("MediaType"), uno::makeAny( _sMediaType ));
173 catch( uno::Exception & ex )
175 ASSERT_EXCEPTION( ex );
177 return xStorage;
180 uno::Reference< embed::XStorage > lcl_getReadStorage(
181 const Sequence< beans::PropertyValue >& rMediaDescriptor,
182 const uno::Reference< uno::XComponentContext >& xContext)
184 uno::Reference< embed::XStorage > xStorage;
188 apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
189 if( aMDHelper.ISSET_Storage )
191 xStorage = aMDHelper.Storage;
193 else
195 // get XStream from MediaDescriptor
196 uno::Reference< io::XInputStream > xStream;
197 ::std::vector< beans::PropertyValue > aPropertiesForStorage;
198 for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
200 if( rMediaDescriptor[i].Name.equalsAsciiL(
201 RTL_CONSTASCII_STRINGPARAM( "InputStream" )))
202 xStream.set( rMediaDescriptor[i].Value, uno::UNO_QUERY );
204 // properties understood by storage factory
205 // (see package/source/xstor/xfactory.cxx for details)
206 if ( rMediaDescriptor[i].Name.equalsAsciiL(
207 RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ))
208 || rMediaDescriptor[i].Name.equalsAsciiL(
209 RTL_CONSTASCII_STRINGPARAM( "Password" ))
210 || rMediaDescriptor[i].Name.equalsAsciiL(
211 RTL_CONSTASCII_STRINGPARAM( "RepairPackage" ))
212 // || rMediaDescriptor[i].Name.equalsAsciiL(
213 // RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ))
214 // || rMediaDescriptor[i].Name.equalsAsciiL(
215 // RTL_CONSTASCII_STRINGPARAM( "Unpacked" ))
218 aPropertiesForStorage.push_back( rMediaDescriptor[i] );
221 OSL_ENSURE( xStream.is(), "No Stream" );
222 if( ! xStream.is())
223 return xStorage;
225 // convert XInputStream to XStorage via the storage factory
226 Reference< lang::XSingleServiceFactory > xStorageFact(
227 xContext->getServiceManager()->createInstanceWithContext(
228 C2U("com.sun.star.embed.StorageFactory"),
229 xContext ),
230 uno::UNO_QUERY_THROW );
231 Sequence< uno::Any > aStorageArgs( 3 );
232 aStorageArgs[0] <<= xStream;
233 aStorageArgs[1] <<= (embed::ElementModes::READ | embed::ElementModes::NOCREATE);
234 aStorageArgs[2] <<= ::chart::ContainerHelper::ContainerToSequence( aPropertiesForStorage );
235 xStorage.set(
236 xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
239 OSL_ENSURE( xStorage.is(), "No Storage" );
241 catch( uno::Exception & ex )
243 ASSERT_EXCEPTION( ex );
246 return xStorage;
250 } // anonymous namespace
252 // ----------------------------------------
254 namespace chart
257 XMLFilter::XMLFilter( Reference< uno::XComponentContext > const & xContext ) :
258 m_xContext( xContext ),
259 m_bCancelOperation( false )
262 XMLFilter::~XMLFilter()
265 // ____ XFilter ____
266 sal_Bool SAL_CALL XMLFilter::filter(
267 const Sequence< beans::PropertyValue >& aDescriptor )
268 throw (uno::RuntimeException)
270 bool bResult = false;
272 MutexGuard aGuard( m_aMutex );
274 // ignore cancel flag at start of function
275 // note: is currently ignored during import/export
276 if( m_bCancelOperation )
277 m_bCancelOperation = false;
279 if( m_xSourceDoc.is())
281 OSL_ENSURE( ! m_xTargetDoc.is(), "source doc is set -> target document should not be set" );
282 if( impl_Export( m_xSourceDoc,
283 aDescriptor ) == 0 )
285 m_xSourceDoc = NULL;
286 bResult = true;
289 else if( m_xTargetDoc.is())
291 if( impl_Import( m_xTargetDoc,
292 aDescriptor ) == 0 )
294 m_xTargetDoc = NULL;
295 bResult = true;
298 else
300 OSL_ENSURE( false, "filter() called with no document set" );
303 return bResult;
306 void SAL_CALL XMLFilter::cancel()
307 throw (uno::RuntimeException)
309 // if mutex is locked set "cancel state"
310 // note: is currently ignored in filter-method
311 if( ! m_aMutex.tryToAcquire())
313 m_bCancelOperation = true;
317 // ____ XImporter ____
318 void SAL_CALL XMLFilter::setTargetDocument(
319 const Reference< lang::XComponent >& Document )
320 throw (lang::IllegalArgumentException,
321 uno::RuntimeException)
323 MutexGuard aGuard( m_aMutex );
324 OSL_ENSURE( ! m_xSourceDoc.is(), "Setting target doc while source doc is set" );
326 m_xTargetDoc = Document;
330 // ____ XExporter ____
331 void SAL_CALL XMLFilter::setSourceDocument(
332 const Reference< lang::XComponent >& Document )
333 throw (lang::IllegalArgumentException,
334 uno::RuntimeException)
336 MutexGuard aGuard( m_aMutex );
337 OSL_ENSURE( ! m_xTargetDoc.is(), "Setting source doc while target doc is set" );
339 m_xSourceDoc = Document;
343 sal_Int32 XMLFilter::impl_Import(
344 const Reference< lang::XComponent > & xDocumentComp,
345 const Sequence< beans::PropertyValue > & rMediaDescriptor )
347 sal_Int32 nWarning = 0;
349 OSL_ENSURE( xDocumentComp.is(), "Import: No Model" );
350 OSL_ENSURE( m_xContext.is(), "Import: No ComponentContext" );
352 if( ! (xDocumentComp.is() &&
353 m_xContext.is()))
354 return nWarning;
358 Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
359 if( ! xServInfo->supportsService( C2U( "com.sun.star.chart2.ChartDocument" )))
361 OSL_ENSURE( false, "Import: No ChartDocument" );
362 return ERRCODE_SFX_GENERAL;
365 Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
366 OSL_ENSURE( xFactory.is(), "Import: No Factory" );
367 if( ! xFactory.is())
368 return ERRCODE_SFX_GENERAL;
370 // create a sax parser
371 Reference< xml::sax::XParser > xSaxParser(
372 xFactory->createInstanceWithContext( C2U( "com.sun.star.xml.sax.Parser" ), m_xContext ),
373 uno::UNO_QUERY_THROW );
375 bool bOasis = true;
376 isOasisFormat( rMediaDescriptor, bOasis );
377 Reference< embed::XStorage > xStorage( lcl_getReadStorage( rMediaDescriptor, m_xContext));
378 if( ! xStorage.is())
379 return ERRCODE_SFX_GENERAL;
381 // bool bOasis = (SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60);
383 Reference< document::XGraphicObjectResolver > xGraphicObjectResolver;
384 uno::Reference< lang::XMultiServiceFactory > xServiceFactory( xFactory, uno::UNO_QUERY);
385 if( xServiceFactory.is())
387 uno::Sequence< uno::Any > aArgs(1);
388 aArgs[0] <<= xStorage;
389 xGraphicObjectResolver.set(
390 xServiceFactory->createInstanceWithArguments(
391 C2U("com.sun.star.comp.Svx.GraphicImportHelper"), aArgs ), uno::UNO_QUERY );
394 // create XPropertySet with extra informatio for the filter
395 /** property map for import info set */
396 comphelper::PropertyMapEntry aImportInfoMap[] =
398 // #80365# necessary properties for XML progress bar at load time
399 { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
400 { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
401 { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
402 { MAP_LEN( "PrivateData" ), 0,
403 &::getCppuType( (Reference<XInterface> *)0 ),
404 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
405 { MAP_LEN( "BaseURI" ), 0,
406 &::getCppuType( (OUString *)0 ),
407 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
408 { MAP_LEN( "StreamRelPath" ), 0,
409 &::getCppuType( (OUString *)0 ),
410 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
411 { MAP_LEN( "StreamName" ), 0,
412 &::getCppuType( (OUString *)0 ),
413 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
414 { MAP_LEN( "BuildId" ), 0,
415 &::getCppuType( (OUString *)0 ),
416 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
417 { NULL, 0, 0, NULL, 0, 0 }
419 uno::Reference< beans::XPropertySet > xImportInfo(
420 comphelper::GenericPropertySet_CreateInstance(
421 new comphelper::PropertySetInfo( aImportInfoMap ) ) );
423 // Set base URI and Hierarchical Name
424 OUString aHierarchName, aBaseUri;
425 uno::Reference< frame::XModel > xModel( m_xSourceDoc, uno::UNO_QUERY );
426 if( xModel.is() )
428 uno::Sequence< beans::PropertyValue > aModProps = xModel->getArgs();
429 for( sal_Int32 nInd = 0; nInd < aModProps.getLength(); nInd++ )
431 if( aModProps[nInd].Name.equals( C2U( "HierarchicalDocumentName" ) ) )
433 // Actually this argument only has meaning for embedded documents
434 aModProps[nInd].Value >>= aHierarchName;
436 else if( aModProps[nInd].Name.equals( C2U( "DocumentBaseURL" ) ) )
438 aModProps[nInd].Value >>= aBaseUri;
443 if( aBaseUri.getLength() )
444 xImportInfo->setPropertyValue( C2U("BaseURI"), uno::makeAny( aBaseUri ) );
446 if( aHierarchName.getLength() )
447 xImportInfo->setPropertyValue( C2U("StreamRelPath"), uno::makeAny( aHierarchName ) );
449 // import meta information
450 if( bOasis )
451 nWarning |= impl_ImportStream(
452 C2U( sXML_metaStreamName ),
453 C2U( sXML_import_chart_oasis_meta_service ),
454 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
456 // import styles
457 nWarning |= impl_ImportStream(
458 C2U( sXML_styleStreamName ),
459 bOasis
460 ? C2U( sXML_import_chart_oasis_styles_service )
461 : C2U( sXML_import_chart_styles_service ),
462 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
464 // import content
465 sal_Int32 nContentWarning = impl_ImportStream(
466 C2U( sXML_contentStreamName ),
467 bOasis
468 ? C2U( sXML_import_chart_oasis_content_service )
469 : C2U( sXML_import_chart_content_service ),
470 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
471 nWarning |= nContentWarning;
473 // import of "content.xml" didn't work - try old "Content.xml" stream
474 if( nContentWarning != 0 )
476 nWarning = impl_ImportStream(
477 C2U( sXML_oldContentStreamName ),
478 C2U( sXML_import_chart_old_content_service ),
479 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
482 catch( uno::Exception & ex )
484 ASSERT_EXCEPTION( ex );
486 // something went awry
487 nWarning = ERRCODE_SFX_GENERAL;
490 return nWarning;
493 sal_Int32 XMLFilter::impl_ImportStream(
494 const OUString & rStreamName,
495 const OUString & rServiceName,
496 const Reference< embed::XStorage > & xStorage,
497 const Reference< xml::sax::XParser > & xParser,
498 const Reference< lang::XMultiComponentFactory > & xFactory,
499 const Reference< document::XGraphicObjectResolver > & xGraphicObjectResolver,
500 uno::Reference< beans::XPropertySet >& xImportInfo )
502 sal_Int32 nWarning = ERRCODE_SFX_GENERAL;
504 Reference< container::XNameAccess > xNameAcc( xStorage, uno::UNO_QUERY );
505 if( ! (xNameAcc.is() &&
506 xNameAcc->hasByName( rStreamName )))
507 return 0;
509 if( xImportInfo.is() )
510 xImportInfo->setPropertyValue( C2U("StreamName"), uno::makeAny( rStreamName ) );
512 if( xStorage.is() &&
513 xStorage->isStreamElement( rStreamName ) )
517 xml::sax::InputSource aParserInput;
518 aParserInput.aInputStream.set(
519 xStorage->openStreamElement(
520 rStreamName,
521 embed::ElementModes::READ | embed::ElementModes::NOCREATE ),
522 uno::UNO_QUERY );
524 // todo: encryption
526 if( aParserInput.aInputStream.is())
528 sal_Int32 nArgs = 0;
529 //if( m_xStatusIndicator.is())
530 // nArgs++;
531 if( xGraphicObjectResolver.is())
532 nArgs++;
533 if( xImportInfo.is())
534 nArgs++;
536 uno::Sequence< uno::Any > aFilterCompArgs( nArgs );
538 nArgs = 0;
539 //if( m_xStatusIndicator.is())
540 // aFilterCompArgs[ nArgs++ ] <<= m_xStatusIndicator;
541 if( xGraphicObjectResolver.is())
542 aFilterCompArgs[nArgs++] <<= xGraphicObjectResolver;
543 if( xImportInfo.is())
544 aFilterCompArgs[ nArgs++ ] <<= xImportInfo;
546 Reference< xml::sax::XDocumentHandler > xDocHandler(
547 xFactory->createInstanceWithArgumentsAndContext( rServiceName, aFilterCompArgs, m_xContext ),
548 uno::UNO_QUERY_THROW );
551 Reference< document::XImporter > xImporter( xDocHandler, uno::UNO_QUERY_THROW );
552 xImporter->setTargetDocument( Reference< lang::XComponent >( m_xTargetDoc, uno::UNO_QUERY_THROW ));
554 if ( m_sDocumentHandler.getLength() )
558 uno::Sequence< uno::Any > aArgs(2);
559 beans::NamedValue aValue;
560 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentHandler"));
561 aValue.Value <<= xDocHandler;
562 aArgs[0] <<= aValue;
563 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
564 aValue.Value <<= m_xTargetDoc;
565 aArgs[1] <<= aValue;
567 xDocHandler.set(xFactory->createInstanceWithArgumentsAndContext(m_sDocumentHandler,aArgs,m_xContext), uno::UNO_QUERY );
568 xImporter.set(xDocHandler,uno::UNO_QUERY);
570 catch(uno::Exception&)
572 OSL_ENSURE(0,"Exception caught!");
575 xParser->setDocumentHandler( xDocHandler );
576 xParser->parseStream( aParserInput );
579 // load was successful
580 nWarning = 0;
582 catch( xml::sax::SAXParseException )
584 // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
586 catch( xml::sax::SAXException )
588 // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
590 catch( packages::zip::ZipIOException )
592 nWarning = ERRCODE_IO_BROKENPACKAGE;
594 catch( io::IOException )
597 catch( uno::Exception& aEx )
599 ASSERT_EXCEPTION( aEx );
603 return nWarning;
606 sal_Int32 XMLFilter::impl_Export(
607 const Reference< lang::XComponent > & xDocumentComp,
608 const Sequence< beans::PropertyValue > & rMediaDescriptor )
610 //save
612 sal_Int32 nWarning = 0;
614 OSL_ENSURE( xDocumentComp.is(), "Export: No Model" );
615 OSL_ENSURE( m_xContext.is(), "Export: No ComponentContext" );
617 if( !xDocumentComp.is() || !m_xContext.is() )
618 return nWarning;
622 Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
623 if( ! xServInfo->supportsService( C2U( "com.sun.star.chart2.ChartDocument" )))
625 OSL_ENSURE( false, "Export: No ChartDocument" );
626 return ERRCODE_SFX_GENERAL;
629 Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
630 OSL_ENSURE( xFactory.is(), "Export: No Factory" );
631 if( ! xFactory.is())
632 return ERRCODE_SFX_GENERAL;
633 uno::Reference< lang::XMultiServiceFactory > xServiceFactory( m_xContext->getServiceManager(), uno::UNO_QUERY);
634 if( ! xServiceFactory.is())
635 return ERRCODE_SFX_GENERAL;
637 uno::Reference< io::XActiveDataSource > xSaxWriter( xServiceFactory->createInstance(
638 C2U("com.sun.star.xml.sax.Writer")), uno::UNO_QUERY );
639 if ( !xSaxWriter.is() )
640 return ERRCODE_SFX_GENERAL;
642 bool bOasis = true;
643 isOasisFormat( rMediaDescriptor, bOasis );
645 uno::Reference< embed::XStorage > xStorage( lcl_getWriteStorage( rMediaDescriptor, m_xContext, getMediaType(bOasis) ) );
646 OSL_ENSURE( xStorage.is(), "No Storage" );
647 if( ! xStorage.is())
648 return ERRCODE_SFX_GENERAL;
650 uno::Reference< xml::sax::XDocumentHandler> xDocHandler( xSaxWriter, uno::UNO_QUERY );
652 if ( m_sDocumentHandler.getLength() )
656 uno::Sequence< uno::Any > aArgs(2);
657 beans::NamedValue aValue;
658 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentHandler"));
659 aValue.Value <<= xDocHandler;
660 aArgs[0] <<= aValue;
661 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
662 aValue.Value <<= xDocumentComp;
663 aArgs[1] <<= aValue;
665 xDocHandler.set(xServiceFactory->createInstanceWithArguments(m_sDocumentHandler,aArgs), uno::UNO_QUERY );
666 xSaxWriter.set(xDocHandler,uno::UNO_QUERY);
668 catch(uno::Exception&)
670 OSL_ENSURE(0,"Exception caught!");
674 uno::Sequence< uno::Any > aGraphicResolverArgs(1);
675 aGraphicResolverArgs[0] <<= xStorage;
676 Reference< document::XGraphicObjectResolver > xGraphicObjectResolver(
677 xServiceFactory->createInstanceWithArguments(
678 C2U("com.sun.star.comp.Svx.GraphicExportHelper"), aGraphicResolverArgs ), uno::UNO_QUERY );
680 uno::Reference< beans::XPropertySet > xInfoSet;
682 // property map for export info set
683 comphelper::PropertyMapEntry aExportInfoMap[] =
685 { MAP_LEN("UsePrettyPrinting"), 0, &::getBooleanCppuType(), beans::PropertyAttribute::MAYBEVOID, 0},
686 { MAP_LEN("BaseURI"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
687 { MAP_LEN("StreamRelPath"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
688 { MAP_LEN("StreamName"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
689 { MAP_LEN("ExportTableNumberList"), 0, &::getBooleanCppuType(), beans::PropertyAttribute::MAYBEVOID, 0 },
690 { NULL, 0, 0, NULL, 0, 0 }
693 xInfoSet = comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) );
695 SvtSaveOptions aSaveOpt;
696 OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
697 sal_Bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
698 xInfoSet->setPropertyValue( sUsePrettyPrinting, uno::makeAny( bUsePrettyPrinting ) );
699 if( ! bOasis )
700 xInfoSet->setPropertyValue( C2U("ExportTableNumberList"), uno::makeAny( true ));
703 sal_Int32 nArgs = 2;
704 if( xGraphicObjectResolver.is())
705 nArgs++;
707 uno::Sequence< uno::Any > aFilterProperties( nArgs );
709 nArgs = 0;
710 aFilterProperties[ nArgs++ ] <<= xInfoSet;
711 aFilterProperties[ nArgs++ ] <<= xDocHandler;
712 if( xGraphicObjectResolver.is())
713 aFilterProperties[ nArgs++ ] <<= xGraphicObjectResolver;
716 // bool bOasis = (SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60);
718 // export meta information
719 if( bOasis )
720 nWarning |= impl_ExportStream(
721 C2U( sXML_metaStreamName ),
722 C2U( sXML_export_chart_oasis_meta_service ),
723 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
725 // export styles
726 nWarning |= impl_ExportStream(
727 C2U( sXML_styleStreamName ),
728 bOasis
729 ? C2U( sXML_export_chart_oasis_styles_service )
730 : C2U( sXML_export_chart_styles_service ),
731 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
733 // export content
734 sal_Int32 nContentWarning = impl_ExportStream(
735 C2U( sXML_contentStreamName ),
736 bOasis
737 ? C2U( sXML_export_chart_oasis_content_service )
738 : C2U( sXML_export_chart_content_service ),
739 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
740 nWarning |= nContentWarning;
742 Reference< lang::XComponent > xComp( xGraphicObjectResolver, uno::UNO_QUERY );
743 if( xComp.is())
744 xComp->dispose();
746 uno::Reference<embed::XTransactedObject> xTransact( xStorage ,uno::UNO_QUERY);
747 if ( xTransact.is() )
748 xTransact->commit();
750 catch( uno::Exception & ex )
752 ASSERT_EXCEPTION( ex );
754 // something went awry
755 nWarning = ERRCODE_SFX_GENERAL;
758 return nWarning;
761 sal_Int32 XMLFilter::impl_ExportStream(
762 const OUString & rStreamName,
763 const OUString & rServiceName,
764 const Reference< embed::XStorage > & xStorage,
765 const uno::Reference< io::XActiveDataSource >& xActiveDataSource,
766 const Reference< lang::XMultiServiceFactory >& xServiceFactory,
767 const Sequence< uno::Any > & rFilterProperties )
769 sal_Int32 nWarning = 0;
773 if( !xServiceFactory.is() )
774 return ERRCODE_SFX_GENERAL;
775 if( !xStorage.is() )
776 return ERRCODE_SFX_GENERAL;
777 if ( !xActiveDataSource.is() )
778 return ERRCODE_SFX_GENERAL;
780 uno::Reference< io::XStream > xStream( xStorage->openStreamElement(
781 rStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ) );
782 if ( !xStream.is() )
783 return ERRCODE_SFX_GENERAL;
784 uno::Reference< io::XOutputStream > xOutputStream( xStream->getOutputStream() );
785 if ( !xOutputStream.is() )
786 return ERRCODE_SFX_GENERAL;
788 uno::Reference< beans::XPropertySet > xStreamProp( xOutputStream, uno::UNO_QUERY );
789 if(xStreamProp.is()) try
791 xStreamProp->setPropertyValue( C2U("MediaType"), uno::makeAny( C2U("text/xml") ) );
792 xStreamProp->setPropertyValue( C2U("Compressed"), uno::makeAny( sal_True ) );//@todo?
793 xStreamProp->setPropertyValue( C2U("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
795 catch( uno::Exception& rEx )
797 ASSERT_EXCEPTION( rEx );
800 xActiveDataSource->setOutputStream(xOutputStream);
802 // set Base URL
804 uno::Reference< beans::XPropertySet > xInfoSet;
805 if( rFilterProperties.getLength() > 0 )
806 rFilterProperties.getConstArray()[0] >>= xInfoSet;
807 OSL_ENSURE( xInfoSet.is(), "missing infoset for export" );
808 if( xInfoSet.is() )
809 xInfoSet->setPropertyValue( C2U("StreamName"), uno::makeAny( rStreamName ) );
812 Reference< XExporter > xExporter( xServiceFactory->createInstanceWithArguments(
813 rServiceName, rFilterProperties ), uno::UNO_QUERY);
814 if ( !xExporter.is() )
815 return ERRCODE_SFX_GENERAL;
817 xExporter->setSourceDocument( m_xSourceDoc );
819 uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY );
820 if ( !xFilter.is() )
821 return ERRCODE_SFX_GENERAL;
823 uno::Sequence < beans::PropertyValue > aMediaDesc(0);
824 //@todo? filter properties? ... url? ...
825 xFilter->filter( aMediaDesc );
827 catch( uno::Exception& rEx )
829 ASSERT_EXCEPTION( rEx );
831 return nWarning;
834 // --------------------------------------------------------------------------------
836 Sequence< OUString > XMLFilter::getSupportedServiceNames_Static()
838 Sequence< OUString > aServices( 2 );
839 aServices[ 0 ] = C2U( "com.sun.star.document.ImportFilter" );
840 aServices[ 1 ] = C2U( "com.sun.star.document.ExportFilter" );
842 // todo: services are incomplete. Missing:
843 // XInitialization, XNamed
844 return aServices;
846 // -----------------------------------------------------------------------------
848 void XMLFilter::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
850 apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
851 if( aMDHelper.ISSET_FilterName )
852 rOutOASIS = aMDHelper.FilterName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("chart8"));
854 // -----------------------------------------------------------------------------
855 ::rtl::OUString XMLFilter::getMediaType(bool _bOasis)
857 return _bOasis ? MIMETYPE_OASIS_OPENDOCUMENT_CHART : MIMETYPE_VND_SUN_XML_CHART;
859 // -----------------------------------------------------------------------------
861 APPHELPER_XSERVICEINFO_IMPL( XMLFilter, C2U( "com.sun.star.comp.chart2.XMLFilter" ) );
862 // -----------------------------------------------------------------------------
864 void XMLReportFilterHelper::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
866 apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
867 if( aMDHelper.ISSET_FilterName )
868 rOutOASIS = aMDHelper.FilterName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("StarOffice XML (Base) Report Chart"));
870 // -----------------------------------------------------------------------------
871 ::rtl::OUString XMLReportFilterHelper::getMediaType(bool )
873 return MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART;
876 } // namespace chart