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_sw.hxx"
26
27 #include <com/sun/star/embed/XStorage.hpp>
28 #include <com/sun/star/embed/ElementModes.hpp>
29 #include <com/sun/star/container/XIndexContainer.hpp>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
32 #include <com/sun/star/io/XActiveDataSource.hpp>
33 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
34 #include <com/sun/star/document/XExporter.hpp>
35 #include <com/sun/star/document/XFilter.hpp>
36 #include <com/sun/star/frame/XModule.hpp>
37 #include <comphelper/processfactory.hxx>
38 #include <comphelper/genericpropertyset.hxx>
39 #include <unotools/streamwrap.hxx>
40 #include <svx/xmlgrhlp.hxx>
41 #include <svx/xmleohlp.hxx>
42 #include <unotools/saveopt.hxx>
43 #include <tools/urlobj.hxx>
44 #include <svl/stritem.hxx>
45 #include <sfx2/frame.hxx>
46 #include <sfx2/docfile.hxx>
47 #include <pam.hxx>
48 #include <doc.hxx>
49 #include <docstat.hxx>
50 #include <docsh.hxx>
51
52 #include <unotools/ucbstreamhelper.hxx>
53 #include <errhdl.hxx>
54 #include <swerror.h>
55 #include <wrtxml.hxx>
56 #include <statstr.hrc>
57 #include <rtl/logfile.hxx>
58
59 #include <comphelper/documentconstants.hxx>
60 #include <comphelper/makesequence.hxx>
61 #include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
62
63 using ::rtl::OUString;
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::container;
67 using namespace ::com::sun::star::document;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::lang;
70
71 #define LOGFILE_AUTHOR "mb93740"
72
SwXMLWriter(const String & rBaseURL)73 SwXMLWriter::SwXMLWriter( const String& rBaseURL )
74 {
75 SetBaseURL( rBaseURL );
76 }
77
78
~SwXMLWriter()79 __EXPORT SwXMLWriter::~SwXMLWriter()
80 {
81 }
82
83
_Write(const uno::Reference<task::XStatusIndicator> & xStatusIndicator,const rtl::OUString & aDocHierarchicalName)84 sal_uInt32 SwXMLWriter::_Write( const uno::Reference < task::XStatusIndicator >& xStatusIndicator, const rtl::OUString& aDocHierarchicalName )
85 {
86 // Get service factory
87 uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
88 comphelper::getProcessServiceFactory();
89 ASSERT( xServiceFactory.is(),
90 "SwXMLWriter::Write: got no service manager" );
91 if( !xServiceFactory.is() )
92 return ERR_SWG_WRITE_ERROR;
93
94 // Get data sink ...
95 uno::Reference< io::XOutputStream > xOut;
96 SvStorageStreamRef xDocStream;
97 uno::Reference< document::XGraphicObjectResolver > xGraphicResolver;
98 SvXMLGraphicHelper *pGraphicHelper = 0;
99 uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
100 SvXMLEmbeddedObjectHelper *pObjectHelper = 0;
101
102 ASSERT( xStg.is(), "Where is my storage?" );
103 pGraphicHelper = SvXMLGraphicHelper::Create( xStg,
104 GRAPHICHELPER_MODE_WRITE,
105 sal_False );
106 xGraphicResolver = pGraphicHelper;
107
108 SfxObjectShell *pPersist = pDoc->GetPersist();
109 if( pPersist )
110 {
111 pObjectHelper = SvXMLEmbeddedObjectHelper::Create(
112 xStg, *pPersist,
113 EMBEDDEDOBJECTHELPER_MODE_WRITE,
114 sal_False );
115 xObjectResolver = pObjectHelper;
116 }
117
118 // create and prepare the XPropertySet that gets passed through
119 // the components, and the XStatusIndicator that shows progress to
120 // the user.
121
122 // create XPropertySet with three properties for status indicator
123 comphelper::PropertyMapEntry aInfoMap[] =
124 {
125 { "ProgressRange", sizeof("ProgressRange")-1, 0,
126 &::getCppuType((sal_Int32*)0),
127 beans::PropertyAttribute::MAYBEVOID, 0},
128 { "ProgressMax", sizeof("ProgressMax")-1, 0,
129 &::getCppuType((sal_Int32*)0),
130 beans::PropertyAttribute::MAYBEVOID, 0},
131 { "ProgressCurrent", sizeof("ProgressCurrent")-1, 0,
132 &::getCppuType((sal_Int32*)0),
133 beans::PropertyAttribute::MAYBEVOID, 0},
134 { "WrittenNumberStyles", sizeof("WrittenNumberStyles")-1, 0,
135 &::getCppuType((uno::Sequence<sal_Int32> *)0),
136 beans::PropertyAttribute::MAYBEVOID, 0},
137 { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
138 &::getBooleanCppuType(),
139 beans::PropertyAttribute::MAYBEVOID, 0},
140 { "ShowChanges", sizeof("ShowChanges")-1, 0,
141 &::getBooleanCppuType(),
142 beans::PropertyAttribute::MAYBEVOID, 0 },
143 { "RedlineProtectionKey", sizeof("RedlineProtectionKey")-1, 0,
144 #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
145 new uno::Type(::getCppuType((Sequence<sal_Int8>*)0)),
146 #else
147 &::getCppuType((Sequence<sal_Int8>*)0),
148 #endif
149 beans::PropertyAttribute::MAYBEVOID, 0 },
150 { "BaseURI", sizeof("BaseURI")-1, 0,
151 &::getCppuType( (OUString *)0 ),
152 beans::PropertyAttribute::MAYBEVOID, 0 },
153 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
154 &::getCppuType( (OUString *)0 ),
155 beans::PropertyAttribute::MAYBEVOID, 0 },
156 { "StreamName", sizeof("StreamName")-1, 0,
157 &::getCppuType( (OUString *)0 ),
158 beans::PropertyAttribute::MAYBEVOID, 0 },
159 { "AutoTextMode", sizeof("AutoTextMode")-1, 0,
160 &::getBooleanCppuType(),
161 beans::PropertyAttribute::MAYBEVOID, 0 },
162 { "StyleNames", sizeof("StyleNames")-1, 0,
163 &::getCppuType( (Sequence<OUString>*)0 ),
164 beans::PropertyAttribute::MAYBEVOID, 0 },
165 { "StyleFamilies", sizeof("StyleFamilies")-1, 0,
166 &::getCppuType( (Sequence<sal_Int32>*)0 ),
167 beans::PropertyAttribute::MAYBEVOID, 0 },
168 // --> OD 2006-09-26 #i69627#
169 { "OutlineStyleAsNormalListStyle", sizeof("OutlineStyleAsNormalListStyle")-1, 0,
170 &::getBooleanCppuType(),
171 beans::PropertyAttribute::MAYBEVOID, 0 },
172 // <--
173 { "TargetStorage", sizeof("TargetStorage")-1,0, &embed::XStorage::static_type(),
174 ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
175
176 { NULL, 0, 0, NULL, 0, 0 }
177 };
178 uno::Reference< beans::XPropertySet > xInfoSet(
179 comphelper::GenericPropertySet_CreateInstance(
180 new comphelper::PropertySetInfo( aInfoMap ) ) );
181
182 const OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") );
183 xInfoSet->setPropertyValue( sTargetStorage, Any( xStg ) );
184
185 // create XStatusIndicator
186 // uno::Reference<task::XStatusIndicator> xStatusIndicator;
187
188 uno::Any aAny;
189 if (bShowProgress)
190 {
191 // set progress range and start status indicator
192 sal_Int32 nProgressRange(1000000);
193 if (xStatusIndicator.is())
194 {
195 xStatusIndicator->start(SW_RESSTR( STR_STATSTR_SWGWRITE),
196 nProgressRange);
197 }
198 aAny <<= nProgressRange;
199 OUString sProgressRange(RTL_CONSTASCII_USTRINGPARAM("ProgressRange"));
200 xInfoSet->setPropertyValue(sProgressRange, aAny);
201
202 aAny <<= static_cast < sal_Int32 >( -1 );
203 OUString sProgressMax(RTL_CONSTASCII_USTRINGPARAM("ProgressMax"));
204 xInfoSet->setPropertyValue(sProgressMax, aAny);
205 }
206
207 SvtSaveOptions aSaveOpt;
208 OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
209 sal_Bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
210 aAny.setValue( &bUsePrettyPrinting, ::getBooleanCppuType() );
211 xInfoSet->setPropertyValue( sUsePrettyPrinting, aAny );
212
213 // save show redline mode ...
214 OUString sShowChanges(RTL_CONSTASCII_USTRINGPARAM("ShowChanges"));
215 sal_uInt16 nRedlineMode = pDoc->GetRedlineMode();
216 sal_Bool bShowChanges( IDocumentRedlineAccess::IsShowChanges( nRedlineMode ) );
217 aAny.setValue( &bShowChanges, ::getBooleanCppuType() );
218 xInfoSet->setPropertyValue( sShowChanges, aAny );
219 // ... and hide redlines for export
220 nRedlineMode &= ~nsRedlineMode_t::REDLINE_SHOW_MASK;
221 nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_INSERT;
222 pDoc->SetRedlineMode((RedlineMode_t)( nRedlineMode ));
223
224 // Set base URI
225 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
226 xInfoSet->setPropertyValue( sPropName, makeAny( ::rtl::OUString( GetBaseURL() ) ) );
227
228 if( SFX_CREATE_MODE_EMBEDDED == pDoc->GetDocShell()->GetCreateMode() )
229 {
230 OUString aName;
231 if ( aDocHierarchicalName.getLength() )
232 aName = aDocHierarchicalName;
233 else
234 aName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "dummyObjectName" ) );
235
236 sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
237 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
238 }
239
240 if( bBlock )
241 {
242 OUString sAutoTextMode(
243 RTL_CONSTASCII_USTRINGPARAM("AutoTextMode"));
244 sal_Bool bTmp = sal_True;
245 Any aAny2;
246 aAny2.setValue( &bTmp, ::getBooleanCppuType() );
247 xInfoSet->setPropertyValue( sAutoTextMode, aAny2 );
248 }
249
250 // --> OD 2006-09-26 #i69627#
251 const sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
252 if ( bOASIS &&
253 docfunc::HasOutlineStyleToBeWrittenAsNormalListStyle( *pDoc ) )
254 {
255 OUString sOutlineStyleAsNormalListStyle(
256 RTL_CONSTASCII_USTRINGPARAM("OutlineStyleAsNormalListStyle") );
257 xInfoSet->setPropertyValue( sOutlineStyleAsNormalListStyle, makeAny( sal_True ) );
258 }
259 // <--
260
261 // filter arguments
262 // - graphics + object resolver for styles + content
263 // - status indicator
264 // - info property set
265 // - else empty
266 sal_Int32 nArgs = 1;
267 if( xStatusIndicator.is() )
268 nArgs++;
269
270 Sequence < Any > aEmptyArgs( nArgs );
271 Any *pArgs = aEmptyArgs.getArray();
272 *pArgs++ <<= xInfoSet;
273 if( xStatusIndicator.is() )
274 *pArgs++ <<= xStatusIndicator;
275
276 if( xGraphicResolver.is() )
277 nArgs++;
278 if( xObjectResolver.is() )
279 nArgs++;
280
281 Sequence < Any > aFilterArgs( nArgs );
282 pArgs = aFilterArgs.getArray();
283 *pArgs++ <<= xInfoSet;
284 if( xGraphicResolver.is() )
285 *pArgs++ <<= xGraphicResolver;
286 if( xObjectResolver.is() )
287 *pArgs++ <<= xObjectResolver;
288 if( xStatusIndicator.is() )
289 *pArgs++ <<= xStatusIndicator;
290
291 //Get model
292 uno::Reference< lang::XComponent > xModelComp(
293 pDoc->GetDocShell()->GetModel(), UNO_QUERY );
294 ASSERT( xModelComp.is(), "XMLWriter::Write: got no model" );
295 if( !xModelComp.is() )
296 return ERR_SWG_WRITE_ERROR;
297
298 PutNumFmtFontsInAttrPool();
299 PutEditEngFontsInAttrPool();
300
301 // properties
302 Sequence < PropertyValue > aProps( pOrigFileName ? 1 : 0 );
303 if( pOrigFileName )
304 {
305 PropertyValue *pProps = aProps.getArray();
306 pProps->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FileName") );
307 (pProps++)->Value <<= OUString( *pOrigFileName );
308 }
309
310 // export sub streams for package, else full stream into a file
311 sal_Bool bWarn = sal_False, bErr = sal_False;
312 String sWarnFile, sErrFile;
313
314 // RDF metadata: export if ODF >= 1.2
315 // N.B.: embedded documents have their own manifest.rdf!
316 if ( bOASIS )
317 {
318 const uno::Reference<beans::XPropertySet> xPropSet(xStg,
319 uno::UNO_QUERY_THROW);
320 const ::rtl::OUString VersionProp(
321 ::rtl::OUString::createFromAscii("Version"));
322 try
323 {
324 ::rtl::OUString Version;
325 // ODF >= 1.2
326 if ((xPropSet->getPropertyValue(VersionProp) >>= Version)
327 && !Version.equals(ODFVER_010_TEXT)
328 && !Version.equals(ODFVER_011_TEXT))
329 {
330 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(
331 xModelComp, uno::UNO_QUERY_THROW);
332 xDMA->storeMetadataToStorage(xStg);
333 }
334 }
335 catch (beans::UnknownPropertyException &)
336 { /* ignore */ }
337 catch (uno::Exception &)
338 {
339 bWarn = sal_True;
340 }
341 }
342
343 sal_Bool bStoreMeta = ( SFX_CREATE_MODE_EMBEDDED != pDoc->GetDocShell()->GetCreateMode() );
344 if ( !bStoreMeta )
345 {
346 try
347 {
348 Reference< frame::XModule > xModule( xModelComp, UNO_QUERY );
349 if ( xModule.is() )
350 {
351 ::rtl::OUString aModuleID = xModule->getIdentifier();
352 bStoreMeta = ( aModuleID.getLength()
353 && ( aModuleID.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FormDesign" ) ) )
354 || aModuleID.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TextReportDesign" ) ) ) ) );
355 }
356 }
357 catch( uno::Exception& )
358 {}
359 }
360
361 if( !bOrganizerMode && !bBlock && bStoreMeta )
362 {
363 if( !WriteThroughComponent(
364 xModelComp, "meta.xml", xServiceFactory,
365 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisMetaExporter"
366 : "com.sun.star.comp.Writer.XMLMetaExporter"),
367 aEmptyArgs, aProps, sal_True ) )
368 {
369 bWarn = sal_True;
370 sWarnFile = String( RTL_CONSTASCII_STRINGPARAM("meta.xml"),
371 RTL_TEXTENCODING_ASCII_US );
372 }
373 }
374
375 if( !bErr )
376 {
377 if( !bBlock )
378 {
379 if( !WriteThroughComponent(
380 xModelComp, "settings.xml", xServiceFactory,
381 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisSettingsExporter"
382 : "com.sun.star.comp.Writer.XMLSettingsExporter"),
383 aEmptyArgs, aProps, sal_False ) )
384 {
385 if( !bWarn )
386 {
387 bWarn = sal_True;
388 sWarnFile = String( RTL_CONSTASCII_STRINGPARAM("settings.xml"),
389 RTL_TEXTENCODING_ASCII_US );
390 }
391 }
392 }
393 }
394
395 if( !WriteThroughComponent(
396 xModelComp, "styles.xml", xServiceFactory,
397 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisStylesExporter"
398 : "com.sun.star.comp.Writer.XMLStylesExporter"),
399 aFilterArgs, aProps, sal_False ) )
400 {
401 bErr = sal_True;
402 sErrFile = String( RTL_CONSTASCII_STRINGPARAM("styles.xml"),
403 RTL_TEXTENCODING_ASCII_US );
404 }
405
406
407 if( !bOrganizerMode && !bErr )
408 {
409 if( !WriteThroughComponent(
410 xModelComp, "content.xml", xServiceFactory,
411 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisContentExporter"
412 : "com.sun.star.comp.Writer.XMLContentExporter"),
413 aFilterArgs, aProps, sal_False ) )
414 {
415 bErr = sal_True;
416 sErrFile = String( RTL_CONSTASCII_STRINGPARAM("content.xml"),
417 RTL_TEXTENCODING_ASCII_US );
418 }
419 }
420
421 if( pDoc->GetCurrentViewShell() && pDoc->GetDocStat().nPage > 1 && //swmod 071108//swmod 071225
422 !(bOrganizerMode || bBlock || bErr) )
423 {
424 // DBG_ASSERT( !pDoc->GetDocStat().bModified,
425 // "doc stat is modified!" );
426 OUString sStreamName( RTL_CONSTASCII_USTRINGPARAM("layout-cache") );
427 try
428 {
429 uno::Reference < io::XStream > xStm = xStg->openStreamElement( sStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
430 SvStream* pStream = utl::UcbStreamHelper::CreateStream( xStm );
431 if( !pStream->GetError() )
432 {
433 uno::Reference < beans::XPropertySet > xSet( xStm, UNO_QUERY );
434 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
435 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("application/binary") );
436 uno::Any aAny2;
437 aAny2 <<= aMime;
438 xSet->setPropertyValue( aPropName, aAny2 );
439 pDoc->WriteLayoutCache( *pStream );
440 }
441
442 delete pStream;
443 }
444 catch ( uno::Exception& )
445 {
446 }
447 }
448
449 if( pGraphicHelper )
450 SvXMLGraphicHelper::Destroy( pGraphicHelper );
451 xGraphicResolver = 0;
452
453 if( pObjectHelper )
454 SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
455 xObjectResolver = 0;
456
457 // restore redline mode
458 aAny = xInfoSet->getPropertyValue( sShowChanges );
459 nRedlineMode = pDoc->GetRedlineMode();
460 nRedlineMode &= ~nsRedlineMode_t::REDLINE_SHOW_MASK;
461 nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_INSERT;
462 if ( *(sal_Bool*)aAny.getValue() )
463 nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_DELETE;
464 pDoc->SetRedlineMode((RedlineMode_t)( nRedlineMode ));
465
466 if (xStatusIndicator.is())
467 {
468 xStatusIndicator->end();
469 }
470
471 if( bErr )
472 {
473 if( sErrFile.Len() )
474 return *new StringErrorInfo( ERR_WRITE_ERROR_FILE, sErrFile,
475 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
476 else
477 return ERR_SWG_WRITE_ERROR;
478 }
479 else if( bWarn )
480 {
481 if( sWarnFile.Len() )
482 return *new StringErrorInfo( WARN_WRITE_ERROR_FILE, sWarnFile,
483 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
484 else
485 return WARN_SWG_FEATURES_LOST;
486 }
487
488 return 0;
489 }
490
WriteStorage()491 sal_uLong SwXMLWriter::WriteStorage()
492 {
493 return _Write( uno::Reference < task::XStatusIndicator >(), ::rtl::OUString() );
494 }
495
WriteMedium(SfxMedium & aTargetMedium)496 sal_uLong SwXMLWriter::WriteMedium( SfxMedium& aTargetMedium )
497 {
498 uno::Reference < task::XStatusIndicator > xStatusIndicator;
499 rtl::OUString aName;
500 const SfxUnoAnyItem* pStatusBarItem = static_cast<const SfxUnoAnyItem*>(
501 aTargetMedium.GetItemSet()->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
502 if ( pStatusBarItem )
503 pStatusBarItem->GetValue() >>= xStatusIndicator;
504 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
505 aTargetMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
506 if ( pDocHierarchItem )
507 aName = pDocHierarchItem->GetValue();
508
509 return _Write( xStatusIndicator, aName );
510 }
511
Write(SwPaM & rPaM,SfxMedium & rMed,const String * pFileName)512 sal_uLong SwXMLWriter::Write( SwPaM& rPaM, SfxMedium& rMed,
513 const String* pFileName )
514 {
515 return IsStgWriter()
516 ? ((StgWriter *)this)->Write( rPaM, rMed.GetOutputStorage(), pFileName, &rMed )
517 : ((Writer *)this)->Write( rPaM, *rMed.GetOutStream(), pFileName );
518 }
519
WriteThroughComponent(const uno::Reference<XComponent> & xComponent,const sal_Char * pStreamName,const uno::Reference<lang::XMultiServiceFactory> & rFactory,const sal_Char * pServiceName,const Sequence<Any> & rArguments,const Sequence<beans::PropertyValue> & rMediaDesc,sal_Bool bPlainStream)520 sal_Bool SwXMLWriter::WriteThroughComponent(
521 const uno::Reference<XComponent> & xComponent,
522 const sal_Char* pStreamName,
523 const uno::Reference<lang::XMultiServiceFactory> & rFactory,
524 const sal_Char* pServiceName,
525 const Sequence<Any> & rArguments,
526 const Sequence<beans::PropertyValue> & rMediaDesc,
527 sal_Bool bPlainStream )
528 {
529 DBG_ASSERT( xStg.is(), "Need storage!" );
530 DBG_ASSERT( NULL != pStreamName, "Need stream name!" );
531 DBG_ASSERT( NULL != pServiceName, "Need service name!" );
532
533 RTL_LOGFILE_TRACE_AUTHOR1( "sw", LOGFILE_AUTHOR,
534 "SwXMLWriter::WriteThroughComponent : stream %s",
535 pStreamName );
536
537 // open stream
538 sal_Bool bRet = sal_False;
539 try
540 {
541 OUString sStreamName = OUString::createFromAscii( pStreamName );
542 uno::Reference<io::XStream> xStream =
543 xStg->openStreamElement( sStreamName,
544 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
545
546 uno::Reference <beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
547 if( !xSet.is() )
548 return sal_False;
549
550 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
551 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
552 uno::Any aAny;
553 aAny <<= aMime;
554 xSet->setPropertyValue( aPropName, aAny );
555
556 OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
557 if( bPlainStream )
558 {
559 OUString aCompressPropName( RTL_CONSTASCII_USTRINGPARAM("Compressed") );
560 sal_Bool bFalse = sal_False;
561 aAny.setValue( &bFalse, ::getBooleanCppuType() );
562 xSet->setPropertyValue( aCompressPropName, aAny );
563 }
564
565 // even plain stream should be encrypted in encrypted documents
566 sal_Bool bTrue = sal_True;
567 aAny.setValue( &bTrue, ::getBooleanCppuType() );
568 xSet->setPropertyValue( aUseCommonPassPropName, aAny );
569
570 // set buffer and create outputstream
571 uno::Reference< io::XOutputStream > xOutputStream = xStream->getOutputStream();
572
573 // set Base URL
574 uno::Reference< beans::XPropertySet > xInfoSet;
575 if( rArguments.getLength() > 0 )
576 rArguments.getConstArray()[0] >>= xInfoSet;
577 DBG_ASSERT( xInfoSet.is(), "missing property set" );
578 if( xInfoSet.is() )
579 {
580 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
581 xInfoSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
582 }
583
584 // write the stuff
585 bRet = WriteThroughComponent(
586 xOutputStream, xComponent, rFactory,
587 pServiceName, rArguments, rMediaDesc );
588 }
589 catch ( uno::Exception& )
590 {
591 }
592
593 return bRet;
594
595 }
596
WriteThroughComponent(const uno::Reference<io::XOutputStream> & xOutputStream,const uno::Reference<XComponent> & xComponent,const uno::Reference<XMultiServiceFactory> & rFactory,const sal_Char * pServiceName,const Sequence<Any> & rArguments,const Sequence<PropertyValue> & rMediaDesc)597 sal_Bool SwXMLWriter::WriteThroughComponent(
598 const uno::Reference<io::XOutputStream> & xOutputStream,
599 const uno::Reference<XComponent> & xComponent,
600 const uno::Reference<XMultiServiceFactory> & rFactory,
601 const sal_Char* pServiceName,
602 const Sequence<Any> & rArguments,
603 const Sequence<PropertyValue> & rMediaDesc )
604 {
605 ASSERT( xOutputStream.is(), "I really need an output stream!" );
606 ASSERT( xComponent.is(), "Need component!" );
607 ASSERT( NULL != pServiceName, "Need component name!" );
608
609 RTL_LOGFILE_CONTEXT_AUTHOR( aFilterLog, "sw", LOGFILE_AUTHOR,
610 "SwXMLWriter::WriteThroughComponent" );
611
612 // get component
613 uno::Reference< io::XActiveDataSource > xSaxWriter(
614 rFactory->createInstance(
615 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
616 "com.sun.star.xml.sax.Writer")) ),
617 UNO_QUERY );
618 ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
619 if(!xSaxWriter.is())
620 return sal_False;
621
622 RTL_LOGFILE_CONTEXT_TRACE( aFilterLog, "SAX-Writer created" );
623
624 // connect XML writer to output stream
625 xSaxWriter->setOutputStream( xOutputStream );
626
627 // prepare arguments (prepend doc handler to given arguments)
628 uno::Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
629 Sequence<Any> aArgs( 1 + rArguments.getLength() );
630 aArgs[0] <<= xDocHandler;
631 for(sal_Int32 i = 0; i < rArguments.getLength(); i++)
632 aArgs[i+1] = rArguments[i];
633
634 // get filter component
635 uno::Reference< document::XExporter > xExporter(
636 rFactory->createInstanceWithArguments(
637 OUString::createFromAscii(pServiceName), aArgs), UNO_QUERY);
638 ASSERT( xExporter.is(),
639 "can't instantiate export filter component" );
640 if( !xExporter.is() )
641 return sal_False;
642 RTL_LOGFILE_CONTEXT_TRACE1( aFilterLog, "%s instantiated.", pServiceName );
643
644 // connect model and filter
645 xExporter->setSourceDocument( xComponent );
646
647 // filter!
648 RTL_LOGFILE_CONTEXT_TRACE( aFilterLog, "call filter()" );
649 uno::Reference<XFilter> xFilter( xExporter, UNO_QUERY );
650 return xFilter->filter( rMediaDesc );
651 }
652
653
654 // -----------------------------------------------------------------------
655
GetXMLWriter(const String &,const String & rBaseURL,WriterRef & xRet)656 void GetXMLWriter( const String& /*rName*/, const String& rBaseURL, WriterRef& xRet )
657 {
658 xRet = new SwXMLWriter( rBaseURL );
659 }
660
661 // -----------------------------------------------------------------------
662