xref: /aoo4110/main/sw/source/filter/xml/wrtxml.cxx (revision b1cdbd2c)
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