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_chartmodel.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 {
262 bool bResult = false;
263
264 MutexGuard aGuard( m_aMutex );
265
266 // ignore cancel flag at start of function
267 // note: is currently ignored during import/export
268 if( m_bCancelOperation )
269 m_bCancelOperation = false;
270
271 if( m_xSourceDoc.is())
272 {
273 OSL_ENSURE( ! m_xTargetDoc.is(), "source doc is set -> target document should not be set" );
274 if( impl_Export( m_xSourceDoc,
275 aDescriptor ) == 0 )
276 {
277 m_xSourceDoc = NULL;
278 bResult = true;
279 }
280 }
281 else if( m_xTargetDoc.is())
282 {
283 if( impl_Import( m_xTargetDoc,
284 aDescriptor ) == 0 )
285 {
286 m_xTargetDoc = NULL;
287 bResult = true;
288 }
289 }
290 else
291 {
292 OSL_ENSURE( false, "filter() called with no document set" );
293 }
294
295 return bResult;
296 }
297
cancel()298 void SAL_CALL XMLFilter::cancel()
299 {
300 // if mutex is locked set "cancel state"
301 // note: is currently ignored in filter-method
302 if( ! m_aMutex.tryToAcquire())
303 {
304 m_bCancelOperation = true;
305 }
306 }
307
308 // ____ XImporter ____
setTargetDocument(const Reference<lang::XComponent> & Document)309 void SAL_CALL XMLFilter::setTargetDocument(
310 const Reference< lang::XComponent >& Document )
311 {
312 MutexGuard aGuard( m_aMutex );
313 OSL_ENSURE( ! m_xSourceDoc.is(), "Setting target doc while source doc is set" );
314
315 m_xTargetDoc = Document;
316 }
317
318
319 // ____ XExporter ____
setSourceDocument(const Reference<lang::XComponent> & Document)320 void SAL_CALL XMLFilter::setSourceDocument(
321 const Reference< lang::XComponent >& Document )
322 {
323 MutexGuard aGuard( m_aMutex );
324 OSL_ENSURE( ! m_xTargetDoc.is(), "Setting source doc while target doc is set" );
325
326 m_xSourceDoc = Document;
327 }
328
329
impl_Import(const Reference<lang::XComponent> & xDocumentComp,const Sequence<beans::PropertyValue> & rMediaDescriptor)330 sal_Int32 XMLFilter::impl_Import(
331 const Reference< lang::XComponent > & xDocumentComp,
332 const Sequence< beans::PropertyValue > & rMediaDescriptor )
333 {
334 sal_Int32 nWarning = 0;
335
336 OSL_ENSURE( xDocumentComp.is(), "Import: No Model" );
337 OSL_ENSURE( m_xContext.is(), "Import: No ComponentContext" );
338
339 if( ! (xDocumentComp.is() &&
340 m_xContext.is()))
341 return nWarning;
342
343 try
344 {
345 Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
346 if( ! xServInfo->supportsService( C2U( "com.sun.star.chart2.ChartDocument" )))
347 {
348 OSL_ENSURE( false, "Import: No ChartDocument" );
349 return ERRCODE_SFX_GENERAL;
350 }
351
352 Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
353 OSL_ENSURE( xFactory.is(), "Import: No Factory" );
354 if( ! xFactory.is())
355 return ERRCODE_SFX_GENERAL;
356
357 // create a sax parser
358 Reference< xml::sax::XParser > xSaxParser(
359 xFactory->createInstanceWithContext( C2U( "com.sun.star.xml.sax.Parser" ), m_xContext ),
360 uno::UNO_QUERY_THROW );
361
362 bool bOasis = true;
363 isOasisFormat( rMediaDescriptor, bOasis );
364 Reference< embed::XStorage > xStorage( lcl_getReadStorage( rMediaDescriptor, m_xContext));
365 if( ! xStorage.is())
366 return ERRCODE_SFX_GENERAL;
367
368 // bool bOasis = (SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60);
369
370 Reference< document::XGraphicObjectResolver > xGraphicObjectResolver;
371 uno::Reference< lang::XMultiServiceFactory > xServiceFactory( xFactory, uno::UNO_QUERY);
372 if( xServiceFactory.is())
373 {
374 uno::Sequence< uno::Any > aArgs(1);
375 aArgs[0] <<= xStorage;
376 xGraphicObjectResolver.set(
377 xServiceFactory->createInstanceWithArguments(
378 C2U("com.sun.star.comp.Svx.GraphicImportHelper"), aArgs ), uno::UNO_QUERY );
379 }
380
381 // create XPropertySet with extra informatio for the filter
382 /** property map for import info set */
383 comphelper::PropertyMapEntry aImportInfoMap[] =
384 {
385 // #80365# necessary properties for XML progress bar at load time
386 { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
387 { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
388 { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
389 { MAP_LEN( "PrivateData" ), 0,
390 &::getCppuType( (Reference<XInterface> *)0 ),
391 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
392 { MAP_LEN( "BaseURI" ), 0,
393 &::getCppuType( (OUString *)0 ),
394 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
395 { MAP_LEN( "StreamRelPath" ), 0,
396 &::getCppuType( (OUString *)0 ),
397 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
398 { MAP_LEN( "StreamName" ), 0,
399 &::getCppuType( (OUString *)0 ),
400 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
401 { MAP_LEN( "BuildId" ), 0,
402 &::getCppuType( (OUString *)0 ),
403 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
404 { NULL, 0, 0, NULL, 0, 0 }
405 };
406 uno::Reference< beans::XPropertySet > xImportInfo(
407 comphelper::GenericPropertySet_CreateInstance(
408 new comphelper::PropertySetInfo( aImportInfoMap ) ) );
409
410 // Set base URI and Hierarchical Name
411 OUString aHierarchName, aBaseUri;
412 uno::Reference< frame::XModel > xModel( m_xSourceDoc, uno::UNO_QUERY );
413 if( xModel.is() )
414 {
415 uno::Sequence< beans::PropertyValue > aModProps = xModel->getArgs();
416 for( sal_Int32 nInd = 0; nInd < aModProps.getLength(); nInd++ )
417 {
418 if( aModProps[nInd].Name.equals( C2U( "HierarchicalDocumentName" ) ) )
419 {
420 // Actually this argument only has meaning for embedded documents
421 aModProps[nInd].Value >>= aHierarchName;
422 }
423 else if( aModProps[nInd].Name.equals( C2U( "DocumentBaseURL" ) ) )
424 {
425 aModProps[nInd].Value >>= aBaseUri;
426 }
427 }
428 }
429
430 if( !aBaseUri.isEmpty() )
431 xImportInfo->setPropertyValue( C2U("BaseURI"), uno::makeAny( aBaseUri ) );
432
433 if( !aHierarchName.isEmpty() )
434 xImportInfo->setPropertyValue( C2U("StreamRelPath"), uno::makeAny( aHierarchName ) );
435
436 // import meta information
437 if( bOasis )
438 nWarning |= impl_ImportStream(
439 C2U( sXML_metaStreamName ),
440 C2U( sXML_import_chart_oasis_meta_service ),
441 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
442
443 // import styles
444 nWarning |= impl_ImportStream(
445 C2U( sXML_styleStreamName ),
446 bOasis
447 ? C2U( sXML_import_chart_oasis_styles_service )
448 : C2U( sXML_import_chart_styles_service ),
449 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
450
451 // import content
452 sal_Int32 nContentWarning = impl_ImportStream(
453 C2U( sXML_contentStreamName ),
454 bOasis
455 ? C2U( sXML_import_chart_oasis_content_service )
456 : C2U( sXML_import_chart_content_service ),
457 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
458 nWarning |= nContentWarning;
459
460 // import of "content.xml" didn't work - try old "Content.xml" stream
461 if( nContentWarning != 0 )
462 {
463 nWarning = impl_ImportStream(
464 C2U( sXML_oldContentStreamName ),
465 C2U( sXML_import_chart_old_content_service ),
466 xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
467 }
468 }
469 catch( uno::Exception & ex )
470 {
471 ASSERT_EXCEPTION( ex );
472
473 // something went awry
474 nWarning = ERRCODE_SFX_GENERAL;
475 }
476
477 return nWarning;
478 }
479
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)480 sal_Int32 XMLFilter::impl_ImportStream(
481 const OUString & rStreamName,
482 const OUString & rServiceName,
483 const Reference< embed::XStorage > & xStorage,
484 const Reference< xml::sax::XParser > & xParser,
485 const Reference< lang::XMultiComponentFactory > & xFactory,
486 const Reference< document::XGraphicObjectResolver > & xGraphicObjectResolver,
487 uno::Reference< beans::XPropertySet >& xImportInfo )
488 {
489 sal_Int32 nWarning = ERRCODE_SFX_GENERAL;
490
491 Reference< container::XNameAccess > xNameAcc( xStorage, uno::UNO_QUERY );
492 if( ! (xNameAcc.is() &&
493 xNameAcc->hasByName( rStreamName )))
494 return 0;
495
496 if( xImportInfo.is() )
497 xImportInfo->setPropertyValue( C2U("StreamName"), uno::makeAny( rStreamName ) );
498
499 if( xStorage.is() &&
500 xStorage->isStreamElement( rStreamName ) )
501 {
502 try
503 {
504 xml::sax::InputSource aParserInput;
505 aParserInput.aInputStream.set(
506 xStorage->openStreamElement(
507 rStreamName,
508 embed::ElementModes::READ | embed::ElementModes::NOCREATE ),
509 uno::UNO_QUERY );
510
511 // todo: encryption
512
513 if( aParserInput.aInputStream.is())
514 {
515 sal_Int32 nArgs = 0;
516 //if( m_xStatusIndicator.is())
517 // nArgs++;
518 if( xGraphicObjectResolver.is())
519 nArgs++;
520 if( xImportInfo.is())
521 nArgs++;
522
523 uno::Sequence< uno::Any > aFilterCompArgs( nArgs );
524
525 nArgs = 0;
526 //if( m_xStatusIndicator.is())
527 // aFilterCompArgs[ nArgs++ ] <<= m_xStatusIndicator;
528 if( xGraphicObjectResolver.is())
529 aFilterCompArgs[nArgs++] <<= xGraphicObjectResolver;
530 if( xImportInfo.is())
531 aFilterCompArgs[ nArgs++ ] <<= xImportInfo;
532
533 Reference< xml::sax::XDocumentHandler > xDocHandler(
534 xFactory->createInstanceWithArgumentsAndContext( rServiceName, aFilterCompArgs, m_xContext ),
535 uno::UNO_QUERY_THROW );
536
537
538 Reference< document::XImporter > xImporter( xDocHandler, uno::UNO_QUERY_THROW );
539 xImporter->setTargetDocument( Reference< lang::XComponent >( m_xTargetDoc, uno::UNO_QUERY_THROW ));
540
541 if ( !m_sDocumentHandler.isEmpty() )
542 {
543 try
544 {
545 uno::Sequence< uno::Any > aArgs(2);
546 beans::NamedValue aValue;
547 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentHandler"));
548 aValue.Value <<= xDocHandler;
549 aArgs[0] <<= aValue;
550 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
551 aValue.Value <<= m_xTargetDoc;
552 aArgs[1] <<= aValue;
553
554 xDocHandler.set(xFactory->createInstanceWithArgumentsAndContext(m_sDocumentHandler,aArgs,m_xContext), uno::UNO_QUERY );
555 xImporter.set(xDocHandler,uno::UNO_QUERY);
556 }
557 catch(uno::Exception&)
558 {
559 OSL_ENSURE(0,"Exception caught!");
560 }
561 }
562 xParser->setDocumentHandler( xDocHandler );
563 xParser->parseStream( aParserInput );
564 }
565
566 // load was successful
567 nWarning = 0;
568 }
569 catch( xml::sax::SAXParseException )
570 {
571 // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
572 }
573 catch( xml::sax::SAXException )
574 {
575 // todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
576 }
577 catch( packages::zip::ZipIOException )
578 {
579 nWarning = ERRCODE_IO_BROKENPACKAGE;
580 }
581 catch( io::IOException )
582 {
583 }
584 catch( uno::Exception& aEx )
585 {
586 ASSERT_EXCEPTION( aEx );
587 }
588 }
589
590 return nWarning;
591 }
592
impl_Export(const Reference<lang::XComponent> & xDocumentComp,const Sequence<beans::PropertyValue> & rMediaDescriptor)593 sal_Int32 XMLFilter::impl_Export(
594 const Reference< lang::XComponent > & xDocumentComp,
595 const Sequence< beans::PropertyValue > & rMediaDescriptor )
596 {
597 //save
598
599 sal_Int32 nWarning = 0;
600
601 OSL_ENSURE( xDocumentComp.is(), "Export: No Model" );
602 OSL_ENSURE( m_xContext.is(), "Export: No ComponentContext" );
603
604 if( !xDocumentComp.is() || !m_xContext.is() )
605 return nWarning;
606
607 try
608 {
609 Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
610 if( ! xServInfo->supportsService( C2U( "com.sun.star.chart2.ChartDocument" )))
611 {
612 OSL_ENSURE( false, "Export: No ChartDocument" );
613 return ERRCODE_SFX_GENERAL;
614 }
615
616 Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
617 OSL_ENSURE( xFactory.is(), "Export: No Factory" );
618 if( ! xFactory.is())
619 return ERRCODE_SFX_GENERAL;
620 uno::Reference< lang::XMultiServiceFactory > xServiceFactory( m_xContext->getServiceManager(), uno::UNO_QUERY);
621 if( ! xServiceFactory.is())
622 return ERRCODE_SFX_GENERAL;
623
624 uno::Reference< io::XActiveDataSource > xSaxWriter( xServiceFactory->createInstance(
625 C2U("com.sun.star.xml.sax.Writer")), uno::UNO_QUERY );
626 if ( !xSaxWriter.is() )
627 return ERRCODE_SFX_GENERAL;
628
629 bool bOasis = true;
630 isOasisFormat( rMediaDescriptor, bOasis );
631
632 uno::Reference< embed::XStorage > xStorage( lcl_getWriteStorage( rMediaDescriptor, m_xContext, getMediaType(bOasis) ) );
633 OSL_ENSURE( xStorage.is(), "No Storage" );
634 if( ! xStorage.is())
635 return ERRCODE_SFX_GENERAL;
636
637 uno::Reference< xml::sax::XDocumentHandler> xDocHandler( xSaxWriter, uno::UNO_QUERY );
638
639 if ( !m_sDocumentHandler.isEmpty() )
640 {
641 try
642 {
643 uno::Sequence< uno::Any > aArgs(2);
644 beans::NamedValue aValue;
645 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentHandler"));
646 aValue.Value <<= xDocHandler;
647 aArgs[0] <<= aValue;
648 aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
649 aValue.Value <<= xDocumentComp;
650 aArgs[1] <<= aValue;
651
652 xDocHandler.set(xServiceFactory->createInstanceWithArguments(m_sDocumentHandler,aArgs), uno::UNO_QUERY );
653 xSaxWriter.set(xDocHandler,uno::UNO_QUERY);
654 }
655 catch(uno::Exception&)
656 {
657 OSL_ENSURE(0,"Exception caught!");
658 }
659 }
660
661 uno::Sequence< uno::Any > aGraphicResolverArgs(1);
662 aGraphicResolverArgs[0] <<= xStorage;
663 Reference< document::XGraphicObjectResolver > xGraphicObjectResolver(
664 xServiceFactory->createInstanceWithArguments(
665 C2U("com.sun.star.comp.Svx.GraphicExportHelper"), aGraphicResolverArgs ), uno::UNO_QUERY );
666
667 uno::Reference< beans::XPropertySet > xInfoSet;
668 {
669 // property map for export info set
670 comphelper::PropertyMapEntry aExportInfoMap[] =
671 {
672 { MAP_LEN("UsePrettyPrinting"), 0, &::getBooleanCppuType(), beans::PropertyAttribute::MAYBEVOID, 0},
673 { MAP_LEN("BaseURI"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
674 { MAP_LEN("StreamRelPath"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
675 { MAP_LEN("StreamName"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
676 { MAP_LEN("ExportTableNumberList"), 0, &::getBooleanCppuType(), beans::PropertyAttribute::MAYBEVOID, 0 },
677 { NULL, 0, 0, NULL, 0, 0 }
678 };
679
680 xInfoSet = comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) );
681
682 SvtSaveOptions aSaveOpt;
683 OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
684 sal_Bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
685 xInfoSet->setPropertyValue( sUsePrettyPrinting, uno::makeAny( bUsePrettyPrinting ) );
686 if( ! bOasis )
687 xInfoSet->setPropertyValue( C2U("ExportTableNumberList"), uno::makeAny( true ));
688 }
689
690 sal_Int32 nArgs = 2;
691 if( xGraphicObjectResolver.is())
692 nArgs++;
693
694 uno::Sequence< uno::Any > aFilterProperties( nArgs );
695 {
696 nArgs = 0;
697 aFilterProperties[ nArgs++ ] <<= xInfoSet;
698 aFilterProperties[ nArgs++ ] <<= xDocHandler;
699 if( xGraphicObjectResolver.is())
700 aFilterProperties[ nArgs++ ] <<= xGraphicObjectResolver;
701 }
702
703 // bool bOasis = (SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60);
704
705 // export meta information
706 if( bOasis )
707 nWarning |= impl_ExportStream(
708 C2U( sXML_metaStreamName ),
709 C2U( sXML_export_chart_oasis_meta_service ),
710 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
711
712 // export styles
713 nWarning |= impl_ExportStream(
714 C2U( sXML_styleStreamName ),
715 bOasis
716 ? C2U( sXML_export_chart_oasis_styles_service )
717 : C2U( sXML_export_chart_styles_service ),
718 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
719
720 // export content
721 sal_Int32 nContentWarning = impl_ExportStream(
722 C2U( sXML_contentStreamName ),
723 bOasis
724 ? C2U( sXML_export_chart_oasis_content_service )
725 : C2U( sXML_export_chart_content_service ),
726 xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
727 nWarning |= nContentWarning;
728
729 Reference< lang::XComponent > xComp( xGraphicObjectResolver, uno::UNO_QUERY );
730 if( xComp.is())
731 xComp->dispose();
732
733 uno::Reference<embed::XTransactedObject> xTransact( xStorage ,uno::UNO_QUERY);
734 if ( xTransact.is() )
735 xTransact->commit();
736 }
737 catch( uno::Exception & ex )
738 {
739 ASSERT_EXCEPTION( ex );
740
741 // something went awry
742 nWarning = ERRCODE_SFX_GENERAL;
743 }
744
745 return nWarning;
746 }
747
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)748 sal_Int32 XMLFilter::impl_ExportStream(
749 const OUString & rStreamName,
750 const OUString & rServiceName,
751 const Reference< embed::XStorage > & xStorage,
752 const uno::Reference< io::XActiveDataSource >& xActiveDataSource,
753 const Reference< lang::XMultiServiceFactory >& xServiceFactory,
754 const Sequence< uno::Any > & rFilterProperties )
755 {
756 sal_Int32 nWarning = 0;
757
758 try
759 {
760 if( !xServiceFactory.is() )
761 return ERRCODE_SFX_GENERAL;
762 if( !xStorage.is() )
763 return ERRCODE_SFX_GENERAL;
764 if ( !xActiveDataSource.is() )
765 return ERRCODE_SFX_GENERAL;
766
767 uno::Reference< io::XStream > xStream( xStorage->openStreamElement(
768 rStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ) );
769 if ( !xStream.is() )
770 return ERRCODE_SFX_GENERAL;
771 uno::Reference< io::XOutputStream > xOutputStream( xStream->getOutputStream() );
772 if ( !xOutputStream.is() )
773 return ERRCODE_SFX_GENERAL;
774
775 uno::Reference< beans::XPropertySet > xStreamProp( xOutputStream, uno::UNO_QUERY );
776 if(xStreamProp.is()) try
777 {
778 xStreamProp->setPropertyValue( C2U("MediaType"), uno::makeAny( C2U("text/xml") ) );
779 xStreamProp->setPropertyValue( C2U("Compressed"), uno::makeAny( sal_True ) );//@todo?
780 xStreamProp->setPropertyValue( C2U("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
781 }
782 catch( uno::Exception& rEx )
783 {
784 ASSERT_EXCEPTION( rEx );
785 }
786
787 xActiveDataSource->setOutputStream(xOutputStream);
788
789 // set Base URL
790 {
791 uno::Reference< beans::XPropertySet > xInfoSet;
792 if( rFilterProperties.getLength() > 0 )
793 rFilterProperties.getConstArray()[0] >>= xInfoSet;
794 OSL_ENSURE( xInfoSet.is(), "missing infoset for export" );
795 if( xInfoSet.is() )
796 xInfoSet->setPropertyValue( C2U("StreamName"), uno::makeAny( rStreamName ) );
797 }
798
799 Reference< XExporter > xExporter( xServiceFactory->createInstanceWithArguments(
800 rServiceName, rFilterProperties ), uno::UNO_QUERY);
801 if ( !xExporter.is() )
802 return ERRCODE_SFX_GENERAL;
803
804 xExporter->setSourceDocument( m_xSourceDoc );
805
806 uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY );
807 if ( !xFilter.is() )
808 return ERRCODE_SFX_GENERAL;
809
810 uno::Sequence < beans::PropertyValue > aMediaDesc(0);
811 //@todo? filter properties? ... url? ...
812 xFilter->filter( aMediaDesc );
813 }
814 catch( uno::Exception& rEx )
815 {
816 ASSERT_EXCEPTION( rEx );
817 }
818 return nWarning;
819 }
820
821 // --------------------------------------------------------------------------------
822
getSupportedServiceNames_Static()823 Sequence< OUString > XMLFilter::getSupportedServiceNames_Static()
824 {
825 Sequence< OUString > aServices( 2 );
826 aServices[ 0 ] = C2U( "com.sun.star.document.ImportFilter" );
827 aServices[ 1 ] = C2U( "com.sun.star.document.ExportFilter" );
828
829 // todo: services are incomplete. Missing:
830 // XInitialization, XNamed
831 return aServices;
832 }
833 // -----------------------------------------------------------------------------
834
isOasisFormat(const Sequence<beans::PropertyValue> & _rMediaDescriptor,bool & rOutOASIS)835 void XMLFilter::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
836 {
837 apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
838 if( aMDHelper.ISSET_FilterName )
839 rOutOASIS = aMDHelper.FilterName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("chart8"));
840 }
841 // -----------------------------------------------------------------------------
getMediaType(bool _bOasis)842 ::rtl::OUString XMLFilter::getMediaType(bool _bOasis)
843 {
844 return _bOasis ? MIMETYPE_OASIS_OPENDOCUMENT_CHART : MIMETYPE_VND_SUN_XML_CHART;
845 }
846 // -----------------------------------------------------------------------------
847
848 APPHELPER_XSERVICEINFO_IMPL( XMLFilter, C2U( "com.sun.star.comp.chart2.XMLFilter" ) );
849 // -----------------------------------------------------------------------------
850
isOasisFormat(const Sequence<beans::PropertyValue> & _rMediaDescriptor,bool & rOutOASIS)851 void XMLReportFilterHelper::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
852 {
853 apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
854 if( aMDHelper.ISSET_FilterName )
855 rOutOASIS = aMDHelper.FilterName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("StarOffice XML (Base) Report Chart"));
856 }
857 // -----------------------------------------------------------------------------
getMediaType(bool)858 ::rtl::OUString XMLReportFilterHelper::getMediaType(bool )
859 {
860 return MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART;
861 }
862
863 } // namespace chart
864