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