001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037 #include "precompiled_sw.hxx"
038 #include "swdetect.hxx"
039
040 #include <framework/interaction.hxx>
041 #ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
042 #include <com/sun/star/frame/XFrame.hpp>
043 #endif
044 #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
045 #include <com/sun/star/frame/XModel.hpp>
046 #endif
047 #ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
048 #include <com/sun/star/lang/XUnoTunnel.hpp>
049 #endif
050 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
051 #include <comphelper/processfactory.hxx>
052 #endif
053 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
054 #include <com/sun/star/container/XNameAccess.hpp>
055 #endif
056 #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
057 #include <com/sun/star/io/XInputStream.hpp>
058 #endif
059 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
060 #include <com/sun/star/task/XInteractionHandler.hpp>
061 #endif
062 #ifndef _COM_SUN_STAR_LANG_WRAPPEDTARGETRUNTIMEEXCEPTION_HPP_
063 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
064 #endif
065 #ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
066 #include <com/sun/star/ucb/CommandAbortedException.hpp>
067 #endif
068 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEAPPEXCEPTION_HPP_
069 #include <com/sun/star/ucb/InteractiveAppException.hpp>
070 #endif
071 #ifndef _COM_SUN_STAR_UCB_XCONTENT_HPP_
072 #include <com/sun/star/ucb/XContent.hpp>
073 #endif
074 #ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPIOEXCEPTION_HPP_
075 #include <com/sun/star/packages/zip/ZipIOException.hpp>
076 #endif
077 #ifndef _TOOLKIT_UNOHLP_HXX
078 #include <toolkit/helper/vclunohelper.hxx>
079 #endif
080 #ifndef _UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX
081 #include <ucbhelper/simpleinteractionrequest.hxx>
082 #endif
083 #include <rtl/ustring.h>
084 #include <rtl/logfile.hxx>
085 #include <svtools/itemset.hxx>
086 #include <vcl/window.hxx>
087 #include <svtools/eitem.hxx>
088 #include <svtools/stritem.hxx>
089 #include <tools/urlobj.hxx>
090 #include <vos/mutex.hxx>
091 #include <svtools/sfxecode.hxx>
092 #include <svtools/ehdl.hxx>
093 #include <sot/storinfo.hxx>
094 #include <vcl/svapp.hxx>
095 #include <sfx2/app.hxx>
096 #include <sfx2/sfxsids.hrc>
097 #include <sfx2/request.hxx>
098 #include <sfx2/docfile.hxx>
099 #include <sfx2/docfilt.hxx>
100 #include <sfx2/fcontnr.hxx>
101 #include <sfx2/brokenpackageint.hxx>
102 #include <svx/impgrf.hxx>
103 #include <svtools/FilterConfigItem.hxx>
104
105 #ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
106 #include <svtools/moduleoptions.hxx>
107 #endif
108 #ifndef _COM_SUN_STAR_UTIL_XARCHIVER_HPP_
109 #include <com/sun/star/util/XArchiver.hpp>
110 #endif
111
112 #include <swdll.hxx>
113
114 using namespace ::com::sun::star;
115 using namespace ::com::sun::star::uno;
116 using namespace ::com::sun::star::io;
117 using namespace ::com::sun::star::frame;
118 using namespace ::com::sun::star::task;
119 using namespace ::com::sun::star::beans;
120 using namespace ::com::sun::star::lang;
121 using namespace ::com::sun::star::ucb;
122 using namespace ::rtl;
123
124 SwFilterDetect::SwFilterDetect( const REFERENCE < lang::XMultiServiceFactory >& )
125 {
126 }
127
128 SwFilterDetect::~SwFilterDetect()
129 {
130 }
131
132 ::rtl::OUString SAL_CALL SwFilterDetect::detect( uno::Sequence< beans::PropertyValue >& lDescriptor ) throw( uno::RuntimeException )
133 {
134 REFERENCE< XInputStream > xStream;
135 REFERENCE< XContent > xContent;
136 REFERENCE< XInteractionHandler > xInteraction;
137 String aURL;
138 ::rtl::OUString sTemp;
139 String aTypeName;
140 String aPreselectedFilterName;
141
142 ::rtl::OUString aDocumentTitle;
143
144
145
146
147 sal_Bool bOpenAsTemplate = sal_False;
148 sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
149
150 sal_Bool bRepairPackage = sal_False;
151 sal_Bool bRepairAllowed = sal_False;
152
153
154
155 sal_Int32 nPropertyCount = lDescriptor.getLength();
156 sal_Int32 nIndexOfFilterName = -1;
157 sal_Int32 nIndexOfInputStream = -1;
158 sal_Int32 nIndexOfContent = -1;
159 sal_Int32 nIndexOfReadOnlyFlag = -1;
160 sal_Int32 nIndexOfTemplateFlag = -1;
161 sal_Int32 nIndexOfDocumentTitle = -1;
162
163 for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
164 {
165
166 if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
167 {
168 lDescriptor[nProperty].Value >>= sTemp;
169 aURL = sTemp;
170 }
171 else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
172 {
173 lDescriptor[nProperty].Value >>= sTemp;
174 aURL = sTemp;
175 }
176 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
177 {
178 lDescriptor[nProperty].Value >>= sTemp;
179 aTypeName = sTemp;
180 }
181 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
182 {
183 lDescriptor[nProperty].Value >>= sTemp;
184 aPreselectedFilterName = sTemp;
185
186
187
188 nIndexOfFilterName = nProperty;
189 }
190 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
191 nIndexOfInputStream = nProperty;
192 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
193 nIndexOfReadOnlyFlag = nProperty;
194 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
195 nIndexOfContent = nProperty;
196 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
197 {
198 lDescriptor[nProperty].Value >>= bOpenAsTemplate;
199 nIndexOfTemplateFlag = nProperty;
200 }
201 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
202 lDescriptor[nProperty].Value >>= xInteraction;
203 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RapairPackage")) )
204 lDescriptor[nProperty].Value >>= bRepairPackage;
205 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
206 nIndexOfDocumentTitle = nProperty;
207 }
208
209
210 ::vos::OGuard aGuard( Application::GetSolarMutex() );
211
212
213 SfxApplication* pApp = SFX_APP();
214 SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() );
215 TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
216 SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, FALSE );
217
218 bWasReadOnly = pItem && pItem->GetValue();
219
220 const SfxFilter* pFilter = 0;
221 String aPrefix = String::CreateFromAscii( "private:factory/" );
222 if( aURL.Match( aPrefix ) == aPrefix.Len() )
223 {
224 if( SvtModuleOptions().IsWriter() )
225 {
226 String aPattern( aPrefix );
227 aPattern += String::CreateFromAscii("swriter");
228 if ( aURL.Match( aPattern ) >= aPattern.Len() )
229
230 return aTypeName;
231 }
232 }
233 else
234 {
235
236 SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, FALSE, NULL, pSet );
237 aMedium.UseInteractionHandler( TRUE );
238 if ( aMedium.GetErrorCode() == ERRCODE_NONE )
239 {
240
241
242 xStream = aMedium.GetInputStream();
243 xContent = aMedium.GetContent();
244 bReadOnly = aMedium.IsReadOnly();
245
246 BOOL bIsStorage = aMedium.IsStorage();
247 if ( bIsStorage )
248 {
249 uno::Reference< embed::XStorage > xStorage = aMedium.GetStorage();
250 if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
251 {
252
253
254
255 aMedium.SetError( aMedium.GetLastStorageCreationState() );
256 if ( xInteraction.is() )
257 {
258 OUString empty;
259 try
260 {
261 InteractiveAppException xException( empty,
262 REFERENCE< XInterface >(),
263 InteractionClassification_ERROR,
264 aMedium.GetError() );
265
266 REFERENCE< XInteractionRequest > xRequest(
267 new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
268 ucbhelper::CONTINUATION_APPROVE ) );
269 xInteraction->handle( xRequest );
270 }
271 catch ( Exception & ) {};
272 }
273 }
274 else
275 {
276 DBG_ASSERT( xStorage.is(), "At this point storage must exist!" );
277
278 try
279 {
280 const SfxFilter* pPreFilter = aPreselectedFilterName.Len() ?
281 SfxFilterMatcher().GetFilter4FilterName( aPreselectedFilterName ) : aTypeName.Len() ?
282 SfxFilterMatcher(String::CreateFromAscii("swriter")).GetFilter4EA( aTypeName ) : 0;
283 if (!pPreFilter)
284 pPreFilter = SfxFilterMatcher(String::CreateFromAscii("sweb")).GetFilter4EA( aTypeName );
285 String aFilterName;
286 if ( pPreFilter )
287 {
288 aFilterName = pPreFilter->GetName();
289 aTypeName = pPreFilter->GetTypeName();
290 }
291
292 aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pPreFilter ? pPreFilter->IsOwnTemplateFormat() : FALSE, &aFilterName );
293 }
294 catch( lang::WrappedTargetException& aWrap )
295 {
296 packages::zip::ZipIOException aZipException;
297
298
299
300
301 if ( ( aWrap.TargetException >>= aZipException ) && ( aTypeName.Len() || aPreselectedFilterName.Len() ) )
302 {
303 if ( xInteraction.is() )
304 {
305
306 aDocumentTitle = aMedium.GetURLObject().getName(
307 INetURLObject::LAST_SEGMENT,
308 true,
309 INetURLObject::DECODE_WITH_CHARSET );
310
311 if ( !bRepairPackage )
312 {
313
314 RequestPackageReparation* pRequest = new RequestPackageReparation( aDocumentTitle );
315 uno::Reference< task::XInteractionRequest > xRequest ( pRequest );
316 xInteraction->handle( xRequest );
317 bRepairAllowed = pRequest->isApproved();
318 }
319
320 if ( !bRepairAllowed )
321 {
322
323 NotifyBrokenPackage* pNotifyRequest = new NotifyBrokenPackage( aDocumentTitle );
324 uno::Reference< task::XInteractionRequest > xRequest ( pNotifyRequest );
325 xInteraction->handle( xRequest );
326 aMedium.SetError( ERRCODE_ABORT );
327 }
328 }
329 else
330
331 aMedium.SetError( ERRCODE_IO_BROKENPACKAGE );
332
333 if ( !bRepairAllowed )
334 {
335 aTypeName.Erase();
336 aPreselectedFilterName.Erase();
337 }
338 }
339 }
340 catch( uno::RuntimeException& )
341 {
342 throw;
343 }
344 catch( uno::Exception& )
345 {
346 aTypeName.Erase();
347 aPreselectedFilterName.Erase();
348 }
349 }
350 }
351 else
352 {
353 aMedium.GetInStream();
354 if ( aMedium.GetErrorCode() == ERRCODE_NONE )
355 {
356 if ( aPreselectedFilterName.Len() )
357 pFilter = SfxFilter::GetFilterByName( aPreselectedFilterName );
358 else
359 pFilter = SfxFilterMatcher().GetFilter4EA( aTypeName );
360
361 BOOL bTestWriter = !pFilter || pFilter->GetServiceName().EqualsAscii("com.sun.star.text.TextDocument") ||
362 pFilter->GetServiceName().EqualsAscii("com.sun.star.text.WebDocument");
363 BOOL bTestGlobal = !pFilter || pFilter->GetServiceName().EqualsAscii("com.sun.star.text.GlobalDocument");
364
365 const SfxFilter* pOrigFilter = NULL;
366 if ( !bTestWriter && !bTestGlobal && pFilter )
367 {
368
369
370
371 pOrigFilter = pFilter;
372 pFilter = SfxFilterMatcher().GetFilter4EA( pFilter->GetTypeName() );
373 bTestWriter = TRUE;
374 }
375
376 ULONG nErr = ERRCODE_NONE;
377 if ( pFilter || bTestWriter )
378 nErr = DetectFilter( aMedium, &pFilter );
379 if ( nErr != ERRCODE_NONE )
380 pFilter = NULL;
381 else if ( pOrigFilter && pFilter && pFilter->GetTypeName() == pOrigFilter->GetTypeName() )
382
383 pFilter = pOrigFilter;
384 }
385
386 if ( pFilter )
387 aTypeName = pFilter->GetTypeName();
388 else
389 aTypeName.Erase();
390 }
391 }
392 }
393
394 if ( nIndexOfInputStream == -1 && xStream.is() )
395 {
396
397 lDescriptor.realloc( nPropertyCount + 1 );
398 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("InputStream");
399 lDescriptor[nPropertyCount].Value <<= xStream;
400 nPropertyCount++;
401 }
402
403 if ( nIndexOfContent == -1 && xContent.is() )
404 {
405
406 lDescriptor.realloc( nPropertyCount + 1 );
407 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("UCBContent");
408 lDescriptor[nPropertyCount].Value <<= xContent;
409 nPropertyCount++;
410 }
411
412 if ( bReadOnly != bWasReadOnly )
413 {
414 if ( nIndexOfReadOnlyFlag == -1 )
415 {
416 lDescriptor.realloc( nPropertyCount + 1 );
417 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("ReadOnly");
418 lDescriptor[nPropertyCount].Value <<= bReadOnly;
419 nPropertyCount++;
420 }
421 else
422 lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
423 }
424
425 if ( !bRepairPackage && bRepairAllowed )
426 {
427 lDescriptor.realloc( nPropertyCount + 1 );
428 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("RepairPackage");
429 lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
430 nPropertyCount++;
431 bOpenAsTemplate = sal_True;
432
433 }
434
435 if ( bOpenAsTemplate )
436 {
437 if ( nIndexOfTemplateFlag == -1 )
438 {
439 lDescriptor.realloc( nPropertyCount + 1 );
440 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("AsTemplate");
441 lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
442 nPropertyCount++;
443 }
444 else
445 lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
446 }
447
448 if ( aDocumentTitle.getLength() )
449 {
450
451 if ( nIndexOfDocumentTitle == -1 )
452 {
453 lDescriptor.realloc( nPropertyCount + 1 );
454 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("DocumentTitle");
455 lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
456 nPropertyCount++;
457 }
458 else
459 lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
460 }
461
462
463 return aTypeName;
464 }
465
466 SFX_IMPL_SINGLEFACTORY( SwFilterDetect )
467
468
469 UNOOUSTRING SAL_CALL SwFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
470 {
471 return impl_getStaticImplementationName();
472 }
473 \
474
475 sal_Bool SAL_CALL SwFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION )
476 {
477 UNOSEQUENCE< UNOOUSTRING > seqServiceNames = getSupportedServiceNames();
478 const UNOOUSTRING* pArray = seqServiceNames.getConstArray();
479 for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
480 {
481 if ( pArray[nCounter] == sServiceName )
482 {
483 return sal_True ;
484 }
485 }
486 return sal_False ;
487 }
488
489
490 UNOSEQUENCE< UNOOUSTRING > SAL_CALL SwFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
491 {
492 return impl_getStaticSupportedServiceNames();
493 }
494
495
496 UNOSEQUENCE< UNOOUSTRING > SwFilterDetect::impl_getStaticSupportedServiceNames()
497 {
498 UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() );
499 UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 3 );
500 seqServiceNames.getArray() [0] = UNOOUSTRING::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection" );
501 seqServiceNames.getArray() [1] = UNOOUSTRING::createFromAscii( "com.sun.star.text.FormatDetector" );
502 seqServiceNames.getArray() [2] = UNOOUSTRING::createFromAscii( "com.sun.star.text.W4WFormatDetector" );
503 return seqServiceNames ;
504 }
505
506
507 UNOOUSTRING SwFilterDetect::impl_getStaticImplementationName()
508 {
509 return UNOOUSTRING::createFromAscii( "com.sun.star.comp.writer.FormatDetector" );
510 }
511
512
513 UNOREFERENCE< UNOXINTERFACE > SAL_CALL SwFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
514 {
515 return UNOREFERENCE< UNOXINTERFACE >( *new SwFilterDetect( xServiceManager ) );
516 }
517