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