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_filter.hxx"
26 #include "typedetection.hxx"
27 #include "constant.hxx"
28
29 //_______________________________________________
30 // includes
31 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
32 #include <com/sun/star/util/XURLTransformer.hpp>
33
34 #ifndef _COM_SUN_STAR_IO_XINPUSTREAM_HPP_
35 #include <com/sun/star/io/XInputStream.hpp>
36 #endif
37 #include <com/sun/star/io/XSeekable.hpp>
38 #include <com/sun/star/task/XInteractionHandler.hpp>
39 #include <tools/wldcrd.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <framework/interaction.hxx>
42 #include <tools/urlobj.hxx>
43 #include <unotools/localfilehelper.hxx>
44
45 //_______________________________________________
46 // namespace
47
48 namespace filter{
49 namespace config{
50
51 namespace css = ::com::sun::star;
52
53 //_______________________________________________
54 // definitions
55
56 // Use this switch to change the behavior of preselection DocumentService ... (see using for further informations)
57 #define IGNORE_NON_URLMATCHING_TYPES_FOR_PRESELECTION_DOCUMENTSERVICE
58
59 // enable/disable special handling for CSV/TXT problem
60 #define WORKAROUND_CSV_TXT_BUG_i60158
61
62 /*-----------------------------------------------
63 03.07.2003 11:25
64 -----------------------------------------------*/
TypeDetection(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)65 TypeDetection::TypeDetection(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
66 {
67 BaseContainer::init(xSMGR ,
68 TypeDetection::impl_getImplementationName() ,
69 TypeDetection::impl_getSupportedServiceNames(),
70 FilterCache::E_TYPE );
71 }
72
73 /*-----------------------------------------------
74 03.07.2003 10:36
75 -----------------------------------------------*/
~TypeDetection()76 TypeDetection::~TypeDetection()
77 {
78 }
79
80 /*-----------------------------------------------
81 03.11.2003 08:43
82 -----------------------------------------------*/
queryTypeByURL(const::rtl::OUString & sURL)83 ::rtl::OUString SAL_CALL TypeDetection::queryTypeByURL(const ::rtl::OUString& sURL)
84 throw (css::uno::RuntimeException)
85 {
86 ::rtl::OUString sType;
87
88 // SAFE ->
89 ::osl::ResettableMutexGuard aLock(m_aLock);
90
91 css::util::URL aURL;
92 aURL.Complete = sURL;
93 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICE_URLTRANSFORMER), css::uno::UNO_QUERY);
94 xParser->parseStrict(aURL);
95
96 // set std types as minimum requirement first!
97 // Only in case no type was found for given URL,
98 // use optional types too ...
99 FlatDetection lFlatTypes;
100 m_rCache->detectFlatForURL(aURL, lFlatTypes);
101
102 if (
103 (lFlatTypes.size() < 1 ) &&
104 (!m_rCache->isFillState(FilterCache::E_CONTAINS_TYPES))
105 )
106 {
107 m_rCache->load(FilterCache::E_CONTAINS_TYPES);
108 m_rCache->detectFlatForURL(aURL, lFlatTypes);
109 }
110
111 // first item is guaranteed as "preferred" one!
112 if (lFlatTypes.size() > 0)
113 {
114 const FlatDetectionInfo& aMatch = *(lFlatTypes.begin());
115 sType = aMatch.sType;
116 }
117
118 return sType;
119 // <- SAFE
120 }
121
122 /*-----------------------------------------------
123 31.10.2003 09:36
124 -----------------------------------------------*/
queryTypeByDescriptor(css::uno::Sequence<css::beans::PropertyValue> & lDescriptor,sal_Bool bAllowDeep)125 ::rtl::OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css::beans::PropertyValue >& lDescriptor,
126 sal_Bool bAllowDeep )
127 throw (css::uno::RuntimeException)
128 {
129 // make the descriptor more usable :-)
130 ::comphelper::MediaDescriptor stlDescriptor(lDescriptor);
131
132 // SAFE -> ----------------------------------
133 ::osl::ResettableMutexGuard aLock(m_aLock);
134
135 //*******************************************
136 // parse given URL to split it into e.g. main and jump marks ...
137 ::rtl::OUString sURL = stlDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString());
138
139 #if OSL_DEBUG_LEVEL > 0
140 if (stlDescriptor.find(::rtl::OUString::createFromAscii("FileName")) != stlDescriptor.end())
141 OSL_ENSURE(sal_False, "Detect using of deprecated and already unsupported MediaDescriptor property \"FileName\"!");
142 #endif
143
144 css::util::URL aURL;
145 aURL.Complete = sURL;
146 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICE_URLTRANSFORMER), css::uno::UNO_QUERY);
147 xParser->parseStrict(aURL);
148
149 //*******************************************
150 // preselected filter, type or document service?
151 // use it as first "flat" detected type later!
152 FlatDetection lFlatTypes;
153 impl_getPreselection(aURL, stlDescriptor, lFlatTypes);
154
155 //*******************************************
156 // get all types, which match to the given descriptor
157 // That can be true by: extensions/url pattern/mime type etcpp.
158 m_rCache->detectFlatForURL(aURL, lFlatTypes);
159
160 aLock.clear();
161 // <- SAFE ----------------------------------
162
163 ::rtl::OUString sType ;
164 ::rtl::OUString sLastChance;
165
166 try
167 {
168 //*******************************************
169 // verify every flat detected (or preselected!) type
170 // by calling its registered deep detection service.
171 // But break this loop if a type match to the given descriptor
172 // by an URL pattern(!) or if deep detection isn't allowed from
173 // outside (bAllowDeep=sal_False) or break the whole detection by
174 // throwing an exception if creation of the might needed input
175 // stream failed by e.g. an IO exception ...
176 OUStringList lUsedDetectors;
177 if (lFlatTypes.size()>0)
178 sType = impl_detectTypeFlatAndDeep(stlDescriptor, lFlatTypes, bAllowDeep, lUsedDetectors, sLastChance);
179
180 //*******************************************
181 // if no flat detected (nor preselected!) type could be
182 // verified and no error occurred during creation of
183 // the might needed input stream, start detection
184 // which uses all registered deep detection services.
185 if (
186 (!sType.getLength()) &&
187 (bAllowDeep )
188 )
189 {
190 sType = impl_detectTypeDeepOnly(stlDescriptor, lUsedDetectors);
191 }
192
193 //*******************************************
194 // flat detection failed
195 // pure deep detection failed
196 // => ask might existing InteractionHandler
197 // means: ask user for it's decision
198 if (!sType.getLength())
199 sType = impl_askUserForTypeAndFilterIfAllowed(stlDescriptor);
200
201 //*******************************************
202 // no real detected type - but a might valid one.
203 // update descriptor and set last chance for return.
204 if (!sType.getLength() && sLastChance.getLength())
205 {
206 OSL_ENSURE(sal_False, "set first flat detected type without a registered deep detection service as \"last chance\" ... nevertheless some other deep detections said \"NO\". I TRY IT!");
207 sType = sLastChance;
208 }
209 }
210 catch(const css::uno::RuntimeException&)
211 { throw; }
212 catch(const css::uno::Exception&)
213 { sType = ::rtl::OUString(); }
214
215 //*******************************************
216 // adapt media descriptor, so it contains the right values
217 // for type/filter name/document service/ etcpp.
218 impl_checkResultsAndAddBestFilter(stlDescriptor, sType); // Attention: sType is used as IN/OUT param here and will might be changed inside this method !!!
219 impl_validateAndSetTypeOnDescriptor(stlDescriptor, sType);
220
221 stlDescriptor >> lDescriptor;
222 return sType;
223 }
224
225 /*-----------------------------------------------
226 03.07.2003 10:36
227 -----------------------------------------------*/
impl_checkResultsAndAddBestFilter(::comphelper::MediaDescriptor & rDescriptor,::rtl::OUString & sType)228 void TypeDetection::impl_checkResultsAndAddBestFilter(::comphelper::MediaDescriptor& rDescriptor,
229 ::rtl::OUString& sType )
230 {
231 // a)
232 // Don't overwrite a might preselected filter!
233 ::rtl::OUString sFilter = rDescriptor.getUnpackedValueOrDefault(
234 ::comphelper::MediaDescriptor::PROP_FILTERNAME(),
235 ::rtl::OUString());
236 if (sFilter.getLength())
237 return;
238
239 // b)
240 // check a preselected document service too.
241 // Then we have to search a suitable filter witin this module.
242 ::rtl::OUString sDocumentService = rDescriptor.getUnpackedValueOrDefault(
243 ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(),
244 ::rtl::OUString());
245 if (sDocumentService.getLength())
246 {
247 try
248 {
249 ::rtl::OUString sRealType = sType;
250
251 #ifdef WORKAROUND_CSV_TXT_BUG_i60158
252 // Workaround for #i60158#
253 // We do not have right filter for Text_Ascii in calc nor a suitable filter for CSV in writer.
254 // So we must overrule our detection and make the right things. Normally we should have
255 // one type TextAscii and two filters registered for these one type.
256 // But then we loose automatic opening of CSV files in calc instead of opening these files
257 // inside writer.
258 if (
259 (sDocumentService.equalsAscii("com.sun.star.sheet.SpreadsheetDocument")) &&
260 (
261 (sRealType.equalsAscii("writer_Text" )) ||
262 (sRealType.equalsAscii("writer_Text_encoded"))
263 )
264 )
265 {
266 sRealType = ::rtl::OUString::createFromAscii("calc_Text_txt_csv_StarCalc");
267 }
268 else
269 if (
270 (sDocumentService.equalsAscii("com.sun.star.text.TextDocument")) &&
271 (sRealType.equalsAscii("calc_Text_txt_csv_StarCalc" ))
272 )
273 {
274 sRealType = ::rtl::OUString::createFromAscii("writer_Text");
275 }
276 #endif // WORKAROUND_CSV_TXT_BUG_i60158
277
278 // SAFE ->
279 ::osl::ResettableMutexGuard aLock(m_aLock);
280
281 // Attention: For executing next lines of code, We must be sure that
282 // all filters already loaded :-(
283 // That can disturb our "load on demand feature". But we have no other chance!
284 m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
285
286 CacheItem lIProps;
287 lIProps[PROPNAME_DOCUMENTSERVICE] <<= sDocumentService;
288 lIProps[PROPNAME_TYPE ] <<= sRealType;
289 OUStringList lFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
290
291 aLock.clear();
292 // <- SAFE
293
294 for ( OUStringList::const_iterator pIt = lFilters.begin();
295 pIt != lFilters.end() && sFilter.getLength() == 0 ;
296 ++pIt )
297 {
298 // SAFE ->
299 aLock.reset();
300 try
301 {
302 CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, *pIt);
303 sal_Int32 nFlags = 0;
304 aFilter[PROPNAME_FLAGS] >>= nFlags;
305
306 if ((nFlags & FLAGVAL_IMPORT) == FLAGVAL_IMPORT)
307 sFilter = *pIt;
308 }
309 catch(const css::uno::Exception&) {}
310 aLock.clear();
311 // <- SAFE
312 }
313
314 if (sFilter.getLength() > 0)
315 {
316 rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sRealType;
317 rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
318 sType = sRealType;
319 return;
320 }
321 }
322 catch(const css::uno::Exception&)
323 {}
324 }
325
326 // c)
327 // We can use the preferred filter for the specified type.
328 // Such preferred filter points:
329 // - to the default filter of the preferred application
330 // - or to any other filter if no preferred filter was set.
331 // Note: It's an optimization only!
332 // It's not guaranteed, that such preferred filter exists.
333 sFilter = ::rtl::OUString();
334 try
335 {
336 // SAFE ->
337 ::osl::ResettableMutexGuard aLock(m_aLock);
338
339 CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
340 aType[PROPNAME_PREFERREDFILTER] >>= sFilter;
341 CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
342
343 aLock.clear();
344 // <- SAFE
345
346 // no exception => found valid type and filter => set it on the given descriptor
347 rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sType ;
348 rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
349 return;
350 }
351 catch(const css::uno::Exception&)
352 {}
353
354 // d)
355 // Search for any import(!) filter, which is registered for this type.
356 sFilter = ::rtl::OUString();
357 try
358 {
359 // SAFE ->
360 ::osl::ResettableMutexGuard aLock(m_aLock);
361
362 // Attention: For executing next lines of code, We must be sure that
363 // all filters already loaded :-(
364 // That can disturb our "load on demand feature". But we have no other chance!
365 m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
366
367 CacheItem lIProps;
368 lIProps[PROPNAME_TYPE] <<= sType;
369 OUStringList lFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
370
371 aLock.clear();
372 // <- SAFE
373
374 OUStringList::const_iterator pIt;
375 for ( pIt = lFilters.begin();
376 pIt != lFilters.end() ;
377 ++pIt )
378 {
379 sFilter = *pIt;
380
381 // SAFE ->
382 aLock.reset();
383 try
384 {
385 CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
386 sal_Int32 nFlags = 0;
387 aFilter[PROPNAME_FLAGS] >>= nFlags;
388
389 if ((nFlags & FLAGVAL_IMPORT) == FLAGVAL_IMPORT)
390 break;
391 }
392 catch(const css::uno::Exception&)
393 { continue; }
394 aLock.clear();
395 // <- SAFE
396
397 sFilter = ::rtl::OUString();
398 }
399
400 if (sFilter.getLength())
401 {
402 rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sType ;
403 rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
404 return;
405 }
406 }
407 catch(const css::uno::Exception&)
408 {}
409 }
410
411 /*-----------------------------------------------
412 14.11.2003 12:06
413 -----------------------------------------------*/
impl_getPreselectionForType(const::rtl::OUString & sPreSelType,const css::util::URL & aParsedURL,FlatDetection & rFlatTypes)414 sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreSelType,
415 const css::util::URL& aParsedURL ,
416 FlatDetection& rFlatTypes )
417 {
418 // Can be used to suppress execution of some parts of this method
419 // if it's already clear that detected type is valid or not.
420 // It's necessary to use shared code at the end, which updates
421 // all return parameters consistent!
422 sal_Bool bBreakDetection = sal_False;
423
424 // Further we must know if it matches by pattern
425 // Every flat detected type by pattern won't be detected deep!
426 sal_Bool bMatchByPattern = sal_False;
427
428 // And we must know if a preselection must be preferred, because
429 // it matches by it's extension too.
430 sal_Bool bMatchByExtension = sal_False;
431
432 // If we e.g. collect all filters of a factory (be a forced factory preselection)
433 // we should prefer all filters of this factory, where the type match the given URL.
434 // All other types (which correspond to filters of the same factory - but don't match
435 // the URL) should be "used later" for detection and sorted at the end of our return vector
436 // rFlatTypes!
437 // => bPreferredPreselection = (matchByExtension || matchByURLPattern)
438 sal_Bool bPreferredPreselection = sal_False;
439
440 // validate type
441 ::rtl::OUString sType(sPreSelType);
442 CacheItem aType;
443 try
444 {
445 // SAFE -> --------------------------
446 ::osl::ResettableMutexGuard aLock(m_aLock);
447 aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
448 aLock.clear();
449 // <- SAFE --------------------------
450 }
451 catch(const css::container::NoSuchElementException&)
452 {
453 sType = ::rtl::OUString();
454 bBreakDetection = sal_True;
455 }
456
457 if (!bBreakDetection)
458 {
459 // We can't check a preselected type for a given stream!
460 // So we must believe, that it can work ...
461 if (aParsedURL.Complete.equalsAsciiL("private:stream", 14))
462 bBreakDetection = sal_True;
463 }
464
465 if (!bBreakDetection)
466 {
467 // extract extension from URL .. to check it case-insensitive !
468 INetURLObject aParser (aParsedURL.Main);
469 ::rtl::OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
470 sal_True ,
471 INetURLObject::DECODE_WITH_CHARSET);
472 sExtension = sExtension.toAsciiLowerCase();
473
474 // otherwise we must know, if it matches to the given URL really.
475 // especially if it matches by its extension or pattern registration.
476 OUStringList lExtensions(aType[PROPNAME_EXTENSIONS]);
477 OUStringList lURLPattern(aType[PROPNAME_URLPATTERN]);
478
479 for (OUStringList::const_iterator pIt = lExtensions.begin();
480 pIt != lExtensions.end() ;
481 ++pIt )
482 {
483 ::rtl::OUString sCheckExtension(pIt->toAsciiLowerCase());
484 if (sCheckExtension.equals(sExtension))
485 {
486 bBreakDetection = sal_True;
487 bMatchByExtension = sal_True;
488 bPreferredPreselection = sal_True;
489 break;
490 }
491 }
492
493 if (!bBreakDetection)
494 {
495 for (OUStringList::const_iterator pIt = lURLPattern.begin();
496 pIt != lURLPattern.end() ;
497 ++pIt )
498 {
499 WildCard aCheck(*pIt);
500 if (aCheck.Matches(aParsedURL.Main))
501 {
502 bBreakDetection = sal_True;
503 bMatchByPattern = sal_True;
504 bPreferredPreselection = sal_True;
505 break;
506 }
507 }
508 }
509
510 /*
511 Comment ... why the following line of code should be commented out .-)
512
513 This type does not seem to fit the requirements
514 But it's an existing and well known type.
515 At least - [because maybe the extension was missing :-( ]
516 we should try to detect this type deep ...
517 So we accept it here :-)
518
519 if (!bBreakDetection)
520 sType = ::rtl::OUString();
521 */
522 }
523
524 // if it's a valid type - set it on all return values!
525 if (sType.getLength())
526 {
527 FlatDetectionInfo aInfo;
528 aInfo.sType = sType;
529 aInfo.bMatchByExtension = bMatchByExtension;
530 aInfo.bMatchByPattern = bMatchByPattern;
531 aInfo.bPreselectedAsType = sal_True;
532
533 if (bPreferredPreselection)
534 rFlatTypes.push_front(aInfo);
535 else
536 rFlatTypes.push_back(aInfo);
537
538 return sal_True;
539 }
540
541 // not valid!
542 return sal_False;
543 }
544
545 /*-----------------------------------------------
546 14.11.2003 12:09
547 -----------------------------------------------*/
impl_getPreselectionForFilter(const::rtl::OUString & sPreSelFilter,const css::util::URL & aParsedURL,FlatDetection & rFlatTypes)548 sal_Bool TypeDetection::impl_getPreselectionForFilter(const ::rtl::OUString& sPreSelFilter,
549 const css::util::URL& aParsedURL ,
550 FlatDetection& rFlatTypes )
551 {
552 // Can be used to suppress execution of some parts of this method
553 // if it's already clear that detected filter is valid or not.
554 // It's necessary to use shared code at the end, which updates
555 // all return parameters consistent!
556 sal_Bool bBreakDetection = sal_False;
557
558 // validate filter
559 ::rtl::OUString sFilter(sPreSelFilter);
560 CacheItem aFilter;
561 try
562 {
563 // SAFE -> --------------------------
564 ::osl::ResettableMutexGuard aLock(m_aLock);
565 aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
566 aLock.clear();
567 // <- SAFE --------------------------
568 }
569 catch(const css::container::NoSuchElementException&)
570 {
571 sFilter = ::rtl::OUString();
572 bBreakDetection = sal_True;
573 }
574
575 if (!bBreakDetection)
576 {
577 // get its type and check if it matches the given URL
578 ::rtl::OUString sType;
579 aFilter[PROPNAME_TYPE] >>= sType;
580
581 bBreakDetection = impl_getPreselectionForType(sType, aParsedURL, rFlatTypes);
582
583 // not a valid type? -> not a valid filter!
584 if (!bBreakDetection)
585 sFilter = ::rtl::OUString();
586 }
587
588 // We have to mark all retrieved preselection items as "preselected by filter"!
589 FlatDetection::iterator pIt;
590 for ( pIt = rFlatTypes.begin();
591 pIt != rFlatTypes.end() ;
592 ++pIt )
593 {
594 FlatDetectionInfo& rInfo = *pIt;
595 rInfo.bPreselectedAsType = sal_False;
596 rInfo.bPreselectedByFilter = sal_True;
597 }
598
599 if (sFilter.getLength())
600 return sal_True;
601 else
602 return sal_False;
603 }
604
605 /*-----------------------------------------------
606 14.11.2003 12:11
607 -----------------------------------------------*/
impl_getPreselectionForDocumentService(const::rtl::OUString & sPreSelDocumentService,const css::util::URL & aParsedURL,FlatDetection & rFlatTypes)608 sal_Bool TypeDetection::impl_getPreselectionForDocumentService(const ::rtl::OUString& sPreSelDocumentService,
609 const css::util::URL& aParsedURL ,
610 FlatDetection& rFlatTypes )
611 {
612 // get all filters, which match to this doc service
613 OUStringList lFilters;
614 try
615 {
616 // SAFE -> --------------------------
617 ::osl::ResettableMutexGuard aLock(m_aLock);
618
619 // Attention: For executing next lines of code, We must be sure that
620 // all filters already loaded :-(
621 // That can disturb our "load on demand feature". But we have no other chance!
622 m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
623
624 CacheItem lIProps;
625 lIProps[PROPNAME_DOCUMENTSERVICE] <<= sPreSelDocumentService;
626 lFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
627
628 aLock.clear();
629 // <- SAFE --------------------------
630 }
631 catch(const css::container::NoSuchElementException&)
632 {
633 lFilters.clear();
634 }
635
636 // step over all filters, and check if its registered type
637 // match the given URL.
638 // But use temp. list of "preselected types" instead of incoming rFlatTypes list!
639 // The reason behind: we must filter the getted results. And copying of stl entries
640 // is an easier job then removing it .-)
641 FlatDetection lPreselections;
642 for (OUStringList::const_iterator pFilter = lFilters.begin();
643 pFilter != lFilters.end() ;
644 ++pFilter )
645 {
646 const ::rtl::OUString sFilter = *pFilter;
647 impl_getPreselectionForFilter(sFilter, aParsedURL, lPreselections);
648 }
649
650 // We have to mark all retrieved preselection items as "preselected by document service".
651 // Further we must ignore all preselected items, which does not match the URL!
652 FlatDetection::iterator pIt;
653 for ( pIt = lPreselections.begin();
654 pIt != lPreselections.end() ;
655 ++pIt )
656 {
657 FlatDetectionInfo& rInfo = *pIt;
658
659 /*
660 #i60158#
661 Preselection by DocumentService ...
662 How many filters (and corresponding types) must be checked ?
663 All or only the list of filters/types, which match to the given URL too ?
664 There is no final decision about this currently. So we make it "configurable" .-)
665 */
666 #ifdef IGNORE_NON_URLMATCHING_TYPES_FOR_PRESELECTION_DOCUMENTSERVICE
667 if (
668 (!rInfo.bMatchByExtension) &&
669 (!rInfo.bMatchByPattern )
670 )
671 continue;
672 #endif
673
674 rInfo.bPreselectedAsType = sal_False;
675 rInfo.bPreselectedByFilter = sal_False;
676 rInfo.bPreselectedByDocumentService = sal_True ;
677 rFlatTypes.push_back(rInfo);
678 }
679
680 return sal_True;
681 }
682
683 /*-----------------------------------------------
684 14.11.2003 12:21
685 -----------------------------------------------*/
impl_getPreselection(const css::util::URL & aParsedURL,::comphelper::MediaDescriptor & rDescriptor,FlatDetection & rFlatTypes)686 void TypeDetection::impl_getPreselection(const css::util::URL& aParsedURL ,
687 ::comphelper::MediaDescriptor& rDescriptor,
688 FlatDetection& rFlatTypes )
689 {
690 // done to be sure, that only valid results leave this function!
691 rFlatTypes.clear();
692
693 /* #i55122#
694 Sometimes we must detect files without or with real unknown extensions.
695 If it does not work /which can happen of course .-)/, the user tried to preselect
696 the right format. But some special dialogs (e.g. "Insert->Sheet From File")
697 add it's own preselection too.
698 So we have a combination of preselected values ...
699
700 Then we should prefer the most important one - set by the user.
701 And the user normally preselects a filter or type. The preselected
702 document service cames from the dialog.
703
704 Further it doesn't matter if the user preselected a filter or a document service.
705 A filter selection is always more explicit then a document service selection.
706 So it must be pereferred. An order between type and filter selection can't be discussed .-)
707 */
708
709 ::rtl::OUString sSelectedType = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
710 if (sSelectedType.getLength())
711 impl_getPreselectionForType(sSelectedType, aParsedURL, rFlatTypes);
712
713 ::rtl::OUString sSelectedFilter = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
714 if (sSelectedFilter.getLength())
715 impl_getPreselectionForFilter(sSelectedFilter, aParsedURL, rFlatTypes);
716
717 ::rtl::OUString sSelectedDoc = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(), ::rtl::OUString());
718 if (sSelectedDoc.getLength())
719 impl_getPreselectionForDocumentService(sSelectedDoc, aParsedURL, rFlatTypes);
720 }
721
722 /*-----------------------------------------------
723 03.11.2003 09:17
724 -----------------------------------------------*/
impl_detectTypeFlatAndDeep(::comphelper::MediaDescriptor & rDescriptor,const FlatDetection & lFlatTypes,sal_Bool bAllowDeep,OUStringList & rUsedDetectors,::rtl::OUString & rLastChance)725 ::rtl::OUString TypeDetection::impl_detectTypeFlatAndDeep( ::comphelper::MediaDescriptor& rDescriptor ,
726 const FlatDetection& lFlatTypes ,
727 sal_Bool bAllowDeep ,
728 OUStringList& rUsedDetectors,
729 ::rtl::OUString& rLastChance )
730 {
731 // reset it every time, so the outside code can distinguish between
732 // a set and a not set value.
733 rLastChance = ::rtl::OUString();
734 rUsedDetectors.clear();
735
736 // step over all possible types for this URL.
737 // solutions:
738 // a) no types => no detection
739 // b) deep detection not allowed => return first valid type of list (because it's the preferred or the first valid one)
740 // or(!) match by URLPattern => in such case a deep detection will be suppressed!
741 // c) type has no detect service => safe the first occurred type without a detect service
742 // as "last chance"(!). It will be used outside of this method
743 // if no further type could be detected.
744 // It must be the first one, because it can be a preferred type.
745 // Our types list was sorted by such criteria!
746 // d) detect service return a valid result => return its decision
747 // e) detect service return an invalid result
748 // or any needed information could not be
749 // getted from the cache => ignore it, and continue with search
750
751 for (FlatDetection::const_iterator pFlatIt = lFlatTypes.begin();
752 pFlatIt != lFlatTypes.end() ;
753 ++pFlatIt )
754 {
755 const FlatDetectionInfo& aFlatTypeInfo = *pFlatIt;
756 ::rtl::OUString sFlatType = aFlatTypeInfo.sType;
757
758 if (!impl_validateAndSetTypeOnDescriptor(rDescriptor, sFlatType))
759 continue;
760
761 // b)
762 if (
763 (!bAllowDeep ) ||
764 (aFlatTypeInfo.bMatchByPattern)
765 )
766 {
767 return sFlatType;
768 }
769
770 try
771 {
772 // SAFE -> ----------------------------------
773 ::osl::ResettableMutexGuard aLock(m_aLock);
774 CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sFlatType);
775 aLock.clear();
776
777 ::rtl::OUString sDetectService;
778 aType[PROPNAME_DETECTSERVICE] >>= sDetectService;
779
780 // c)
781 if (!sDetectService.getLength())
782 {
783 // accept or not accept flat types without deep detection: that's the question :-)
784 // May be there exists some states, where we have to use our LastChance feature instead
785 // of using the flat type directly.
786 // Here the list of task ID's, which was related to these lines of code:
787 // #i47159#, #i43404#, #i46494#
788
789 // a flat detected type without the chance for a deep detection ... but preselected by the user
790 // explicitly (means preselected as type or filter ... not as documentservice!)
791 // should be accepted. So the user can overrule our detection.
792 if (
793 (aFlatTypeInfo.bPreselectedAsType ) ||
794 (aFlatTypeInfo.bPreselectedByFilter)
795 )
796 return sFlatType;
797
798 // flat detected types without any registered deep detection service and not
799 // preselected by the user can be used as LAST CHANCE in case no other type could
800 // be detected. Of course only the first type without deep detector can be used.
801 // Further ones has to be ignored.
802 if (rLastChance.getLength() < 1)
803 rLastChance = sFlatType;
804
805 continue;
806 }
807
808 // don't forget to add every real asked deep detection service here.
809 // Such detectors will be ignored if may be "impl_detectTypeDeepOnly()"
810 // must be called later!
811 rUsedDetectors.push_back(sDetectService);
812 ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
813
814 // d)
815 if (sDeepType.getLength())
816 return sDeepType;
817 }
818 catch(const css::container::NoSuchElementException&)
819 {}
820 // e)
821 }
822
823 return ::rtl::OUString();
824 // <- SAFE ----------------------------------
825 }
826
827 /*-----------------------------------------------
828 03.11.2003 09:19
829 -----------------------------------------------*/
impl_detectTypeDeepOnly(::comphelper::MediaDescriptor & rDescriptor,const OUStringList & lOutsideUsedDetectors)830 ::rtl::OUString TypeDetection::impl_detectTypeDeepOnly( ::comphelper::MediaDescriptor& rDescriptor ,
831 const OUStringList& lOutsideUsedDetectors)
832 {
833 // We must know if a detect service was already used:
834 // i) in a combined flat/deep detection scenario outside or
835 // ii) in this method for a deep detection only.
836 // Reason: Such deep detection services work differently in these two modes!
837 OUStringList lInsideUsedDetectors;
838 OUStringList::const_iterator pIt;
839
840 // a)
841 // The list of "already used detect services" correspond to the list
842 // of preselected or flat detected types. But these detect services was called
843 // to check these types explicitly and return black/white ... yes/no only.
844 // Now they are called to return any possible result. But we should prefer
845 // these already used detect services against all other ones!
846 for ( pIt = lOutsideUsedDetectors.begin();
847 pIt != lOutsideUsedDetectors.end() ;
848 ++pIt )
849 {
850 const ::rtl::OUString& sDetectService = *pIt;
851 ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
852 if (sDeepType.getLength())
853 return sDeepType;
854 lInsideUsedDetectors.push_back(sDetectService);
855 }
856
857 // SAFE -> ----------------------------------
858 ::osl::ResettableMutexGuard aLock(m_aLock);
859 OUStringList lDetectors = m_rCache->getItemNames(FilterCache::E_DETECTSERVICE);
860 aLock.clear();
861 // <- SAFE ----------------------------------
862
863 // b)
864 // Sometimes it would be nice to ask a special set of detect services before
865 // any other detect service is asked. E.g. by using a preselection of a DocumentService.
866 // That's needed to prevent us from asking the "wrong application module" and
867 // opening the files into the "wrong application".
868 ::rtl::OUString sPreselDocumentService = rDescriptor.getUnpackedValueOrDefault(
869 ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(),
870 ::rtl::OUString());
871 if (sPreselDocumentService.getLength())
872 {
873 for ( pIt = lDetectors.begin();
874 pIt != lDetectors.end() ;
875 ++pIt )
876 {
877 const ::rtl::OUString& sDetectService = *pIt;
878
879 OUStringList::const_iterator pAlreadyUsed = ::std::find(lInsideUsedDetectors.begin(), lInsideUsedDetectors.end(), sDetectService);
880 if (pAlreadyUsed != lInsideUsedDetectors.end())
881 continue;
882
883 // SAFE -> --------------------------------------------------------
884 aLock.reset();
885
886 CacheItem lIProps;
887 lIProps[PROPNAME_DETECTSERVICE] <<= sDetectService;
888 OUStringList lTypes = m_rCache->getMatchingItemsByProps(FilterCache::E_TYPE, lIProps);
889
890 aLock.clear();
891 // <- SAFE --------------------------------------------------------
892
893 sal_Bool bMatchDetectorToDocumentService = sal_False;
894 OUStringList::const_iterator pIt2;
895 for ( pIt2 = lTypes.begin();
896 pIt2 != lTypes.end() ;
897 ++pIt2 )
898 {
899 const ::rtl::OUString& sType = *pIt2;
900
901 try
902 {
903 // SAFE -> ----------------------------------------------------
904 aLock.reset();
905
906 CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
907 ::rtl::OUString sFilter;
908 aType[PROPNAME_PREFERREDFILTER] >>= sFilter;
909 CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
910 ::rtl::OUString sCheckDocumentService;
911 aFilter[PROPNAME_DOCUMENTSERVICE] >>= sCheckDocumentService;
912
913 aLock.clear();
914 // <- SAFE
915
916 if (sCheckDocumentService.equals(sPreselDocumentService))
917 {
918 bMatchDetectorToDocumentService = sal_True;
919 break;
920 }
921 }
922 catch(const css::uno::Exception&)
923 { continue; }
924 }
925
926 if (bMatchDetectorToDocumentService)
927 {
928 ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
929 if (sDeepType.getLength())
930 return sDeepType;
931 lInsideUsedDetectors.push_back(sDetectService);
932 }
933 }
934 }
935
936 // c)
937 // Last chance. No "used detectors", no "preselected detectors" ... ask any existing detect services
938 // for this till know unknown format.
939 for ( pIt = lDetectors.begin();
940 pIt != lDetectors.end() ;
941 ++pIt )
942 {
943 const ::rtl::OUString& sDetectService = *pIt;
944
945 OUStringList::const_iterator pAlreadyUsed = ::std::find(lInsideUsedDetectors.begin(), lInsideUsedDetectors.end(), sDetectService);
946 if (pAlreadyUsed != lInsideUsedDetectors.end())
947 continue;
948
949 ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
950 if (sDeepType.getLength())
951 return sDeepType;
952 }
953
954 return ::rtl::OUString();
955 }
956
957 /*-----------------------------------------------
958 07.03.2005 11:13
959 -----------------------------------------------*/
impl_seekStreamToZero(comphelper::MediaDescriptor & rDescriptor)960 void TypeDetection::impl_seekStreamToZero(comphelper::MediaDescriptor& rDescriptor)
961 {
962 // try to seek to 0 ...
963 // But because XSeekable is an optional interface ... try it only .-)
964 css::uno::Reference< css::io::XInputStream > xStream = rDescriptor.getUnpackedValueOrDefault(
965 ::comphelper::MediaDescriptor::PROP_INPUTSTREAM(),
966 css::uno::Reference< css::io::XInputStream >());
967 css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY);
968 if (xSeek.is())
969 {
970 try
971 {
972 xSeek->seek(0);
973 }
974 catch(const css::uno::RuntimeException& exRun)
975 { throw exRun; }
976 catch(const css::uno::Exception&)
977 {}
978 }
979 }
980
981 /*-----------------------------------------------
982 30.10.2003 15:12
983 -----------------------------------------------*/
impl_askDetectService(const::rtl::OUString & sDetectService,::comphelper::MediaDescriptor & rDescriptor)984 ::rtl::OUString TypeDetection::impl_askDetectService(const ::rtl::OUString& sDetectService,
985 ::comphelper::MediaDescriptor& rDescriptor )
986 {
987 // Open the stream and add it to the media descriptor if this method is called for the first time.
988 // All following requests to this method will detect, that there already exists a stream .-)
989 // Attention: This method throws an exception if the stream could not be opened.
990 // It's important to break any further detection in such case.
991 // Catch it on the highest detection level only !!!
992 impl_openStream(rDescriptor);
993
994 // seek to 0 is an optional feature to be more robust against
995 // "simple implemented detect services" .-)
996 impl_seekStreamToZero(rDescriptor);
997
998 css::uno::Reference< css::document::XExtendedFilterDetection > xDetector;
999 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR;
1000
1001 // SAFE ->
1002 ::osl::ResettableMutexGuard aLock(m_aLock);
1003 xSMGR = m_xSMGR;
1004 aLock.clear();
1005 // <- SAFE
1006
1007 // Attention! If e.g. an office module was not installed sometimes we find a
1008 // registered detect service, which is referred inside the configuration ... but not really
1009 // installed. On the other side we use third party components here, which can make trouble anyway.
1010 // So we should handle errors during creation of such services more gracefully .-)
1011 xDetector = css::uno::Reference< css::document::XExtendedFilterDetection >(
1012 xSMGR->createInstance(sDetectService),
1013 css::uno::UNO_QUERY);
1014
1015 if ( ! xDetector.is())
1016 return ::rtl::OUString();
1017
1018 ::rtl::OUString sDeepType;
1019 try
1020 {
1021 // start deep detection
1022 // Don't forget to convert stl descriptor to its uno representation.
1023
1024 /* Attention!
1025 You have to use an explicit instance of this uno sequence ...
1026 Because it's used as an in out parameter. And in case of a temp. used object
1027 we will run into memory corruptions!
1028 */
1029 css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
1030 rDescriptor >> lDescriptor;
1031 sDeepType = xDetector->detect(lDescriptor);
1032 rDescriptor << lDescriptor;
1033 }
1034 catch(const css::uno::Exception&)
1035 {
1036 // We should ignore errors here.
1037 // Thrown exceptions mostly will end in crash recovery ...
1038 // But might be we find another deep detection service which can detect the same
1039 // document without a problem .-)
1040 sDeepType = ::rtl::OUString();
1041 }
1042
1043 // seek to 0 is an optional feature to be more robust against
1044 // "simple implemented detect services" .-)
1045 impl_seekStreamToZero(rDescriptor);
1046
1047 // analyze the results
1048 // a) detect service returns "" => return "" too and remove TYPE/FILTER prop from descriptor
1049 // b) returned type is unknown => return "" too and remove TYPE/FILTER prop from descriptor
1050 // c) returned type is valid => check TYPE/FILTER props inside descriptor and return the type
1051
1052 // this special helper checks for a valid type
1053 // and set right values on the descriptor!
1054 sal_Bool bValidType = impl_validateAndSetTypeOnDescriptor(rDescriptor, sDeepType);
1055 if (bValidType)
1056 return sDeepType;
1057
1058 return ::rtl::OUString();
1059 }
1060
1061 /*-----------------------------------------------
1062 17.12.2004 13:47
1063 -----------------------------------------------*/
impl_askUserForTypeAndFilterIfAllowed(::comphelper::MediaDescriptor & rDescriptor)1064 ::rtl::OUString TypeDetection::impl_askUserForTypeAndFilterIfAllowed(::comphelper::MediaDescriptor& rDescriptor)
1065 {
1066 // SAFE ->
1067 ::osl::ResettableMutexGuard aLock(m_aLock);
1068 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1069 aLock.clear();
1070 // <- SAFE
1071
1072 css::uno::Reference< css::task::XInteractionHandler > xInteraction =
1073 rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(),
1074 css::uno::Reference< css::task::XInteractionHandler >());
1075
1076 if (!xInteraction.is())
1077 return ::rtl::OUString();
1078
1079 ::rtl::OUString sURL =
1080 rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_URL(),
1081 ::rtl::OUString());
1082
1083 css::uno::Reference< css::io::XInputStream > xStream =
1084 rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_INPUTSTREAM(),
1085 css::uno::Reference< css::io::XInputStream >());
1086
1087 // Don't disturb the user for "non existing files - means empty URLs" or
1088 // if we were forced to detect a stream.
1089 // Reason behind: We must be sure to ask user for "unknown contents" only ...
1090 // and not for "missing files". Especially if detection is done by a stream only
1091 // we can't check if the stream points to an "existing content"!
1092 if (
1093 (!sURL.getLength() ) || // "non existing file" ?
1094 (!xStream.is() ) || // non existing file !
1095 (sURL.equalsIgnoreAsciiCaseAsciiL("private:stream", 14)) // not a good idea .-)
1096 )
1097 return ::rtl::OUString();
1098
1099 try
1100 {
1101 // create a new request to ask user for his decision about the usable filter
1102 ::framework::RequestFilterSelect aRequest(sURL);
1103 xInteraction->handle(aRequest.GetRequest());
1104
1105 // "Cancel" pressed? => return with error
1106 if (aRequest.isAbort())
1107 return ::rtl::OUString();
1108
1109 // "OK" pressed => verify the selected filter, get its corresponding
1110 // type and return it. (BTW: We must update the media descriptor here ...)
1111 // The user selected explicitly a filter ... but normally we are interested on
1112 // a type here only. But we must be sure, that the selected filter is used
1113 // too and no ambiguous filter registration disturb us .-)
1114
1115 ::rtl::OUString sFilter = aRequest.getFilter();
1116 if (!impl_validateAndSetFilterOnDescriptor(rDescriptor, sFilter))
1117 return ::rtl::OUString();
1118
1119 ::rtl::OUString sType;
1120 rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] >>= sType;
1121 return sType;
1122 }
1123 catch(const css::uno::Exception&)
1124 {}
1125
1126 return ::rtl::OUString();
1127 }
1128
1129 /*-----------------------------------------------
1130 10.03.2004 10:30
1131 -----------------------------------------------*/
impl_openStream(::comphelper::MediaDescriptor & rDescriptor)1132 void TypeDetection::impl_openStream(::comphelper::MediaDescriptor& rDescriptor)
1133 throw (css::uno::Exception)
1134 {
1135 sal_Bool bSuccess = sal_False;
1136 ::rtl::OUString sURL = rDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString() );
1137 sal_Bool bRequestedReadOnly = rDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_READONLY(), sal_False );
1138 if ( sURL.getLength() && ::utl::LocalFileHelper::IsLocalFile( INetURLObject( sURL ).GetMainURL( INetURLObject::NO_DECODE ) ) )
1139 {
1140 // AOO uses own file locking mechanics in case of local file
1141 bSuccess = rDescriptor.addInputStreamOwnLock();
1142 }
1143 else
1144 bSuccess = rDescriptor.addInputStream();
1145
1146 if ( !bSuccess )
1147 throw css::uno::Exception(_FILTER_CONFIG_FROM_ASCII_("Could not open stream."), static_cast< css::document::XTypeDetection* >(this));
1148
1149 if ( !bRequestedReadOnly )
1150 {
1151 // The MediaDescriptor implementation adds ReadOnly argument if the file can not be opened for writing
1152 // this argument should be either removed or an additional argument should be added so that application
1153 // can separate the case when the user explicitly requests readonly document.
1154 // The current solution is to remove it here.
1155 rDescriptor.erase( ::comphelper::MediaDescriptor::PROP_READONLY() );
1156 }
1157 }
1158
1159 /*-----------------------------------------------
1160 04.07.2003 13:47
1161 -----------------------------------------------*/
impl_removeTypeFilterFromDescriptor(::comphelper::MediaDescriptor & rDescriptor)1162 void TypeDetection::impl_removeTypeFilterFromDescriptor(::comphelper::MediaDescriptor& rDescriptor)
1163 {
1164 ::comphelper::MediaDescriptor::iterator pItType = rDescriptor.find(::comphelper::MediaDescriptor::PROP_TYPENAME() );
1165 ::comphelper::MediaDescriptor::iterator pItFilter = rDescriptor.find(::comphelper::MediaDescriptor::PROP_FILTERNAME());
1166 if (pItType != rDescriptor.end())
1167 rDescriptor.erase(pItType);
1168 if (pItFilter != rDescriptor.end())
1169 rDescriptor.erase(pItFilter);
1170 }
1171
1172 /*-----------------------------------------------
1173 14.10.2003 11:15
1174 -----------------------------------------------*/
impl_validateAndSetTypeOnDescriptor(::comphelper::MediaDescriptor & rDescriptor,const::rtl::OUString & sType)1175 sal_Bool TypeDetection::impl_validateAndSetTypeOnDescriptor( ::comphelper::MediaDescriptor& rDescriptor,
1176 const ::rtl::OUString& sType )
1177 {
1178 // SAFE ->
1179 ::osl::ResettableMutexGuard aLock(m_aLock);
1180 if (m_rCache->hasItem(FilterCache::E_TYPE, sType))
1181 {
1182 rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
1183 return sal_True;
1184 }
1185 aLock.clear();
1186 // <- SAFE
1187
1188 // remove all related informations from the descriptor
1189 impl_removeTypeFilterFromDescriptor(rDescriptor);
1190 return sal_False;
1191 }
1192
1193 /*-----------------------------------------------
1194 04.07.2003 14:01
1195 -----------------------------------------------*/
impl_validateAndSetFilterOnDescriptor(::comphelper::MediaDescriptor & rDescriptor,const::rtl::OUString & sFilter)1196 sal_Bool TypeDetection::impl_validateAndSetFilterOnDescriptor( ::comphelper::MediaDescriptor& rDescriptor,
1197 const ::rtl::OUString& sFilter )
1198 {
1199 try
1200 {
1201 // SAFE ->
1202 ::osl::ResettableMutexGuard aLock(m_aLock);
1203
1204 CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
1205 ::rtl::OUString sType;
1206 aFilter[PROPNAME_TYPE] >>= sType;
1207 CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
1208
1209 aLock.clear();
1210 // <- SAFE
1211
1212 // found valid type and filter => set it on the given descriptor
1213 rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sType ;
1214 rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
1215 return sal_True;
1216 }
1217 catch(const css::container::NoSuchElementException&){}
1218
1219 // remove all related informations from the descriptor
1220 impl_removeTypeFilterFromDescriptor(rDescriptor);
1221 return sal_False;
1222 }
1223
1224 /*-----------------------------------------------
1225 03.07.2003 10:36
1226 -----------------------------------------------*/
impl_getImplementationName()1227 ::rtl::OUString TypeDetection::impl_getImplementationName()
1228 {
1229 return ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.TypeDetection");
1230 }
1231
1232 /*-----------------------------------------------
1233 03.07.2003 11:27
1234 -----------------------------------------------*/
impl_getSupportedServiceNames()1235 css::uno::Sequence< ::rtl::OUString > TypeDetection::impl_getSupportedServiceNames()
1236 {
1237 css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
1238 lServiceNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection");
1239 return lServiceNames;
1240 }
1241
1242 /*-----------------------------------------------
1243 09.07.2003 08:02
1244 -----------------------------------------------*/
impl_createInstance(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)1245 css::uno::Reference< css::uno::XInterface > SAL_CALL TypeDetection::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
1246 {
1247 TypeDetection* pNew = new TypeDetection(xSMGR);
1248 return css::uno::Reference< css::uno::XInterface >(static_cast< css::document::XTypeDetection* >(pNew), css::uno::UNO_QUERY);
1249 }
1250
1251 } // namespace config
1252 } // namespace filter
1253