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