xref: /AOO41X/main/sw/source/filter/xml/wrtxml.cxx (revision 48a4b4ec7cd598bf6db29cc5523a742c4c2eb450)
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     xInfoSet->setPropertyValue( sUsePrettyPrinting, uno::makeAny(bUsePrettyPrinting));
211 
212     // save show redline mode ...
213     OUString sShowChanges(RTL_CONSTASCII_USTRINGPARAM("ShowChanges"));
214     sal_uInt16 nRedlineMode = pDoc->GetRedlineMode();
215     sal_Bool bShowChanges( IDocumentRedlineAccess::IsShowChanges( nRedlineMode ) );
216     aAny.setValue( &bShowChanges, ::getBooleanCppuType() );
217     xInfoSet->setPropertyValue( sShowChanges, aAny );
218     // ... and hide redlines for export
219     nRedlineMode &= ~nsRedlineMode_t::REDLINE_SHOW_MASK;
220     nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_INSERT;
221     pDoc->SetRedlineMode((RedlineMode_t)( nRedlineMode ));
222 
223     // Set base URI
224     OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
225     xInfoSet->setPropertyValue( sPropName, makeAny( ::rtl::OUString( GetBaseURL() ) ) );
226 
227     if( SFX_CREATE_MODE_EMBEDDED == pDoc->GetDocShell()->GetCreateMode() )
228     {
229         OUString aName;
230         if ( aDocHierarchicalName.getLength() )
231             aName = aDocHierarchicalName;
232         else
233             aName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "dummyObjectName" ) );
234 
235         sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
236         xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
237     }
238 
239     if( bBlock )
240     {
241         OUString sAutoTextMode(
242                 RTL_CONSTASCII_USTRINGPARAM("AutoTextMode"));
243         sal_Bool bTmp = sal_True;
244         Any aAny2;
245         aAny2.setValue( &bTmp, ::getBooleanCppuType() );
246         xInfoSet->setPropertyValue( sAutoTextMode, aAny2 );
247     }
248 
249     // --> OD 2006-09-26 #i69627#
250     const sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
251     if ( bOASIS &&
252          docfunc::HasOutlineStyleToBeWrittenAsNormalListStyle( *pDoc ) )
253     {
254         OUString sOutlineStyleAsNormalListStyle(
255                 RTL_CONSTASCII_USTRINGPARAM("OutlineStyleAsNormalListStyle") );
256         xInfoSet->setPropertyValue( sOutlineStyleAsNormalListStyle, makeAny( sal_True ) );
257     }
258     // <--
259 
260     // filter arguments
261     // - graphics + object resolver for styles + content
262     // - status indicator
263     // - info property set
264     // - else empty
265     sal_Int32 nArgs = 1;
266     if( xStatusIndicator.is() )
267         nArgs++;
268 
269     Sequence < Any > aEmptyArgs( nArgs );
270     Any *pArgs = aEmptyArgs.getArray();
271     *pArgs++ <<= xInfoSet;
272     if( xStatusIndicator.is() )
273         *pArgs++ <<= xStatusIndicator;
274 
275     if( xGraphicResolver.is() )
276         nArgs++;
277     if( xObjectResolver.is() )
278         nArgs++;
279 
280     Sequence < Any > aFilterArgs( nArgs );
281     pArgs = aFilterArgs.getArray();
282     *pArgs++ <<= xInfoSet;
283     if( xGraphicResolver.is() )
284         *pArgs++ <<= xGraphicResolver;
285     if( xObjectResolver.is() )
286         *pArgs++ <<= xObjectResolver;
287     if( xStatusIndicator.is() )
288         *pArgs++ <<= xStatusIndicator;
289 
290     //Get model
291     uno::Reference< lang::XComponent > xModelComp(
292         pDoc->GetDocShell()->GetModel(), UNO_QUERY );
293     ASSERT( xModelComp.is(), "XMLWriter::Write: got no model" );
294     if( !xModelComp.is() )
295         return ERR_SWG_WRITE_ERROR;
296 
297     PutNumFmtFontsInAttrPool();
298     PutEditEngFontsInAttrPool();
299 
300     // properties
301     Sequence < PropertyValue > aProps( pOrigFileName ? 1 : 0 );
302     if( pOrigFileName )
303     {
304         PropertyValue *pProps = aProps.getArray();
305         pProps->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FileName") );
306         (pProps++)->Value <<= OUString( *pOrigFileName  );
307     }
308 
309     // export sub streams for package, else full stream into a file
310     sal_Bool bWarn = sal_False, bErr = sal_False;
311     String sWarnFile, sErrFile;
312 
313     // RDF metadata: export if ODF >= 1.2
314     // N.B.: embedded documents have their own manifest.rdf!
315     if ( bOASIS )
316     {
317         const uno::Reference<beans::XPropertySet> xPropSet(xStg,
318             uno::UNO_QUERY_THROW);
319         const ::rtl::OUString VersionProp(
320             ::rtl::OUString::createFromAscii("Version"));
321         try
322         {
323             ::rtl::OUString Version;
324             // ODF >= 1.2
325             if ((xPropSet->getPropertyValue(VersionProp) >>= Version)
326                 && !Version.equals(ODFVER_010_TEXT)
327                 && !Version.equals(ODFVER_011_TEXT))
328             {
329                 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(
330                     xModelComp, uno::UNO_QUERY_THROW);
331                 xDMA->storeMetadataToStorage(xStg);
332             }
333         }
334         catch (beans::UnknownPropertyException &)
335         { /* ignore */ }
336         catch (uno::Exception &)
337         {
338             bWarn = sal_True;
339         }
340     }
341 
342     sal_Bool bStoreMeta = ( SFX_CREATE_MODE_EMBEDDED != pDoc->GetDocShell()->GetCreateMode() );
343     if ( !bStoreMeta )
344     {
345         try
346         {
347             Reference< frame::XModule > xModule( xModelComp, UNO_QUERY );
348             if ( xModule.is() )
349             {
350                 ::rtl::OUString aModuleID = xModule->getIdentifier();
351                 bStoreMeta = ( aModuleID.getLength()
352                   && ( aModuleID.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FormDesign" ) ) )
353                     || aModuleID.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TextReportDesign" ) ) ) ) );
354             }
355         }
356         catch( uno::Exception& )
357         {}
358     }
359 
360     if( !bOrganizerMode && !bBlock && bStoreMeta )
361     {
362         if( !WriteThroughComponent(
363                 xModelComp, "meta.xml", xServiceFactory,
364                 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisMetaExporter"
365                         : "com.sun.star.comp.Writer.XMLMetaExporter"),
366                 aEmptyArgs, aProps, sal_True ) )
367         {
368             bWarn = sal_True;
369             sWarnFile = String( RTL_CONSTASCII_STRINGPARAM("meta.xml"),
370                                 RTL_TEXTENCODING_ASCII_US );
371         }
372     }
373 
374     if( !bErr )
375     {
376         if( !bBlock )
377         {
378             if( !WriteThroughComponent(
379                 xModelComp, "settings.xml", xServiceFactory,
380                 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisSettingsExporter"
381                         : "com.sun.star.comp.Writer.XMLSettingsExporter"),
382                 aEmptyArgs, aProps, sal_False ) )
383             {
384                 if( !bWarn )
385                 {
386                     bWarn = sal_True;
387                     sWarnFile = String( RTL_CONSTASCII_STRINGPARAM("settings.xml"),
388                                         RTL_TEXTENCODING_ASCII_US );
389                 }
390             }
391         }
392     }
393 
394     if( !WriteThroughComponent(
395             xModelComp, "styles.xml", xServiceFactory,
396             (bOASIS ? "com.sun.star.comp.Writer.XMLOasisStylesExporter"
397                     : "com.sun.star.comp.Writer.XMLStylesExporter"),
398             aFilterArgs, aProps, sal_False ) )
399     {
400         bErr = sal_True;
401         sErrFile = String( RTL_CONSTASCII_STRINGPARAM("styles.xml"),
402                            RTL_TEXTENCODING_ASCII_US );
403     }
404 
405 
406     if( !bOrganizerMode && !bErr )
407     {
408         if( !WriteThroughComponent(
409                 xModelComp, "content.xml", xServiceFactory,
410                 (bOASIS ? "com.sun.star.comp.Writer.XMLOasisContentExporter"
411                         : "com.sun.star.comp.Writer.XMLContentExporter"),
412                 aFilterArgs, aProps, sal_False ) )
413         {
414             bErr = sal_True;
415             sErrFile = String( RTL_CONSTASCII_STRINGPARAM("content.xml"),
416                                RTL_TEXTENCODING_ASCII_US );
417         }
418     }
419 
420     if( pDoc->GetCurrentViewShell() && pDoc->GetDocStat().nPage > 1 &&  //swmod 071108//swmod 071225
421         !(bOrganizerMode || bBlock || bErr) )
422     {
423 //          DBG_ASSERT( !pDoc->GetDocStat().bModified,
424 //                      "doc stat is modified!" );
425         OUString sStreamName( RTL_CONSTASCII_USTRINGPARAM("layout-cache") );
426         try
427         {
428             uno::Reference < io::XStream > xStm = xStg->openStreamElement( sStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
429             SvStream* pStream = utl::UcbStreamHelper::CreateStream( xStm );
430             if( !pStream->GetError() )
431             {
432                 uno::Reference < beans::XPropertySet > xSet( xStm, UNO_QUERY );
433                 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
434                 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("application/binary") );
435                 uno::Any aAny2;
436                 aAny2 <<= aMime;
437                 xSet->setPropertyValue( aPropName, aAny2 );
438                 pDoc->WriteLayoutCache( *pStream );
439             }
440 
441             delete pStream;
442         }
443         catch ( uno::Exception& )
444         {
445         }
446     }
447 
448     if( pGraphicHelper )
449         SvXMLGraphicHelper::Destroy( pGraphicHelper );
450     xGraphicResolver = 0;
451 
452     if( pObjectHelper )
453         SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
454     xObjectResolver = 0;
455 
456     // restore redline mode
457     aAny = xInfoSet->getPropertyValue( sShowChanges );
458     nRedlineMode = pDoc->GetRedlineMode();
459     nRedlineMode &= ~nsRedlineMode_t::REDLINE_SHOW_MASK;
460     nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_INSERT;
461     if ( *(sal_Bool*)aAny.getValue() )
462         nRedlineMode |= nsRedlineMode_t::REDLINE_SHOW_DELETE;
463     pDoc->SetRedlineMode((RedlineMode_t)( nRedlineMode ));
464 
465     if (xStatusIndicator.is())
466     {
467         xStatusIndicator->end();
468     }
469 
470     if( bErr )
471     {
472         if( sErrFile.Len() )
473             return *new StringErrorInfo( ERR_WRITE_ERROR_FILE, sErrFile,
474                                          ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
475         else
476             return ERR_SWG_WRITE_ERROR;
477     }
478     else if( bWarn )
479     {
480         if( sWarnFile.Len() )
481             return *new StringErrorInfo( WARN_WRITE_ERROR_FILE, sWarnFile,
482                                          ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
483         else
484             return WARN_SWG_FEATURES_LOST;
485     }
486 
487     return 0;
488 }
489 
WriteStorage()490 sal_uLong SwXMLWriter::WriteStorage()
491 {
492     return _Write( uno::Reference < task::XStatusIndicator >(), ::rtl::OUString() );
493 }
494 
WriteMedium(SfxMedium & aTargetMedium)495 sal_uLong SwXMLWriter::WriteMedium( SfxMedium& aTargetMedium )
496 {
497     uno::Reference < task::XStatusIndicator > xStatusIndicator;
498     rtl::OUString aName;
499     const SfxUnoAnyItem* pStatusBarItem = static_cast<const SfxUnoAnyItem*>(
500        aTargetMedium.GetItemSet()->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
501     if ( pStatusBarItem )
502         pStatusBarItem->GetValue() >>= xStatusIndicator;
503     const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
504         aTargetMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
505     if ( pDocHierarchItem )
506         aName = pDocHierarchItem->GetValue();
507 
508     return _Write( xStatusIndicator, aName );
509 }
510 
Write(SwPaM & rPaM,SfxMedium & rMed,const String * pFileName)511 sal_uLong SwXMLWriter::Write( SwPaM& rPaM, SfxMedium& rMed,
512                                const String* pFileName )
513 {
514     return IsStgWriter()
515             ? ((StgWriter *)this)->Write( rPaM, rMed.GetOutputStorage(), pFileName, &rMed )
516             : ((Writer *)this)->Write( rPaM, *rMed.GetOutStream(), pFileName );
517 }
518 
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)519 sal_Bool SwXMLWriter::WriteThroughComponent(
520     const uno::Reference<XComponent> & xComponent,
521     const sal_Char* pStreamName,
522     const uno::Reference<lang::XMultiServiceFactory> & rFactory,
523     const sal_Char* pServiceName,
524     const Sequence<Any> & rArguments,
525     const Sequence<beans::PropertyValue> & rMediaDesc,
526     sal_Bool bPlainStream )
527 {
528     DBG_ASSERT( xStg.is(), "Need storage!" );
529     DBG_ASSERT( NULL != pStreamName, "Need stream name!" );
530     DBG_ASSERT( NULL != pServiceName, "Need service name!" );
531 
532     RTL_LOGFILE_TRACE_AUTHOR1( "sw", LOGFILE_AUTHOR,
533                                "SwXMLWriter::WriteThroughComponent : stream %s",
534                                pStreamName );
535 
536     // open stream
537     sal_Bool bRet = sal_False;
538     try
539     {
540         OUString sStreamName = OUString::createFromAscii( pStreamName );
541         uno::Reference<io::XStream> xStream =
542                 xStg->openStreamElement( sStreamName,
543                 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
544 
545         uno::Reference <beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
546         if( !xSet.is() )
547             return sal_False;
548 
549         String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
550         OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
551         uno::Any aAny;
552         aAny <<= aMime;
553         xSet->setPropertyValue( aPropName, aAny );
554 
555         OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
556         if( bPlainStream )
557         {
558             OUString aCompressPropName( RTL_CONSTASCII_USTRINGPARAM("Compressed") );
559             sal_Bool bFalse = sal_False;
560             aAny.setValue( &bFalse, ::getBooleanCppuType() );
561             xSet->setPropertyValue( aCompressPropName, aAny );
562         }
563 
564         // even plain stream should be encrypted in encrypted documents
565         sal_Bool bTrue = sal_True;
566         aAny.setValue( &bTrue, ::getBooleanCppuType() );
567         xSet->setPropertyValue( aUseCommonPassPropName, aAny );
568 
569         // set buffer and create outputstream
570         uno::Reference< io::XOutputStream > xOutputStream = xStream->getOutputStream();
571 
572         // set Base URL
573         uno::Reference< beans::XPropertySet > xInfoSet;
574         if( rArguments.getLength() > 0 )
575             rArguments.getConstArray()[0] >>= xInfoSet;
576         DBG_ASSERT( xInfoSet.is(), "missing property set" );
577         if( xInfoSet.is() )
578         {
579             OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
580             xInfoSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
581         }
582 
583         // write the stuff
584         bRet = WriteThroughComponent(
585             xOutputStream, xComponent, rFactory,
586             pServiceName, rArguments, rMediaDesc );
587     }
588     catch ( uno::Exception& )
589     {
590     }
591 
592     return bRet;
593 
594 }
595 
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)596 sal_Bool SwXMLWriter::WriteThroughComponent(
597     const uno::Reference<io::XOutputStream> & xOutputStream,
598     const uno::Reference<XComponent> & xComponent,
599     const uno::Reference<XMultiServiceFactory> & rFactory,
600     const sal_Char* pServiceName,
601     const Sequence<Any> & rArguments,
602     const Sequence<PropertyValue> & rMediaDesc )
603 {
604     ASSERT( xOutputStream.is(), "I really need an output stream!" );
605     ASSERT( xComponent.is(), "Need component!" );
606     ASSERT( NULL != pServiceName, "Need component name!" );
607 
608     RTL_LOGFILE_CONTEXT_AUTHOR( aFilterLog, "sw", LOGFILE_AUTHOR,
609                                 "SwXMLWriter::WriteThroughComponent" );
610 
611     // get component
612     uno::Reference< io::XActiveDataSource > xSaxWriter(
613         rFactory->createInstance(
614             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
615                 "com.sun.star.xml.sax.Writer")) ),
616         UNO_QUERY );
617     ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
618     if(!xSaxWriter.is())
619         return sal_False;
620 
621     RTL_LOGFILE_CONTEXT_TRACE( aFilterLog, "SAX-Writer created" );
622 
623     // connect XML writer to output stream
624     xSaxWriter->setOutputStream( xOutputStream );
625 
626     // prepare arguments (prepend doc handler to given arguments)
627     uno::Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
628     Sequence<Any> aArgs( 1 + rArguments.getLength() );
629     aArgs[0] <<= xDocHandler;
630     for(sal_Int32 i = 0; i < rArguments.getLength(); i++)
631         aArgs[i+1] = rArguments[i];
632 
633     // get filter component
634     uno::Reference< document::XExporter > xExporter(
635         rFactory->createInstanceWithArguments(
636             OUString::createFromAscii(pServiceName), aArgs), UNO_QUERY);
637     ASSERT( xExporter.is(),
638             "can't instantiate export filter component" );
639     if( !xExporter.is() )
640         return sal_False;
641     RTL_LOGFILE_CONTEXT_TRACE1( aFilterLog, "%s instantiated.", pServiceName );
642 
643     // connect model and filter
644     xExporter->setSourceDocument( xComponent );
645 
646     // filter!
647     RTL_LOGFILE_CONTEXT_TRACE( aFilterLog, "call filter()" );
648     uno::Reference<XFilter> xFilter( xExporter, UNO_QUERY );
649     return xFilter->filter( rMediaDesc );
650 }
651 
652 
653 // -----------------------------------------------------------------------
654 
GetXMLWriter(const String &,const String & rBaseURL,WriterRef & xRet)655 void GetXMLWriter( const String& /*rName*/, const String& rBaseURL, WriterRef& xRet )
656 {
657     xRet = new SwXMLWriter( rBaseURL );
658 }
659 
660 // -----------------------------------------------------------------------
661