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