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