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