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 #ifndef __FILTER_CONFIG_TYPEDETECTION_HXX_
24 #define __FILTER_CONFIG_TYPEDETECTION_HXX_
25 
26 //_______________________________________________
27 // includes
28 
29 #include "basecontainer.hxx"
30 #include <com/sun/star/document/XTypeDetection.hpp>
31 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
32 #include <comphelper/mediadescriptor.hxx>
33 #include <cppuhelper/implbase1.hxx>
34 
35 //_______________________________________________
36 // namespace
37 
38 namespace filter{
39     namespace config{
40 
41 namespace css = ::com::sun::star;
42 
43 //_______________________________________________
44 // definitions
45 
46 //_______________________________________________
47 
48 /** @short      implements the service <type scope="com.sun.star.document">TypeDetection</type>.
49  */
50 class TypeDetection : public ::cppu::ImplInheritanceHelper1< BaseContainer                 ,
51                                                              css::document::XTypeDetection >
52 {
53     //-------------------------------------------
54     // native interface
55 
56     public:
57 
58         //---------------------------------------
59         // ctor/dtor
60 
61         /** @short  standard ctor to connect this interface wrapper to
62                     the global filter cache instance ...
63 
64             @param  xSMGR
65                     reference to the uno service manager, which created this service instance.
66          */
67         TypeDetection(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
68 
69         //---------------------------------------
70 
71         /** @short  standard dtor.
72          */
73         virtual ~TypeDetection();
74 
75     //-------------------------------------------
76     // private helper
77 
78     private:
79 
80         //---------------------------------------
81         /** TODO document me */
82         sal_Bool impl_getPreselectionForType(const ::rtl::OUString& sPreSelType,
83                                              const css::util::URL&  aParsedURL ,
84                                                    FlatDetection&   rFlatTypes );
85 
86         //---------------------------------------
87         /** TODO document me */
88         sal_Bool impl_getPreselectionForFilter(const ::rtl::OUString& sPreSelFilter,
89                                                const css::util::URL&  aParsedURL   ,
90                                                      FlatDetection&   rFlatTypes   );
91 
92         //---------------------------------------
93         /** TODO document me */
94         sal_Bool impl_getPreselectionForDocumentService(const ::rtl::OUString& sPreSelDocumentService,
95                                                          const css::util::URL& aParsedURL            ,
96                                                                FlatDetection&  rFlatTypes            );
97 
98         //---------------------------------------
99 
100         /** @short      check if a filter or a type was preselected inside the given
101                         MediaDescriptor and validate this information.
102 
103             @descr      Only in case the preselected filter exists and its type registration
104                         seems to be usefully, it would be used realy as valid type detection
105                         result. This method doesnt make any deep detection here. It checks only
106                         if the preselection match to the URL by an URLPattern.
107                         This information has to be added to the given rFlatTypes list too.
108                         The outside code can use it to supress a deep detection then in general.
109                         Because pattern are defined as non detectable at all!
110 
111             @param      pDescriptor
112                         provides any easy-to-use stl interface to the MediaDescriptor.
113                         Note : Its content will be adapted to returned result of this method.
114                         Means: The type/filter entries of it will be actualized or removed.
115 
116             @param      rFlatTypes
117                         the preselected type (or the registered type of a preselected filter)
118                         will be added here as first(!) element. Further we have to provide the
119                         information, if this type match to the given URL by its URLPattern
120                         registration.
121          */
122         void impl_getPreselection(const css::util::URL&                aParsedURL ,
123                                         ::comphelper::MediaDescriptor& rDescriptor,
124                                         FlatDetection&                 rFlatTypes );
125 
126         //---------------------------------------
127 
128         /** @short      make a combined flat/deep type detection
129 
130             @descr      It steps over all flat detected types (given by the parameter lFlatTypes),
131                         try it and search for most suitable one.
132                         The specified MediaDescriptor will be patched, so it contain
133                         the right values everytime. Using of any deep detection service
134                         can be enabled/disabled. And last but not least: If the results
135                         wont be realy clear (because a flat detected type has no deep
136                         detection service), a "sugested" type name will be returned as "rLastChance".
137                         It can be used after e.g. all well known deep detection services
138                         was used without getting any result. Then this "last-chance-type"
139                         should be returned. Of course using of it can fail too ... but its a try :-)
140 
141                         As an optimization - this method collects the names of all used deep
142                         detection services. This information can be usefull inside the may be
143                         afterwards called method "impl_detectTypeDeepOnly()"!
144 
145             @param      rDescriptor
146                         provides any easy-to-use stl interface to the MediaDescriptor.
147                         Note : Its content will be adapted to returned result of this method.
148                         Means: The type/filter entries of it will be actualized or removed from it.
149 
150             @param      lFlatTypes
151                         a list of all flat detected types, which should be checked here.
152                         No other types are allowed here!
153 
154             @param      rLastChance
155                         the internal name of a "suggested type" ... (see before)
156                         Note: it will be reseted to an empty string everytimes. So
157                         a set value of "rLastChance" can be detected outside very easy.
158 
159             @param      rUsedDetectors
160                         used as [out] parameter. It contains a list of names of all deep
161                         detection services, which was used inside this method.
162                         Such detectors can be ignored later if "impl_detectTypeDeepOnly()"
163                         is called.
164 
165             @param      bAllowDeep
166                         enable/disable using of a might existing deep detection service.
167 
168             @return     The internal name of a detected type.
169                         An empty value if detection failed. .... but see rLastChance
170                         for additional returns!
171          */
172         ::rtl::OUString impl_detectTypeFlatAndDeep(      ::comphelper::MediaDescriptor& rDescriptor   ,
173                                                    const FlatDetection&                 lFlatTypes    ,
174                                                          sal_Bool                       bAllowDeep    ,
175                                                          OUStringList&                  rUsedDetectors,
176                                                          ::rtl::OUString&               rLastChance   );
177 
178         //---------------------------------------
179 
180         /** @short      make a deep type detection only
181 
182             @descr      It steps over all well known deep detection services
183                         and check her results. The first positive result will be
184                         used for return. Its more a "try and error" algorithm then
185                         a real type detection and will be used if a flat detection
186                         cant work realy ... e.g. if the extension of an URL is
187                         missing or wrong.
188 
189             @param      rDescriptor
190                         provides any easy-to-use stl interface to the MediaDescriptor.
191                         Note : Its content will be adapted to returned result of this method.
192                         Means: The type/filter entries of it will be actualized or removed from it.
193 
194             @param      rUsedDetectors
195                         It contains a list of names of all deep detection services,
196                         which was already used inside the method "impl_detectTypeFlatAndDeep()"!
197                         Such detectors must be ignored here!
198 
199             @return     The internal name of a detected type.
200                         An empty value if detection failed.
201          */
202         ::rtl::OUString impl_detectTypeDeepOnly(      ::comphelper::MediaDescriptor& rDescriptor   ,
203                                                 const OUStringList&                  rUsedDetectors);
204 
205         //---------------------------------------
206 
207         /** @short      seek a might existing stream to position 0.
208 
209             @descr      This is an optinal action to be more robust
210                         in case any detect service doesnt make this seek ...
211                         Normaly it's part of any called detect service or filter ...
212                         but sometimes it's not done there.
213 
214             @param      rDescriptor
215                         a stl representation of the MediaDescriptor as in/out parameter.
216          */
217         void impl_seekStreamToZero(comphelper::MediaDescriptor& rDescriptor);
218 
219         //---------------------------------------
220 
221         /** @short      make deep type detection for a specified
222                         detect service (threadsafe!).
223 
224             @descr      It creates the right uno service, prepare the
225                         needed MediaDescriptor, call ths right interfaces,
226                         and return the results.
227 
228             @attention  The results (means type and corresponding filter)
229                         are already part of the in/out parameter pDescriptor.
230                         (in case they was valid).
231 
232             @param      sDetectService
233                         uno service name of the detect service.
234 
235             @param      rDescriptor
236                         a stl representation of the MediaDescriptor as in/out parameter.
237          */
238         ::rtl::OUString impl_askDetectService(const ::rtl::OUString&               sDetectService,
239                                                     ::comphelper::MediaDescriptor& rDescriptor   );
240 
241         //---------------------------------------
242 
243         /** @short      try to find an interaction handler and
244                         ask him to select a possible filter for
245                         this unknown format.
246 
247             @descr      If the user select a filter, it will be used as return value
248                         without further checking against the given file content!
249 
250             @param      rDescriptor
251                         a stl representation of the MediaDescriptor as in/out parameter.
252 
253             @return     [string]
254                         a valid type name or an empty string if user canceled interaction.
255          */
256         ::rtl::OUString impl_askUserForTypeAndFilterIfAllowed(::comphelper::MediaDescriptor& rDescriptor);
257 
258         //---------------------------------------
259 
260         /** @short      check if an input stream is already part of the
261                         given MediaDesciptor and creates a new one if neccessary.
262 
263             @attention  This method does further something special!
264                         <ul>
265                             <li>
266                                 If the given URL seem to be a streamable content, but creation of the stream
267                                 failed (might by an IOException), this method throws an exception.
268                                 (May be an existing interaction handler must be called here too ...)
269                                 The whole detection must be interrupted then and the interface method queryTypeByDescriptor()
270                                 must return an empty type name value.
271 
272                                 That prevent us against multiple handling of the same error more then ones
273                                 (e.g. if we ask all detect services as fallback ...).
274                             </li>
275                             <li>
276                                 In case the stream already exists inside the descriptor this method does nothing.
277                             </li>
278                             <li>
279                                 In case the stream does not exists but can be created successfully, the stream will
280                                 be added to the descriptor.
281                             </li>
282                         </ul>
283 
284             @param      rDescriptor
285                         provides any easy-to-use stl interface to the MediaDescriptor.
286                         Note : Its content will be adapted to returned result of this method.
287                         Means: The stream will be added to it.
288 
289             @throw      Any suitable exception if stream should be opened but operation was not sucessfull.
290                         Note: If an interactionHandler is part of the given descriptor too, it was already used.
291                         Means: let the exception pass trough the top most interface method!
292          */
293         void impl_openStream(::comphelper::MediaDescriptor& rDescriptor)
294             throw (css::uno::Exception);
295 
296         //---------------------------------------
297 
298         /** @short      validate the specified type and its relation ships
299                         and set all needed informations related to this type
300                         in the specified descriptor.
301 
302             @descr      Related informations are: - corresponding filter
303                                                   - media type
304                                                   - ...
305 
306             @param      rDescriptor
307                         provides access to the outside MediaDescriptor.
308 
309             @param      sType
310                         the name of the type, which should be set on the descriptor.
311                         Can be empty to remove any related value from the descriptor!
312 
313             @return     TRUE the specified type and its registrations was valid(!) and
314                         could be set on the descriptor.
315          */
316         sal_Bool impl_validateAndSetTypeOnDescriptor(      ::comphelper::MediaDescriptor& rDescriptor,
317                                                      const ::rtl::OUString&               sType      );
318 
319         //---------------------------------------
320 
321         /** @short      validate the specified filter and its relation ships
322                         and set all needed informations related to this filter
323                         in the specified descriptor.
324 
325             @descr      Related informations are: - corresponding type
326                                                   - ...
327 
328             @param      rDescriptor
329                         provides access to the outside MediaDescriptor.
330 
331             @param      sFilter
332                         the name of the filter, which should be set on the descriptor.
333                         Can be empty to remove any related value from the descriptor!
334 
335             @return     TRUE the specified type and its registrations was valid(!) and
336                         could be set on the descriptor.
337          */
338         sal_Bool impl_validateAndSetFilterOnDescriptor(      ::comphelper::MediaDescriptor& rDescriptor,
339                                                        const ::rtl::OUString&               sFilter    );
340 
341         //---------------------------------------
342 
343         /** @short      remove anythimng related to a TYPE/FILTER entry from the
344                         specified MediaDescriptor.
345 
346             @descr      This method works together with impl_validateAndSetTypeOnDescriptor()/
347                         impl_validateAndSetFilterOnDescriptor(). All informations, which can be
348                         set by these two operations must be "removeable" by this method.
349 
350             @param      rDescriptor
351                         reference to the MediaDescriptor (represented by an easy-to-use
352                         stl interface!), which should be patched.
353          */
354         void impl_removeTypeFilterFromDescriptor(::comphelper::MediaDescriptor& rDescriptor);
355 
356         //---------------------------------------
357 
358         /** @short      search the best suitable filter for the given type
359                         and add it into the media descriptor.
360 
361             @descr      Normaly this is a type detection only ...
362                         but for some special features we must overwrite our detection
363                         because a file must be loaded into a special (means preselected)
364                         application.
365 
366                         E.g. CSV/TXT format are sometimes ugly to handle .-)
367 
368                         Note: If the descriptor already include a filter
369                         (may be selected by a FilterSelect interaction or preselected
370                         by the user itself) ... we dont change that here !
371 
372             @param      rDescriptor
373                         reference to the MediaDescriptor (represented by an easy-to-use
374                         stl interface!), which should be patched.
375 
376             @param      sType
377                         the internal type name, where we search a filter for.
378                         Used as IN/OUT parameter so we can overrule the detection result for
379                         types too !
380 
381             @note       #i60158#
382                         sometimes our text ascii and our csv filter cant work together.
383                         Then we overwrite our detection hardly.
384                         sType param is used as out parameter then too ... and
385                         rDescriptor will be changed by selecting another filter.
386                         (see code)
387          */
388         void impl_checkResultsAndAddBestFilter(::comphelper::MediaDescriptor& rDescriptor,
389                                                ::rtl::OUString&               sType      );
390 
391     //-------------------------------------------
392     // uno interface
393 
394     public:
395 
396         //---------------------------------------
397         // XTypeDetection
398 
399         virtual ::rtl::OUString SAL_CALL queryTypeByURL(const ::rtl::OUString& sURL)
400             throw (css::uno::RuntimeException);
401 
402         virtual ::rtl::OUString SAL_CALL queryTypeByDescriptor(css::uno::Sequence< css::beans::PropertyValue >& lDescriptor,
403                                                                sal_Bool                                         bAllowDeep )
404             throw (css::uno::RuntimeException);
405 
406     //-------------------------------------------
407     // static uno helper!
408 
409     public:
410 
411         //---------------------------------------
412 
413         /** @short  return the uno implementation name of this class.
414 
415             @descr  Because this information is used at several places
416                     (and mostly an object instance of this class is not possible)
417                     its implemented as a static function!
418 
419             @return The fix uno implementation name of this class.
420          */
421         static ::rtl::OUString impl_getImplementationName();
422 
423         //---------------------------------------
424 
425         /** @short  return the list of supported uno services of this class.
426 
427             @descr  Because this information is used at several places
428                     (and mostly an object instance of this class is not possible)
429                     its implemented as a static function!
430 
431             @return The fix list of uno services supported by this class.
432          */
433         static css::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames();
434 
435         //---------------------------------------
436 
437         /** @short  return a new intsnace of this class.
438 
439             @descr  This method is used by the uno service manager, to create
440                     a new instance of this service if needed.
441 
442             @param  xSMGR
443                     reference to the uno service manager, which require
444                     this new instance. It should be passed to the new object
445                     so it can be used internaly to create own needed uno resources.
446 
447             @return The new instance of this service as an uno reference.
448          */
449         static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
450 };
451 
452     } // namespace config
453 } // namespace filter
454 
455 #endif // __FILTER_CONFIG_TYPEDETECTION_HXX_
456