LibreOffice Module filter (master) 1
filtercache.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <memory>
23#include "filtercache.hxx"
24#include "constant.hxx"
26
27/*TODO see using below ... */
28#define AS_ENABLE_FILTER_UINAMES
29
30#include <com/sun/star/configuration/theDefaultProvider.hpp>
31#include <com/sun/star/util/XChangesBatch.hpp>
32#include <com/sun/star/container/XNameContainer.hpp>
33#include <com/sun/star/lang/XSingleServiceFactory.hpp>
34#include <com/sun/star/beans/NamedValue.hpp>
35#include <com/sun/star/beans/XMultiPropertySet.hpp>
36#include <com/sun/star/beans/XProperty.hpp>
37#include <com/sun/star/beans/PropertyValue.hpp>
38#include <com/sun/star/beans/Property.hpp>
39#include <com/sun/star/beans/PropertyAttribute.hpp>
40#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
43
46#include <rtl/ustrbuf.hxx>
47#include <rtl/uri.hxx>
48#include <sal/log.hxx>
49#include <tools/urlobj.hxx>
50#include <tools/wldcrd.hxx>
52
53#include <officecfg/Setup.hxx>
54#include <o3tl/string_view.hxx>
55
56
57namespace filter::config{
58
60 : m_eFillState(E_CONTAINS_NOTHING )
61{
62 int i = 0;
63 OUString sStandardProps[10];
64
65 sStandardProps[i++] = PROPNAME_USERDATA;
66 sStandardProps[i++] = PROPNAME_TEMPLATENAME;
67 sStandardProps[i++] = PROPNAME_ENABLED;
68 // E_READ_UPDATE only above
69 sStandardProps[i++] = PROPNAME_TYPE;
70 sStandardProps[i++] = PROPNAME_FILEFORMATVERSION;
71 sStandardProps[i++] = PROPNAME_UICOMPONENT;
72 sStandardProps[i++] = PROPNAME_FILTERSERVICE;
73 sStandardProps[i++] = PROPNAME_DOCUMENTSERVICE;
74 sStandardProps[i++] = PROPNAME_EXPORTEXTENSION;
75 sStandardProps[i++] = PROPNAME_FLAGS; // must be last.
76 assert(i == SAL_N_ELEMENTS(sStandardProps));
77
78 // E_READ_NOTHING -> creative nothingness.
80 css::uno::Sequence< OUString >(sStandardProps + 3, 7);
82 css::uno::Sequence< OUString >(sStandardProps, 3);
84 css::uno::Sequence< OUString >(sStandardProps,
85 SAL_N_ELEMENTS(sStandardProps));
86
87 i = 0;
88 OUString sTypeProps[7];
89 sTypeProps[i++] = PROPNAME_MEDIATYPE;
90 // E_READ_UPDATE only above
91 sTypeProps[i++] = PROPNAME_PREFERREDFILTER;
92 sTypeProps[i++] = PROPNAME_DETECTSERVICE;
93 sTypeProps[i++] = PROPNAME_URLPATTERN;
94 sTypeProps[i++] = PROPNAME_EXTENSIONS;
95 sTypeProps[i++] = PROPNAME_PREFERRED;
96 sTypeProps[i++] = PROPNAME_CLIPBOARDFORMAT;
97 assert(i == SAL_N_ELEMENTS(sTypeProps));
98
99 // E_READ_NOTHING -> more creative nothingness.
101 css::uno::Sequence< OUString >(sTypeProps + 1, 6);
103 css::uno::Sequence< OUString >(sTypeProps, 1);
105 css::uno::Sequence< OUString >(sTypeProps,
106 SAL_N_ELEMENTS(sTypeProps));
107}
108
109
111{
112 if (m_xTypesChglisteners.is())
113 m_xTypesChglisteners->stopListening();
114 if (m_xFiltersChgListener.is())
115 m_xFiltersChgListener->stopListening();
116}
117
118
119std::unique_ptr<FilterCache> FilterCache::clone() const
120{
121 // SAFE -> ----------------------------------
122 std::unique_lock aGuard(m_aMutex);
123
124 auto pClone = std::make_unique<FilterCache>();
125
126 // Don't copy the configuration access points here.
127 // They will be created on demand inside the cloned instance,
128 // if they are needed.
129
130 pClone->m_lTypes = m_lTypes;
131 pClone->m_lFilters = m_lFilters;
132 pClone->m_lFrameLoaders = m_lFrameLoaders;
133 pClone->m_lContentHandlers = m_lContentHandlers;
134 pClone->m_lExtensions2Types = m_lExtensions2Types;
135 pClone->m_lURLPattern2Types = m_lURLPattern2Types;
136
137 pClone->m_sActLocale = m_sActLocale;
138
139 pClone->m_eFillState = m_eFillState;
140
141 pClone->m_lChangedTypes = m_lChangedTypes;
142 pClone->m_lChangedFilters = m_lChangedFilters;
143 pClone->m_lChangedFrameLoaders = m_lChangedFrameLoaders;
144 pClone->m_lChangedContentHandlers = m_lChangedContentHandlers;
145
146 return pClone;
147 // <- SAFE ----------------------------------
148}
149
150
152{
153 // SAFE -> ----------------------------------
154 std::unique_lock aGuard(m_aMutex);
155
156 // a)
157 // Don't copy the configuration access points here!
158 // We must use our own ones...
159
160 // b)
161 // Further we can ignore the uno service manager.
162 // We should already have a valid instance.
163
164 // c)
165 // Take over only changed items!
166 // Otherwise we risk the following scenario:
167 // c1) clone_1 contains changed filters
168 // c2) clone_2 container changed types
169 // c3) clone_1 take over changed filters and unchanged types
170 // c4) clone_2 take over unchanged filters(!) and changed types(!)
171 // c5) c4 overwrites c3!
172
173 if (!rClone.m_lChangedTypes.empty())
174 m_lTypes = rClone.m_lTypes;
175 if (!rClone.m_lChangedFilters.empty())
176 m_lFilters = rClone.m_lFilters;
177 if (!rClone.m_lChangedFrameLoaders.empty())
179 if (!rClone.m_lChangedContentHandlers.empty())
181
182 m_lChangedTypes.clear();
183 m_lChangedFilters.clear();
186
187 m_sActLocale = rClone.m_sActLocale;
188
189 m_eFillState = rClone.m_eFillState;
190
191 // renew all dependencies and optimizations
192 // Because we can't be sure, that changed filters on one clone
193 // and changed types of another clone work together.
194 // But here we can check against the later changes...
196 // <- SAFE ----------------------------------
197}
198
200{
201 // SAFE -> ----------------------------------
202 std::unique_lock aGuard(m_aMutex);
203
204 // check if required fill state is already reached ...
205 // There is nothing to do then.
206 if ((m_eFillState & eRequired) == eRequired)
207 return;
208
209 // Otherwise load the missing items.
210
211
212 // a) load some const values from configuration.
213 // These values are needed there for loading
214 // config items ...
215 // Further we load some std items from the
216 // configuration so we can try to load the first
217 // office document with a minimal set of values.
219 {
221 if (m_sActLocale.isEmpty())
222 {
224 }
225
226 // Support the old configuration support. Read it only one times during office runtime!
227 impl_readOldFormat(aGuard);
228 }
229
230
231 // b) If the required fill state was not reached
232 // but std values was already loaded ...
233 // we must load some further missing items.
234 impl_load(aGuard, eRequired);
235 // <- SAFE
236}
237
239{
240 // SAFE ->
241 std::unique_lock aGuard(m_aMutex);
242 return ((m_eFillState & eState) == eState);
243 // <- SAFE
244}
245
246
250{
251 // SAFE ->
252 std::unique_lock aGuard(m_aMutex);
253
254 // search for right list
255 // An exception is thrown - "eType" is unknown.
256 // => rList will be valid everytimes next line is reached.
257 const CacheItemList& rList = impl_getItemList(aGuard, eType);
258
259 std::vector<OUString> lKeys;
260 lKeys.reserve(rList.size());
261
262 // search items, which provides all needed properties of set "lIProps"
263 // but not of set "lEProps"!
264 for (auto const& elem : rList)
265 {
266 if (
267 (elem.second.haveProps(lIProps) ) &&
268 (elem.second.dontHaveProps(lEProps))
269 )
270 {
271 lKeys.push_back(elem.first);
272 }
273 }
274
275 return lKeys;
276 // <- SAFE
277}
278
279
281{
282 // SAFE ->
283 std::unique_lock aGuard(m_aMutex);
284
285 // search for right list
286 // An exception is thrown - "eType" is unknown.
287 // => rList will be valid everytimes next line is reached.
288 const CacheItemList& rList = impl_getItemList(aGuard, eType);
289
290 return !rList.empty();
291 // <- SAFE
292}
293
294
295std::vector<OUString> FilterCache::getItemNames(EItemType eType) const
296{
297 // SAFE ->
298 std::unique_lock aGuard(m_aMutex);
299 return getItemNames(aGuard, eType);
300 // <- SAFE
301}
302
303std::vector<OUString> FilterCache::getItemNames(std::unique_lock<std::mutex>& rGuard, EItemType eType) const
304{
305 // search for right list
306 // An exception is thrown - "eType" is unknown.
307 // => rList will be valid everytimes next line is reached.
308 const CacheItemList& rList = impl_getItemList(rGuard, eType);
309
310 std::vector<OUString> lKeys;
311 for (auto const& elem : rList)
312 {
313 lKeys.push_back(elem.first);
314 }
315 return lKeys;
316}
317
318
320 const OUString& sItem)
321{
322 // SAFE ->
323 std::unique_lock aGuard(m_aMutex);
324
325 // search for right list
326 // An exception is thrown - "eType" is unknown.
327 // => rList will be valid everytimes next line is reached.
328 const CacheItemList& rList = impl_getItemList(aGuard, eType);
329
330 // if item could not be found - check if it can be loaded
331 // from the underlying configuration layer. Might it was not already
332 // loaded into this FilterCache object before.
333 CacheItemList::const_iterator pIt = rList.find(sItem);
334 if (pIt != rList.end())
335 return true;
336
337 try
338 {
339 impl_loadItemOnDemand(aGuard, eType, sItem);
340 // no exception => item could be loaded!
341 return true;
342 }
343 catch(const css::container::NoSuchElementException&)
344 {}
345
346 return false;
347 // <- SAFE
348}
349
350
352 const OUString& sItem)
353{
354 // SAFE ->
355 std::unique_lock aGuard(m_aMutex);
356
357 CacheItem aItem = impl_getItem(aGuard, eType, sItem);
358 // <- SAFE
359 return aItem;
360}
361
362
363CacheItem& FilterCache::impl_getItem( std::unique_lock<std::mutex>& rGuard,
364 EItemType eType,
365 const OUString& sItem)
366{
367 // search for right list
368 // An exception is thrown if "eType" is unknown.
369 // => rList will be valid everytimes next line is reached.
370 CacheItemList& rList = impl_getItemList(rGuard, eType);
371
372 // check if item exists ...
373 CacheItemList::iterator pIt = rList.find(sItem);
374 if (pIt == rList.end())
375 {
376 // ... or load it on demand from the
377 // underlying configuration layer.
378 // Note: NoSuchElementException is thrown automatically here if
379 // item could not be loaded!
380 pIt = impl_loadItemOnDemand(rGuard, eType, sItem);
381 }
382
383 /* Workaround for #137955#
384 Draw types and filters are installed ... but draw was disabled during setup.
385 We must suppress accessing these filters. Otherwise the office can crash.
386 Solution for the next major release: do not install those filters !
387 */
388 if (eType == E_FILTER)
389 {
390 CacheItem& rFilter = pIt->second;
391 OUString sDocService;
392 rFilter[PROPNAME_DOCUMENTSERVICE] >>= sDocService;
393
394 // In Standalone-Impress the module WriterWeb is not installed
395 // but it is there to load help pages
396 bool bIsHelpFilter = sItem == "writer_web_HTML_help";
397
398 if ( !bIsHelpFilter && !impl_isModuleInstalled(rGuard, sDocService) )
399 {
400 OUString sMsg("The requested filter '" + sItem +
401 "' exists ... but it should not; because the corresponding LibreOffice module was not installed.");
402 throw css::container::NoSuchElementException(sMsg, css::uno::Reference< css::uno::XInterface >());
403 }
404 }
405
406 return pIt->second;
407}
408
409
411 const OUString& sItem)
412{
413 // SAFE ->
414 std::unique_lock aGuard(m_aMutex);
415
416 // search for right list
417 // An exception is thrown - "eType" is unknown.
418 // => rList will be valid everytimes next line is reached.
419 CacheItemList& rList = impl_getItemList(aGuard, eType);
420
421 CacheItemList::iterator pItem = rList.find(sItem);
422 if (pItem == rList.end())
423 pItem = impl_loadItemOnDemand(aGuard, eType, sItem); // throws NoSuchELementException!
424 rList.erase(pItem);
425
427}
428
429
431 const OUString& sItem ,
432 const CacheItem& aValue)
433{
434 // SAFE ->
435 std::unique_lock aGuard(m_aMutex);
436
437 // search for right list
438 // An exception is thrown - "eType" is unknown.
439 // => rList will be valid everytimes next line is reached.
440 CacheItemList& rList = impl_getItemList(aGuard, eType);
441
442 // name must be part of the property set too ... otherwise our
443 // container query can't work correctly
444 CacheItem aItem = aValue;
445 aItem[PROPNAME_NAME] <<= sItem;
447
448 // remove implicit properties as e.g. FINALIZED or MANDATORY
449 // They can't be saved here and must be read on demand later, if they are needed.
451
452 rList[sItem] = aItem;
453
455}
456
457
459 const OUString& sItem)
460{
461 // SAFE ->
462 std::unique_lock aGuard(m_aMutex);
463 impl_loadItemOnDemand(aGuard, eType, sItem);
464}
465
466
468 const OUString& sItem)
469{
470 // SAFE ->
471 std::unique_lock aGuard(m_aMutex);
472
473 const CacheItem& rItem = impl_getItem(aGuard, eType, sItem);
474
475 // Note: Opening of the configuration layer throws some exceptions
476 // if it failed. So we mustn't check any reference here...
477 css::uno::Reference< css::container::XNameAccess > xPackage;
478 css::uno::Reference< css::container::XNameAccess > xSet;
479 switch(eType)
480 {
481 case E_TYPE :
482 {
483 xPackage.set(impl_openConfig(aGuard, E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
484 xPackage->getByName(CFGSET_TYPES) >>= xSet;
485 }
486 break;
487
488 case E_FILTER :
489 {
490 xPackage.set(impl_openConfig(aGuard, E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
491 xPackage->getByName(CFGSET_FILTERS) >>= xSet;
492 }
493 break;
494
495 case E_FRAMELOADER :
496 {
497 /* TODO
498 Hack -->
499 The default frame loader can't be located inside the normal set of frame loaders.
500 It's an atomic property inside the misc cfg package. So we can't retrieve the information
501 about FINALIZED and MANDATORY very easy ... :-(
502 => set it to readonly/required everytimes :-)
503 */
504 css::uno::Any aDirectValue = impl_getDirectCFGValue(aGuard, CFGDIRECTKEY_DEFAULTFRAMELOADER);
505 OUString sDefaultFrameLoader;
506 if (
507 (aDirectValue >>= sDefaultFrameLoader) &&
508 (!sDefaultFrameLoader.isEmpty() ) &&
509 (sItem == sDefaultFrameLoader )
510 )
511 {
512 css::uno::Sequence aProps = rItem.getAsPackedPropertyValueList(true, true);
513 return css::uno::Any(aProps);
514 }
515 /* <-- HACK */
516
517 xPackage.set(impl_openConfig(aGuard, E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
518 xPackage->getByName(CFGSET_FRAMELOADERS) >>= xSet;
519 }
520 break;
521
522 case E_CONTENTHANDLER :
523 {
524 xPackage.set(impl_openConfig(aGuard, E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
525 xPackage->getByName(CFGSET_CONTENTHANDLERS) >>= xSet;
526 }
527 break;
528 default: break;
529 }
530
531 bool bFinalized, bMandatory;
532 try
533 {
534 css::uno::Reference< css::beans::XProperty > xItem;
535 xSet->getByName(sItem) >>= xItem;
536 css::beans::Property aDescription = xItem->getAsProperty();
537
538 bFinalized = ((aDescription.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
539 bMandatory = ((aDescription.Attributes & css::beans::PropertyAttribute::REMOVABLE) != css::beans::PropertyAttribute::REMOVABLE);
540
541 }
542 catch(const css::container::NoSuchElementException&)
543 {
544 /* Ignore exceptions for missing elements inside configuration.
545 May by the following reason exists:
546 - The item does not exists inside the new configuration package org.openoffice.TypeDetection - but
547 we got it from the old package org.openoffice.Office/TypeDetection. We don't migrate such items
548 automatically to the new format. Because it will disturb e.g. the deinstallation of an external filter
549 package. Because such external filter can remove the old file - but not the automatically created new one ...
550
551 => mark item as FINALIZED / MANDATORY, we don't support writing to the old format
552 */
553 bFinalized = true;
554 bMandatory = true;
555 }
556
557 css::uno::Sequence<css::beans::PropertyValue> aProps = rItem.getAsPackedPropertyValueList(bFinalized, bMandatory);
558
559 return css::uno::Any(aProps);
560 // <- SAFE
561}
562
563
565{
567 if (pIt != rItem.end())
568 rItem.erase(pIt);
569 pIt = rItem.find(PROPNAME_MANDATORY);
570 if (pIt != rItem.end())
571 rItem.erase(pIt);
572}
573
574
576{
577 // SAFE ->
578 std::unique_lock aGuard(m_aMutex);
579
580 // renew all dependencies and optimizations
582
583 if (!m_lChangedTypes.empty())
584 {
585 css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(aGuard, E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
586 css::uno::Reference< css::container::XNameAccess > xSet ;
587
588 xConfig->getByName(CFGSET_TYPES) >>= xSet;
590
591 css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
592 xFlush->commitChanges();
593 }
594
595 if (!m_lChangedFilters.empty())
596 {
597 css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(aGuard, E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
598 css::uno::Reference< css::container::XNameAccess > xSet ;
599
600 xConfig->getByName(CFGSET_FILTERS) >>= xSet;
602
603 css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
604 xFlush->commitChanges();
605 }
606
607 /*TODO FrameLoader/ContentHandler must be flushed here too ... */
608}
609
610
611void FilterCache::impl_flushByList(const css::uno::Reference< css::container::XNameAccess >& xSet ,
612 EItemType eType ,
613 const CacheItemList& rCache,
614 const std::vector<OUString>& lItems)
615{
616 css::uno::Reference< css::container::XNameContainer > xAddRemoveSet(xSet, css::uno::UNO_QUERY);
617 css::uno::Reference< css::lang::XSingleServiceFactory > xFactory(xSet, css::uno::UNO_QUERY);
618
619 for (auto const& item : lItems)
620 {
621 EItemFlushState eState = impl_specifyFlushOperation(xSet, rCache, item);
622 switch(eState)
623 {
624 case E_ITEM_REMOVED :
625 {
626 xAddRemoveSet->removeByName(item);
627 }
628 break;
629
630 case E_ITEM_ADDED :
631 {
632 css::uno::Reference< css::container::XNameReplace > xItem (xFactory->createInstance(), css::uno::UNO_QUERY);
633
634 // special case. no exception - but not a valid item => set must be finalized or mandatory!
635 // Reject flush operation by throwing an exception. At least one item couldn't be flushed.
636 if (!xItem.is())
637 throw css::uno::Exception("Can not add item. Set is finalized or mandatory!",
638 css::uno::Reference< css::uno::XInterface >());
639
640 CacheItemList::const_iterator pItem = rCache.find(item);
641 impl_saveItem(xItem, eType, pItem->second);
642 xAddRemoveSet->insertByName(item, css::uno::Any(xItem));
643 }
644 break;
645
646 case E_ITEM_CHANGED :
647 {
648 css::uno::Reference< css::container::XNameReplace > xItem;
649 xSet->getByName(item) >>= xItem;
650
651 // special case. no exception - but not a valid item => it must be finalized or mandatory!
652 // Reject flush operation by throwing an exception. At least one item couldn't be flushed.
653 if (!xItem.is())
654 throw css::uno::Exception("Can not change item. It's finalized or mandatory!",
655 css::uno::Reference< css::uno::XInterface >());
656
657 CacheItemList::const_iterator pItem = rCache.find(item);
658 impl_saveItem(xItem, eType, pItem->second);
659 }
660 break;
661 default: break;
662 }
663 }
664}
665
666
667void FilterCache::detectFlatForURL(const css::util::URL& aURL ,
668 FlatDetection& rFlatTypes) const
669{
670 // extract extension from URL, so it can be used directly as key into our hash map!
671 // Note further: It must be converted to lower case, because the optimize hash
672 // (which maps extensions to types) work with lower case key strings!
673 INetURLObject aParser (aURL.Main);
674 OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
675 true ,
677 sExtension = sExtension.toAsciiLowerCase();
678
679 // SAFE -> ----------------------------------
680 std::unique_lock aGuard(m_aMutex);
681
682
683 // i) Step over all well known URL pattern
684 // and add registered types to the return list too
685 // Do it as first one - because: if a type match by a
686 // pattern a following deep detection can be suppressed!
687 // Further we can stop after first match ...
688 for (auto const& pattern : m_lURLPattern2Types)
689 {
690 WildCard aPatternCheck(pattern.first);
691 if (aPatternCheck.Matches(aURL.Main))
692 {
693 const std::vector<OUString>& rTypesForPattern = pattern.second;
694
695 FlatDetectionInfo aInfo;
696 aInfo.sType = *(rTypesForPattern.begin());
697 aInfo.bMatchByPattern = true;
698
699 rFlatTypes.push_back(aInfo);
700// return;
701 }
702 }
703
704
705 // ii) search types matching to the given extension.
706 // Copy every matching type without changing its order!
707 // Because preferred types was added as first one during
708 // loading configuration.
709 CacheItemRegistration::const_iterator pExtReg = m_lExtensions2Types.find(sExtension);
710 if (pExtReg != m_lExtensions2Types.end())
711 {
712 const std::vector<OUString>& rTypesForExtension = pExtReg->second;
713 for (auto const& elem : rTypesForExtension)
714 {
715 FlatDetectionInfo aInfo;
716 aInfo.sType = elem;
717 aInfo.bMatchByExtension = true;
718
719 rFlatTypes.push_back(aInfo);
720 }
721 }
722
723 // <- SAFE ----------------------------------
724}
725
726const CacheItemList& FilterCache::impl_getItemList(std::unique_lock<std::mutex>& /*rGuard*/, EItemType eType) const
727{
728 switch(eType)
729 {
730 case E_TYPE : return m_lTypes ;
731 case E_FILTER : return m_lFilters ;
732 case E_FRAMELOADER : return m_lFrameLoaders ;
734
735 }
736
737 throw css::uno::RuntimeException("unknown sub container requested.",
738 css::uno::Reference< css::uno::XInterface >());
739}
740
741CacheItemList& FilterCache::impl_getItemList(std::unique_lock<std::mutex>& /*rGuard*/, EItemType eType)
742{
743 switch(eType)
744 {
745 case E_TYPE : return m_lTypes ;
746 case E_FILTER : return m_lFilters ;
747 case E_FRAMELOADER : return m_lFrameLoaders ;
749
750 }
751
752 throw css::uno::RuntimeException("unknown sub container requested.",
753 css::uno::Reference< css::uno::XInterface >());
754}
755
756css::uno::Reference< css::uno::XInterface > FilterCache::impl_openConfig(std::unique_lock<std::mutex>& rGuard, EConfigProvider eProvider)
757{
758 OUString sPath ;
759 css::uno::Reference< css::uno::XInterface >* pConfig = nullptr;
760 css::uno::Reference< css::uno::XInterface > xOld ;
761 OString sRtlLog ;
762
763 switch(eProvider)
764 {
765 case E_PROVIDER_TYPES :
766 {
767 if (m_xConfigTypes.is())
768 return m_xConfigTypes;
769 sPath = CFGPACKAGE_TD_TYPES;
770 pConfig = &m_xConfigTypes;
771 sRtlLog = "impl_openconfig(E_PROVIDER_TYPES)";
772 }
773 break;
774
775 case E_PROVIDER_FILTERS :
776 {
777 if (m_xConfigFilters.is())
778 return m_xConfigFilters;
779 sPath = CFGPACKAGE_TD_FILTERS;
780 pConfig = &m_xConfigFilters;
781 sRtlLog = "impl_openconfig(E_PROVIDER_FILTERS)";
782 }
783 break;
784
785 case E_PROVIDER_OTHERS :
786 {
787 if (m_xConfigOthers.is())
788 return m_xConfigOthers;
789 sPath = CFGPACKAGE_TD_OTHERS;
790 pConfig = &m_xConfigOthers;
791 sRtlLog = "impl_openconfig(E_PROVIDER_OTHERS)";
792 }
793 break;
794
795 case E_PROVIDER_OLD :
796 {
797 // This special provider is used to work with
798 // the old configuration format only. It's not cached!
799 sPath = CFGPACKAGE_TD_OLD;
800 pConfig = &xOld;
801 sRtlLog = "impl_openconfig(E_PROVIDER_OLD)";
802 }
803 break;
804
805 default : throw css::uno::RuntimeException("These configuration node is not supported here for open!", nullptr);
806 }
807
808 {
809 SAL_INFO( "filter.config", "" << sRtlLog);
810 *pConfig = impl_createConfigAccess(rGuard, sPath ,
811 false, // bReadOnly
812 true ); // bLocalesMode
813 }
814
815
816 // Start listening for changes on that configuration access.
817 switch(eProvider)
818 {
819 case E_PROVIDER_TYPES:
820 {
822 m_xTypesChglisteners->startListening();
823 }
824 break;
826 {
828 m_xFiltersChgListener->startListening();
829 }
830 break;
831 default:
832 break;
833 }
834
835 return *pConfig;
836}
837
838css::uno::Any FilterCache::impl_getDirectCFGValue(std::unique_lock<std::mutex>& rGuard, std::u16string_view sDirectKey)
839{
840 OUString sRoot;
841 OUString sKey ;
842
843 if (
844 (!::utl::splitLastFromConfigurationPath(sDirectKey, sRoot, sKey)) ||
845 (sRoot.isEmpty() ) ||
846 (sKey.isEmpty() )
847 )
848 return css::uno::Any();
849
850 css::uno::Reference< css::uno::XInterface > xCfg = impl_createConfigAccess(rGuard, sRoot ,
851 true , // bReadOnly
852 false); // bLocalesMode
853 if (!xCfg.is())
854 return css::uno::Any();
855
856 css::uno::Reference< css::container::XNameAccess > xAccess(xCfg, css::uno::UNO_QUERY);
857 if (!xAccess.is())
858 return css::uno::Any();
859
860 css::uno::Any aValue;
861 try
862 {
863 aValue = xAccess->getByName(sKey);
864 }
865 catch(const css::uno::RuntimeException&)
866 { throw; }
867 catch(const css::uno::Exception&)
868 {
869 TOOLS_WARN_EXCEPTION( "filter.config", "");
870 aValue.clear();
871 }
872
873 return aValue;
874}
875
876
877css::uno::Reference< css::uno::XInterface > FilterCache::impl_createConfigAccess(std::unique_lock<std::mutex>& /*rGuard*/,
878 const OUString& sRoot ,
879 bool bReadOnly ,
880 bool bLocalesMode)
881{
882 css::uno::Reference< css::uno::XInterface > xCfg;
883
885 {
886 try
887 {
888 css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
889 css::configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() ) );
890
891 ::std::vector< css::uno::Any > lParams;
892 css::beans::NamedValue aParam;
893
894 // set root path
895 aParam.Name = "nodepath";
896 aParam.Value <<= sRoot;
897 lParams.push_back(css::uno::Any(aParam));
898
899 // enable "all locales mode" ... if required
900 if (bLocalesMode)
901 {
902 aParam.Name = "locale";
903 aParam.Value <<= OUString("*");
904 lParams.push_back(css::uno::Any(aParam));
905 }
906
907 // open it
908 if (bReadOnly)
909 xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS,
911 else
912 xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS,
914
915 // If configuration could not be opened... but factory method did not throw an exception
916 // trigger throwing of our own CorruptedFilterConfigurationException.
917 // Let message empty. The normal exception text show enough information to the user.
918 if (! xCfg.is())
919 throw css::uno::Exception(
920 "Got NULL reference on opening configuration file ... but no exception.",
921 css::uno::Reference< css::uno::XInterface >());
922 }
923 catch(const css::uno::Exception& ex)
924 {
925 throw css::document::CorruptedFilterConfigurationException(
926 "filter configuration, caught: " + ex.Message,
927 css::uno::Reference< css::uno::XInterface >(),
928 ex.Message);
929 }
930 }
931
932 return xCfg;
933}
934
935
936void FilterCache::impl_validateAndOptimize(std::unique_lock<std::mutex>& rGuard)
937{
938 // First check if any filter or type could be read
939 // from the underlying configuration!
940 bool bSomeTypesShouldExist = ((m_eFillState & E_CONTAINS_STANDARD ) == E_CONTAINS_STANDARD );
941 bool bAllFiltersShouldExist = ((m_eFillState & E_CONTAINS_FILTERS ) == E_CONTAINS_FILTERS );
942
943#if OSL_DEBUG_LEVEL > 0
944
945 sal_Int32 nWarnings = 0;
946
947// sal_Bool bAllTypesShouldExist = ((m_eFillState & E_CONTAINS_TYPES ) == E_CONTAINS_TYPES );
948 bool bAllLoadersShouldExist = ((m_eFillState & E_CONTAINS_FRAMELOADERS ) == E_CONTAINS_FRAMELOADERS );
949 bool bAllHandlersShouldExist = ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS);
950#endif
951
952 if (
953 (
954 bSomeTypesShouldExist && m_lTypes.empty()
955 ) ||
956 (
957 bAllFiltersShouldExist && m_lFilters.empty()
958 )
959 )
960 {
961 throw css::document::CorruptedFilterConfigurationException(
962 "filter configuration: the list of types or filters is empty",
963 css::uno::Reference< css::uno::XInterface >(),
964 "The list of types or filters is empty." );
965 }
966
967 // Create a log for all detected problems, which
968 // occur in the next few lines.
969 // If there are some real errors throw a RuntimException!
970 // If there are some warnings only, show an assertion.
971 sal_Int32 nErrors = 0;
972 OUStringBuffer sLog(256);
973
974 for (auto const& elem : m_lTypes)
975 {
976 const OUString & sType = elem.first;
977 const CacheItem & aType = elem.second;
978
979 // get its registration for file Extensions AND(!) URLPattern ...
980 // It doesn't matter if these items exists or if our
981 // used index access create some default ones ...
982 // only in case there is no filled set of Extensions AND
983 // no filled set of URLPattern -> we must try to remove this invalid item
984 // from this cache!
985 css::uno::Sequence< OUString > lExtensions;
986 css::uno::Sequence< OUString > lURLPattern;
987 auto it = aType.find(PROPNAME_EXTENSIONS);
988 if (it != aType.end())
989 it->second >>= lExtensions;
990 it = aType.find(PROPNAME_URLPATTERN);
991 if (it != aType.end())
992 it->second >>= lURLPattern;
993 sal_Int32 ce = lExtensions.getLength();
994 sal_Int32 cu = lURLPattern.getLength();
995
996#if OSL_DEBUG_LEVEL > 0
997
998 OUString sInternalTypeNameCheck;
999 it = aType.find(PROPNAME_NAME);
1000 if (it != aType.end())
1001 it->second >>= sInternalTypeNameCheck;
1002 if (sInternalTypeNameCheck != sType)
1003 {
1004 sLog.append("Warning\t:\t" "The type \"" + sType + "\" does support the property \"Name\" correctly.\n");
1005 ++nWarnings;
1006 }
1007
1008 if (!ce && !cu)
1009 {
1010 sLog.append("Warning\t:\t" "The type \"" + sType + "\" does not contain any URL pattern nor any extensions.\n");
1011 ++nWarnings;
1012 }
1013#endif
1014
1015 // create an optimized registration for this type to
1016 // its set list of extensions/url pattern. If it's a "normal" type
1017 // set it at the end of this optimized list. But if it's
1018 // a "Preferred" one - set it to the front of this list.
1019 // Of course multiple "Preferred" registrations can occur
1020 // (they shouldn't - but they can!) ... Ignore it. The last
1021 // preferred type is usable in the same manner then every
1022 // other type!
1023 bool bPreferred = false;
1024 it = aType.find(PROPNAME_PREFERRED);
1025 if (it != aType.end())
1026 it->second >>= bPreferred;
1027
1028 const OUString* pExtensions = lExtensions.getConstArray();
1029 for (sal_Int32 e=0; e<ce; ++e)
1030 {
1031 // Note: We must be sure that address the right hash entry
1032 // does not depend from any upper/lower case problems ...
1033 OUString sNormalizedExtension = pExtensions[e].toAsciiLowerCase();
1034
1035 std::vector<OUString>& lTypesForExtension = m_lExtensions2Types[sNormalizedExtension];
1036 if (::std::find(lTypesForExtension.begin(), lTypesForExtension.end(), sType) != lTypesForExtension.end())
1037 continue;
1038
1039 if (bPreferred)
1040 lTypesForExtension.insert(lTypesForExtension.begin(), sType);
1041 else
1042 lTypesForExtension.push_back(sType);
1043 }
1044
1045 const OUString* pURLPattern = lURLPattern.getConstArray();
1046 for (sal_Int32 u=0; u<cu; ++u)
1047 {
1048 std::vector<OUString>& lTypesForURLPattern = m_lURLPattern2Types[pURLPattern[u]];
1049 if (::std::find(lTypesForURLPattern.begin(), lTypesForURLPattern.end(), sType) != lTypesForURLPattern.end())
1050 continue;
1051
1052 if (bPreferred)
1053 lTypesForURLPattern.insert(lTypesForURLPattern.begin(), sType);
1054 else
1055 lTypesForURLPattern.push_back(sType);
1056 }
1057
1058#if OSL_DEBUG_LEVEL > 0
1059
1060 // Don't check cross references between types and filters, if
1061 // not all filters read from disk!
1062 // OK - this cache can read single filters on demand too ...
1063 // but then the fill state of this cache should not be set to E_CONTAINS_FILTERS!
1064 if (!bAllFiltersShouldExist)
1065 continue;
1066
1067 OUString sPrefFilter;
1068 it = aType.find(PROPNAME_PREFERREDFILTER);
1069 if (it != aType.end())
1070 it->second >>= sPrefFilter;
1071 if (sPrefFilter.isEmpty())
1072 {
1073 // OK - there is no filter for this type. But that's not an error.
1074 // Maybe it can be handled by a ContentHandler...
1075 // But at this time it's not guaranteed that there is any ContentHandler
1076 // or FrameLoader inside this cache... but on disk...
1077 bool bReferencedByLoader = true;
1078 bool bReferencedByHandler = true;
1079 if (bAllLoadersShouldExist)
1080 bReferencedByLoader = !impl_searchFrameLoaderForType(sType).isEmpty();
1081
1082 if (bAllHandlersShouldExist)
1083 bReferencedByHandler = !impl_searchContentHandlerForType(sType).isEmpty();
1084
1085 if (
1086 (!bReferencedByLoader ) &&
1087 (!bReferencedByHandler)
1088 )
1089 {
1090 sLog.append("Warning\t:\t" "The type \"" + sType + "\" is not used by any filter, loader or content handler.\n");
1091 ++nWarnings;
1092 }
1093 }
1094
1095 if (!sPrefFilter.isEmpty())
1096 {
1097 CacheItemList::const_iterator pIt2 = m_lFilters.find(sPrefFilter);
1098 if (pIt2 == m_lFilters.end())
1099 {
1100 if (bAllFiltersShouldExist)
1101 {
1102 ++nWarnings; // preferred filters can point to a non-installed office module ! no error ... it's a warning only .-(
1103 sLog.append("error\t:\t");
1104 }
1105 else
1106 {
1107 ++nWarnings;
1108 sLog.append("warning\t:\t");
1109 }
1110
1111 sLog.append("The type \"" + sType + "\" points to an invalid filter \"" + sPrefFilter + "\".\n");
1112 continue;
1113 }
1114
1115 CacheItem aPrefFilter = pIt2->second;
1116 OUString sFilterTypeReg;
1117 aPrefFilter[PROPNAME_TYPE] >>= sFilterTypeReg;
1118 if (sFilterTypeReg != sType)
1119 {
1120 sLog.append("error\t:\t" "The preferred filter \"" +
1121 sPrefFilter + "\" of type \"" + sType +
1122 "\" is registered for another type \"" + sFilterTypeReg +
1123 "\".\n");
1124 ++nErrors;
1125 }
1126
1127 sal_Int32 nFlags = 0;
1128 aPrefFilter[PROPNAME_FLAGS] >>= nFlags;
1129 if (!(static_cast<SfxFilterFlags>(nFlags) & SfxFilterFlags::IMPORT))
1130 {
1131 sLog.append("error\t:\t" "The preferred filter \"" + sPrefFilter + "\" of type \"" +
1132 sType + "\" is not an IMPORT filter!\n");
1133 ++nErrors;
1134 }
1135
1136 OUString sInternalFilterNameCheck;
1137 aPrefFilter[PROPNAME_NAME] >>= sInternalFilterNameCheck;
1138 if (sInternalFilterNameCheck != sPrefFilter)
1139 {
1140 sLog.append("Warning\t:\t" "The filter \"" + sPrefFilter +
1141 "\" does support the property \"Name\" correctly.\n");
1142 ++nWarnings;
1143 }
1144 }
1145#endif
1146 }
1147
1148 // create dependencies between the global default frame loader
1149 // and all types (and of course if registered filters), which
1150 // does not registered for any other loader.
1151 css::uno::Any aDirectValue = impl_getDirectCFGValue(rGuard, CFGDIRECTKEY_DEFAULTFRAMELOADER);
1152 OUString sDefaultFrameLoader;
1153
1154 if (
1155 (!(aDirectValue >>= sDefaultFrameLoader)) ||
1156 (sDefaultFrameLoader.isEmpty() )
1157 )
1158 {
1159 sLog.append("error\t:\t" "There is no valid default frame loader!?\n");
1160 ++nErrors;
1161 }
1162
1163 // a) get list of all well known types
1164 // b) step over all well known frame loader services
1165 // and remove all types from list a), which already
1166 // referenced by a loader b)
1167 std::vector<OUString> lTypes = getItemNames(rGuard, E_TYPE);
1168 for (auto & frameLoader : m_lFrameLoaders)
1169 {
1170 // Note: of course the default loader must be ignored here.
1171 // Because we replace its registration later completely with all
1172 // types, which are not referenced by any other loader.
1173 // So we can avoid our code against the complexity of a diff!
1174 OUString sLoader = frameLoader.first;
1175 if (sLoader == sDefaultFrameLoader)
1176 continue;
1177
1178 CacheItem& rLoader = frameLoader.second;
1179 css::uno::Any& rTypesReg = rLoader[PROPNAME_TYPES];
1180 const css::uno::Sequence<OUString> lTypesReg = rTypesReg.get<css::uno::Sequence<OUString> >();
1181
1182 for (auto const& typeReg : lTypesReg)
1183 {
1184 auto pTypeCheck = ::std::find(lTypes.begin(), lTypes.end(), typeReg);
1185 if (pTypeCheck != lTypes.end())
1186 lTypes.erase(pTypeCheck);
1187 }
1188 }
1189
1190 CacheItem& rDefaultLoader = m_lFrameLoaders[sDefaultFrameLoader];
1191 rDefaultLoader[PROPNAME_NAME ] <<= sDefaultFrameLoader;
1192 rDefaultLoader[PROPNAME_TYPES] <<= comphelper::containerToSequence(lTypes);
1193
1194 OUString sLogOut = sLog.makeStringAndClear();
1195 OSL_ENSURE(!nErrors, OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1196 if (nErrors>0)
1197 throw css::document::CorruptedFilterConfigurationException(
1198 "filter configuration: " + sLogOut,
1199 css::uno::Reference< css::uno::XInterface >(),
1200 sLogOut);
1201#if OSL_DEBUG_LEVEL > 0
1202 OSL_ENSURE(!nWarnings, OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1203#endif
1204}
1205
1207 const OUString& sItem)
1208{
1209 std::vector<OUString>* pList = nullptr;
1210 switch(eType)
1211 {
1212 case E_TYPE :
1213 pList = &m_lChangedTypes;
1214 break;
1215
1216 case E_FILTER :
1217 pList = &m_lChangedFilters;
1218 break;
1219
1220 case E_FRAMELOADER :
1221 pList = &m_lChangedFrameLoaders;
1222 break;
1223
1224 case E_CONTENTHANDLER :
1226 break;
1227
1228 default : throw css::uno::RuntimeException("unsupported item type", nullptr);
1229 }
1230
1231 auto pItem = ::std::find(pList->cbegin(), pList->cend(), sItem);
1232 if (pItem == pList->cend())
1233 pList->push_back(sItem);
1234}
1235
1236FilterCache::EItemFlushState FilterCache::impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1237 const CacheItemList& rList,
1238 const OUString& sItem)
1239{
1240 bool bExistsInConfigLayer = xSet->hasByName(sItem);
1241 bool bExistsInMemory = (rList.find(sItem) != rList.end());
1242
1244
1245 // !? ... such situation can occur, if an item was added and(!) removed before it was flushed :-)
1246 if (!bExistsInConfigLayer && !bExistsInMemory)
1247 eState = E_ITEM_UNCHANGED;
1248 else if (!bExistsInConfigLayer && bExistsInMemory)
1249 eState = E_ITEM_ADDED;
1250 else if (bExistsInConfigLayer && bExistsInMemory)
1251 eState = E_ITEM_CHANGED;
1252 else if (bExistsInConfigLayer && !bExistsInMemory)
1253 eState = E_ITEM_REMOVED;
1254
1255 return eState;
1256}
1257
1258void FilterCache::impl_load(std::unique_lock<std::mutex>& rGuard, EFillState eRequiredState)
1259{
1260 // Attention: Detect services are part of the standard set!
1261 // So there is no need to handle it separately.
1262
1263
1264 // a) The standard set of config value is needed.
1265 if (
1266 ((eRequiredState & E_CONTAINS_STANDARD) == E_CONTAINS_STANDARD) &&
1268 )
1269 {
1270 // Attention! If config couldn't be opened successfully
1271 // and exception is thrown automatically and must be forwarded
1272 // to our caller...
1273 css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(rGuard, E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1274 {
1275 SAL_INFO( "filter.config", "FilterCache::load std");
1276 impl_loadSet(rGuard, xTypes, E_TYPE, E_READ_STANDARD, &m_lTypes);
1277 }
1278 }
1279
1280
1281 // b) We need all type information ...
1282 if (
1283 ((eRequiredState & E_CONTAINS_TYPES) == E_CONTAINS_TYPES) &&
1285 )
1286 {
1287 // Attention! If config couldn't be opened successfully
1288 // and exception is thrown automatically and must be forwarded
1289 // to our call...
1290 css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(rGuard, E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1291 {
1292 SAL_INFO( "filter.config", "FilterCache::load all types");
1293 impl_loadSet(rGuard, xTypes, E_TYPE, E_READ_UPDATE, &m_lTypes);
1294 }
1295 }
1296
1297
1298 // c) We need all filter information ...
1299 if (
1300 ((eRequiredState & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) &&
1302 )
1303 {
1304 // Attention! If config couldn't be opened successfully
1305 // and exception is thrown automatically and must be forwarded
1306 // to our call...
1307 css::uno::Reference< css::container::XNameAccess > xFilters(impl_openConfig(rGuard, E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
1308 {
1309 SAL_INFO( "filter.config", "FilterCache::load all filters");
1310 impl_loadSet(rGuard, xFilters, E_FILTER, E_READ_ALL, &m_lFilters);
1311 }
1312 }
1313
1314
1315 // c) We need all frame loader information ...
1316 if (
1317 ((eRequiredState & E_CONTAINS_FRAMELOADERS) == E_CONTAINS_FRAMELOADERS) &&
1319 )
1320 {
1321 // Attention! If config couldn't be opened successfully
1322 // and exception is thrown automatically and must be forwarded
1323 // to our call...
1324 css::uno::Reference< css::container::XNameAccess > xLoaders(impl_openConfig(rGuard, E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1325 {
1326 SAL_INFO( "filter.config", "FilterCache::load all frame loader");
1328 }
1329 }
1330
1331
1332 // d) We need all content handler information...
1333 if (
1336 )
1337 {
1338 // Attention! If config couldn't be opened successfully
1339 // and exception is thrown automatically and must be forwarded
1340 // to our call...
1341 css::uno::Reference< css::container::XNameAccess > xHandlers(impl_openConfig(rGuard, E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1342 {
1343 SAL_INFO( "filter.config", "FilterCache::load all content handler");
1345 }
1346 }
1347
1348 // update fill state. Note: it's a bit field, which combines different parts.
1349 m_eFillState = static_cast<EFillState>(static_cast<sal_Int32>(m_eFillState) | static_cast<sal_Int32>(eRequiredState));
1350
1351 // any data read?
1352 // yes! => validate it and update optimized structures.
1354}
1355
1356void FilterCache::impl_loadSet(std::unique_lock<std::mutex>& rGuard,
1357 const css::uno::Reference< css::container::XNameAccess >& xConfig,
1358 EItemType eType ,
1359 EReadOption eOption,
1360 CacheItemList* pCache )
1361{
1362 // get access to the right configuration set
1363 OUString sSetName;
1364 switch(eType)
1365 {
1366 case E_TYPE :
1367 sSetName = CFGSET_TYPES;
1368 break;
1369
1370 case E_FILTER :
1371 sSetName = CFGSET_FILTERS;
1372 break;
1373
1374 case E_FRAMELOADER :
1375 sSetName = CFGSET_FRAMELOADERS;
1376 break;
1377
1378 case E_CONTENTHANDLER :
1379 sSetName = CFGSET_CONTENTHANDLERS;
1380 break;
1381 default: break;
1382 }
1383
1384 css::uno::Reference< css::container::XNameAccess > xSet;
1385 css::uno::Sequence< OUString > lItems;
1386
1387 try
1388 {
1389 css::uno::Any aVal = xConfig->getByName(sSetName);
1390 if (!(aVal >>= xSet) || !xSet.is())
1391 {
1392 OUString sMsg("Could not open configuration set \"" + sSetName + "\".");
1393 throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1394 }
1395 lItems = xSet->getElementNames();
1396 }
1397 catch(const css::uno::Exception& ex)
1398 {
1399 throw css::document::CorruptedFilterConfigurationException(
1400 "filter configuration, caught: " + ex.Message,
1401 css::uno::Reference< css::uno::XInterface >(),
1402 ex.Message);
1403 }
1404
1405 // get names of all existing sub items of this set
1406 // step over it and fill internal cache structures.
1407
1408 // But don't update optimized structures like e.g. hash
1409 // for mapping extensions to its types!
1410
1411 const OUString* pItems = lItems.getConstArray();
1412 sal_Int32 c = lItems.getLength();
1413 for (sal_Int32 i=0; i<c; ++i)
1414 {
1415 CacheItemList::iterator pItem = pCache->find(pItems[i]);
1416 switch(eOption)
1417 {
1418 // a) read a standard set of properties only or read all
1419 case E_READ_STANDARD :
1420 case E_READ_ALL :
1421 {
1422 try
1423 {
1424 (*pCache)[pItems[i]] = impl_loadItem(rGuard, xSet, eType, pItems[i], eOption);
1425 }
1426 catch(const css::uno::Exception& ex)
1427 {
1428 throw css::document::CorruptedFilterConfigurationException(
1429 "filter configuration, caught: " + ex.Message,
1430 css::uno::Reference< css::uno::XInterface >(),
1431 ex.Message);
1432 }
1433 }
1434 break;
1435
1436 // b) read optional properties only!
1437 // All items must already exist inside our cache.
1438 // But they must be updated.
1439 case E_READ_UPDATE :
1440 {
1441 if (pItem == pCache->end())
1442 {
1443 OUString sMsg("item \"" + pItems[i] + "\" not found for update!");
1444 throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1445 }
1446 try
1447 {
1448 CacheItem aItem = impl_loadItem(rGuard, xSet, eType, pItems[i], eOption);
1449 pItem->second.update(aItem);
1450 }
1451 catch(const css::uno::Exception& ex)
1452 {
1453 throw css::document::CorruptedFilterConfigurationException(
1454 "filter configuration, caught: " + ex.Message,
1455 css::uno::Reference< css::uno::XInterface >(),
1456 ex.Message);
1457 }
1458 }
1459 break;
1460 default: break;
1461 }
1462 }
1463}
1464
1465void FilterCache::impl_readPatchUINames(std::unique_lock<std::mutex>& /*rGuard*/,
1466 const css::uno::Reference< css::container::XNameAccess >& xNode,
1467 CacheItem& rItem)
1468{
1469
1470 OUString sActLocale = m_sActLocale ;
1471
1472 css::uno::Any aVal = xNode->getByName(PROPNAME_UINAME);
1473 css::uno::Reference< css::container::XNameAccess > xUIName;
1474 if (!(aVal >>= xUIName) && !xUIName.is())
1475 return;
1476
1477 const ::std::vector< OUString > lLocales(comphelper::sequenceToContainer< ::std::vector< OUString >>(
1478 xUIName->getElementNames()));
1479 ::std::vector< OUString >::const_iterator pLocale ;
1481
1482 for (auto const& locale : lLocales)
1483 {
1484 OUString sValue;
1485 xUIName->getByName(locale) >>= sValue;
1486
1487 lUINames[locale] <<= sValue;
1488 }
1489
1490 aVal <<= lUINames.getAsConstPropertyValueList();
1491 rItem[PROPNAME_UINAMES] = aVal;
1492
1493 // find right UIName for current office locale
1494 // Use fallbacks too!
1495 pLocale = LanguageTag::getFallback(lLocales, sActLocale);
1496 if (pLocale == lLocales.end())
1497 {
1498#if OSL_DEBUG_LEVEL > 0
1499 if ( sActLocale == "en-US" )
1500 return;
1501 OUString sName = rItem.getUnpackedValueOrDefault(PROPNAME_NAME, OUString());
1502
1503 SAL_WARN("filter.config", "Fallback scenario for filter or type '" << sName << "' and locale '" <<
1504 sActLocale << "' failed. Please check your filter configuration.");
1505#endif
1506 return;
1507 }
1508
1509 const OUString& sLocale = *pLocale;
1510 ::comphelper::SequenceAsHashMap::const_iterator pUIName = lUINames.find(sLocale);
1511 if (pUIName != lUINames.end())
1512 rItem[PROPNAME_UINAME] = pUIName->second;
1513}
1514
1515void FilterCache::impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
1516 const CacheItem& rItem)
1517{
1518 css::uno::Reference< css::container::XNameContainer > xAdd (xNode, css::uno::UNO_QUERY);
1519
1520 css::uno::Sequence< css::beans::PropertyValue > lUINames = rItem.getUnpackedValueOrDefault(PROPNAME_UINAMES, css::uno::Sequence< css::beans::PropertyValue >());
1521 sal_Int32 c = lUINames.getLength();
1522 const css::beans::PropertyValue* pUINames = lUINames.getConstArray();
1523
1524 for (sal_Int32 i=0; i<c; ++i)
1525 {
1526 if (xNode->hasByName(pUINames[i].Name))
1527 xNode->replaceByName(pUINames[i].Name, pUINames[i].Value);
1528 else
1529 xAdd->insertByName(pUINames[i].Name, pUINames[i].Value);
1530 }
1531}
1532
1533/*-----------------------------------------------
1534 TODO
1535 clarify, how the real problem behind the
1536 wrong constructed CacheItem instance (which
1537 will force a crash during destruction)
1538 can be solved ...
1539-----------------------------------------------*/
1540CacheItem FilterCache::impl_loadItem(std::unique_lock<std::mutex>& rGuard,
1541 const css::uno::Reference< css::container::XNameAccess >& xSet ,
1542 EItemType eType ,
1543 const OUString& sItem ,
1544 EReadOption eOption)
1545{
1546 // try to get an API object, which points directly to the
1547 // requested item. If it fail an exception should occur and
1548 // break this operation. Of course returned API object must be
1549 // checked too.
1550 css::uno::Reference< css::container::XNameAccess > xItem;
1551 css::uno::Any aVal = xSet->getByName(sItem);
1552 if (!(aVal >>= xItem) || !xItem.is())
1553 {
1554 throw css::uno::RuntimeException("found corrupted item \"" + sItem + "\".",
1555 css::uno::Reference< css::uno::XInterface >());
1556 }
1557
1558 // set too. Of course it's already used as key into the e.g. outside
1559 // used hash map... but some of our API methods provide
1560 // this property set as result only. But the user of this CacheItem
1561 // should know, which value the key names has :-) IT'S IMPORTANT!
1562 CacheItem aItem;
1563 aItem[PROPNAME_NAME] <<= sItem;
1564 switch(eType)
1565 {
1566 case E_TYPE :
1567 {
1568 assert(eOption >= 0 && eOption <= E_READ_ALL);
1569 css::uno::Sequence< OUString > &rNames = m_aTypeProps[eOption];
1570
1571 // read standard properties of a filter
1572 if (rNames.hasElements())
1573 {
1574 css::uno::Reference< css::beans::XMultiPropertySet >
1575 xPropSet( xItem, css::uno::UNO_QUERY_THROW);
1576 css::uno::Sequence< css::uno::Any > aValues = xPropSet->getPropertyValues(rNames);
1577
1578 for (sal_Int32 i = 0; i < aValues.getLength(); i++)
1579 aItem[rNames[i]] = aValues[i];
1580 }
1581
1582 // read optional properties of a type
1583 // no else here! Is an additional switch ...
1584 if (eOption == E_READ_UPDATE || eOption == E_READ_ALL)
1585 impl_readPatchUINames(rGuard, xItem, aItem);
1586 }
1587 break;
1588
1589
1590 case E_FILTER :
1591 {
1592 assert(eOption >= 0 && eOption <= E_READ_ALL);
1593 css::uno::Sequence< OUString > &rNames = m_aStandardProps[eOption];
1594
1595 // read standard properties of a filter
1596 if (rNames.hasElements())
1597 {
1598 css::uno::Reference< css::beans::XMultiPropertySet >
1599 xPropSet( xItem, css::uno::UNO_QUERY_THROW);
1600 css::uno::Sequence< css::uno::Any > aValues = xPropSet->getPropertyValues(rNames);
1601
1602 for (sal_Int32 i = 0; i < rNames.getLength(); i++)
1603 {
1604 const OUString &rPropName = rNames[i];
1605 if (i != rNames.getLength() - 1 || rPropName != PROPNAME_FLAGS)
1606 aItem[rPropName] = aValues[i];
1607 else
1608 {
1609 assert(rPropName == PROPNAME_FLAGS);
1610 // special handling for flags! Convert it from a list of names to its
1611 // int representation ...
1612 css::uno::Sequence< OUString > lFlagNames;
1613 if (aValues[i] >>= lFlagNames)
1614 aItem[rPropName] <<= static_cast<sal_Int32>(FilterCache::impl_convertFlagNames2FlagField(lFlagNames));
1615 }
1616 }
1617 }
1618//TODO remove it if moving of filter uinames to type uinames
1619// will be finished really
1620#ifdef AS_ENABLE_FILTER_UINAMES
1621 if (eOption == E_READ_UPDATE || eOption == E_READ_ALL)
1622 impl_readPatchUINames(rGuard, xItem, aItem);
1623#endif // AS_ENABLE_FILTER_UINAMES
1624 }
1625 break;
1626
1627 case E_FRAMELOADER :
1628 case E_CONTENTHANDLER :
1629 aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
1630 break;
1631 default: break;
1632 }
1633
1634 return aItem;
1635}
1636
1637CacheItemList::iterator FilterCache::impl_loadItemOnDemand( std::unique_lock<std::mutex>& rGuard,
1638 EItemType eType,
1639 const OUString& sItem)
1640{
1641 CacheItemList* pList = nullptr;
1642 css::uno::Reference< css::uno::XInterface > xConfig ;
1643 OUString sSet ;
1644
1645 switch(eType)
1646 {
1647 case E_TYPE :
1648 {
1649 pList = &m_lTypes;
1650 xConfig = impl_openConfig(rGuard, E_PROVIDER_TYPES);
1651 sSet = CFGSET_TYPES;
1652 }
1653 break;
1654
1655 case E_FILTER :
1656 {
1657 pList = &m_lFilters;
1658 xConfig = impl_openConfig(rGuard, E_PROVIDER_FILTERS);
1659 sSet = CFGSET_FILTERS;
1660 }
1661 break;
1662
1663 case E_FRAMELOADER :
1664 {
1665 pList = &m_lFrameLoaders;
1666 xConfig = impl_openConfig(rGuard, E_PROVIDER_OTHERS);
1667 sSet = CFGSET_FRAMELOADERS;
1668 }
1669 break;
1670
1671 case E_CONTENTHANDLER :
1672 {
1673 pList = &m_lContentHandlers;
1674 xConfig = impl_openConfig(rGuard, E_PROVIDER_OTHERS);
1676 }
1677 break;
1678 }
1679
1680 if (!pList)
1681 throw css::container::NoSuchElementException();
1682
1683 css::uno::Reference< css::container::XNameAccess > xRoot(xConfig, css::uno::UNO_QUERY_THROW);
1684 css::uno::Reference< css::container::XNameAccess > xSet ;
1685 xRoot->getByName(sSet) >>= xSet;
1686
1687 CacheItemList::iterator pItemInCache = pList->find(sItem);
1688 bool bItemInConfig = xSet->hasByName(sItem);
1689
1690 if (bItemInConfig)
1691 {
1692 (*pList)[sItem] = impl_loadItem(rGuard, xSet, eType, sItem, E_READ_ALL);
1693 }
1694 else
1695 {
1696 if (pItemInCache != pList->end())
1697 pList->erase(pItemInCache);
1698 // OK - this item does not exists inside configuration.
1699 // And we already updated our internal cache.
1700 // But the outside code needs this NoSuchElementException
1701 // to know, that this item does notexists.
1702 // Nobody checks the iterator!
1703 throw css::container::NoSuchElementException();
1704 }
1705
1706 return pList->find(sItem);
1707}
1708
1709void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem,
1710 EItemType eType,
1711 const CacheItem & aItem)
1712{
1713 // This function changes the properties of aItem one-by-one; but it also
1714 // listens to the configuration changes and reloads the whole item from the
1715 // configuration on change, so use a copy of aItem throughout:
1716 CacheItem copiedItem(aItem);
1717
1719 switch(eType)
1720 {
1721
1722 case E_TYPE :
1723 {
1724 pIt = copiedItem.find(PROPNAME_PREFERREDFILTER);
1725 if (pIt != copiedItem.end())
1726 xItem->replaceByName(PROPNAME_PREFERREDFILTER, pIt->second);
1727 pIt = copiedItem.find(PROPNAME_DETECTSERVICE);
1728 if (pIt != copiedItem.end())
1729 xItem->replaceByName(PROPNAME_DETECTSERVICE, pIt->second);
1730 pIt = copiedItem.find(PROPNAME_URLPATTERN);
1731 if (pIt != copiedItem.end())
1732 xItem->replaceByName(PROPNAME_URLPATTERN, pIt->second);
1733 pIt = copiedItem.find(PROPNAME_EXTENSIONS);
1734 if (pIt != copiedItem.end())
1735 xItem->replaceByName(PROPNAME_EXTENSIONS, pIt->second);
1736 pIt = copiedItem.find(PROPNAME_PREFERRED);
1737 if (pIt != copiedItem.end())
1738 xItem->replaceByName(PROPNAME_PREFERRED, pIt->second);
1739 pIt = copiedItem.find(PROPNAME_MEDIATYPE);
1740 if (pIt != copiedItem.end())
1741 xItem->replaceByName(PROPNAME_MEDIATYPE, pIt->second);
1742 pIt = copiedItem.find(PROPNAME_CLIPBOARDFORMAT);
1743 if (pIt != copiedItem.end())
1744 xItem->replaceByName(PROPNAME_CLIPBOARDFORMAT, pIt->second);
1745
1746 css::uno::Reference< css::container::XNameReplace > xUIName;
1747 xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1748 impl_savePatchUINames(xUIName, copiedItem);
1749 }
1750 break;
1751
1752
1753 case E_FILTER :
1754 {
1755 pIt = copiedItem.find(PROPNAME_TYPE);
1756 if (pIt != copiedItem.end())
1757 xItem->replaceByName(PROPNAME_TYPE, pIt->second);
1758 pIt = copiedItem.find(PROPNAME_FILEFORMATVERSION);
1759 if (pIt != copiedItem.end())
1760 xItem->replaceByName(PROPNAME_FILEFORMATVERSION, pIt->second);
1761 pIt = copiedItem.find(PROPNAME_UICOMPONENT);
1762 if (pIt != copiedItem.end())
1763 xItem->replaceByName(PROPNAME_UICOMPONENT, pIt->second);
1764 pIt = copiedItem.find(PROPNAME_FILTERSERVICE);
1765 if (pIt != copiedItem.end())
1766 xItem->replaceByName(PROPNAME_FILTERSERVICE, pIt->second);
1767 pIt = copiedItem.find(PROPNAME_DOCUMENTSERVICE);
1768 if (pIt != copiedItem.end())
1769 xItem->replaceByName(PROPNAME_DOCUMENTSERVICE, pIt->second);
1770 pIt = copiedItem.find(PROPNAME_USERDATA);
1771 if (pIt != copiedItem.end())
1772 xItem->replaceByName(PROPNAME_USERDATA, pIt->second);
1773 pIt = copiedItem.find(PROPNAME_TEMPLATENAME);
1774 if (pIt != copiedItem.end())
1775 xItem->replaceByName(PROPNAME_TEMPLATENAME, pIt->second);
1776
1777 // special handling for flags! Convert it from an integer flag field back
1778 // to a list of names ...
1779 pIt = copiedItem.find(PROPNAME_FLAGS);
1780 if (pIt != copiedItem.end())
1781 {
1782 sal_Int32 nFlags = 0;
1783 pIt->second >>= nFlags;
1784 css::uno::Any aFlagNameList;
1785 aFlagNameList <<= FilterCache::impl_convertFlagField2FlagNames(static_cast<SfxFilterFlags>(nFlags));
1786 xItem->replaceByName(PROPNAME_FLAGS, aFlagNameList);
1787 }
1788
1789//TODO remove it if moving of filter uinames to type uinames
1790// will be finished really
1791#ifdef AS_ENABLE_FILTER_UINAMES
1792 css::uno::Reference< css::container::XNameReplace > xUIName;
1793 xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1794 impl_savePatchUINames(xUIName, copiedItem);
1795#endif // AS_ENABLE_FILTER_UINAMES
1796 }
1797 break;
1798
1799
1800 case E_FRAMELOADER :
1801 case E_CONTENTHANDLER :
1802 {
1803 pIt = copiedItem.find(PROPNAME_TYPES);
1804 if (pIt != copiedItem.end())
1805 xItem->replaceByName(PROPNAME_TYPES, pIt->second);
1806 }
1807 break;
1808 default: break;
1809 }
1810}
1811
1812/*-----------------------------------------------
1813 static! => no locks necessary
1814-----------------------------------------------*/
1816{
1817 std::vector<OUString> lFlagNames;
1818
1819 if (nFlags & SfxFilterFlags::STARONEFILTER ) lFlagNames.emplace_back(FLAGNAME_3RDPARTYFILTER );
1820 if (nFlags & SfxFilterFlags::ALIEN ) lFlagNames.emplace_back(FLAGNAME_ALIEN );
1821 if (nFlags & SfxFilterFlags::CONSULTSERVICE ) lFlagNames.emplace_back(FLAGNAME_CONSULTSERVICE );
1822 if (nFlags & SfxFilterFlags::DEFAULT ) lFlagNames.emplace_back(FLAGNAME_DEFAULT );
1823 if (nFlags & SfxFilterFlags::ENCRYPTION ) lFlagNames.emplace_back(FLAGNAME_ENCRYPTION );
1824 if (nFlags & SfxFilterFlags::EXPORT ) lFlagNames.emplace_back(FLAGNAME_EXPORT );
1825 if (nFlags & SfxFilterFlags::IMPORT ) lFlagNames.emplace_back(FLAGNAME_IMPORT );
1826 if (nFlags & SfxFilterFlags::INTERNAL ) lFlagNames.emplace_back(FLAGNAME_INTERNAL );
1827 if (nFlags & SfxFilterFlags::NOTINFILEDLG ) lFlagNames.emplace_back(FLAGNAME_NOTINFILEDIALOG );
1828 if (nFlags & SfxFilterFlags::MUSTINSTALL ) lFlagNames.emplace_back(FLAGNAME_NOTINSTALLED );
1829 if (nFlags & SfxFilterFlags::OWN ) lFlagNames.emplace_back(FLAGNAME_OWN );
1830 if (nFlags & SfxFilterFlags::PACKED ) lFlagNames.emplace_back(FLAGNAME_PACKED );
1831 if (nFlags & SfxFilterFlags::PASSWORDTOMODIFY ) lFlagNames.emplace_back(FLAGNAME_PASSWORDTOMODIFY );
1832 if (nFlags & SfxFilterFlags::PREFERED ) lFlagNames.emplace_back(FLAGNAME_PREFERRED );
1833 if (nFlags & SfxFilterFlags::STARTPRESENTATION) lFlagNames.emplace_back(FLAGNAME_STARTPRESENTATION);
1834 if (nFlags & SfxFilterFlags::OPENREADONLY ) lFlagNames.emplace_back(FLAGNAME_READONLY );
1835 if (nFlags & SfxFilterFlags::SUPPORTSSELECTION) lFlagNames.emplace_back(FLAGNAME_SUPPORTSSELECTION);
1836 if (nFlags & SfxFilterFlags::TEMPLATE ) lFlagNames.emplace_back(FLAGNAME_TEMPLATE );
1837 if (nFlags & SfxFilterFlags::TEMPLATEPATH ) lFlagNames.emplace_back(FLAGNAME_TEMPLATEPATH );
1838 if (nFlags & SfxFilterFlags::COMBINED ) lFlagNames.emplace_back(FLAGNAME_COMBINED );
1839 if (nFlags & SfxFilterFlags::SUPPORTSSIGNING) lFlagNames.emplace_back(FLAGNAME_SUPPORTSSIGNING);
1840 if (nFlags & SfxFilterFlags::GPGENCRYPTION) lFlagNames.emplace_back(FLAGNAME_GPGENCRYPTION);
1841 if (nFlags & SfxFilterFlags::EXOTIC) lFlagNames.emplace_back(FLAGNAME_EXOTIC);
1842
1843 return comphelper::containerToSequence(lFlagNames);
1844}
1845
1846/*-----------------------------------------------
1847 static! => no locks necessary
1848-----------------------------------------------*/
1849SfxFilterFlags FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence< OUString >& lNames)
1850{
1851 SfxFilterFlags nField = SfxFilterFlags::NONE;
1852
1853 const OUString* pNames = lNames.getConstArray();
1854 sal_Int32 c = lNames.getLength();
1855 for (sal_Int32 i=0; i<c; ++i)
1856 {
1857 if (pNames[i] == FLAGNAME_3RDPARTYFILTER)
1858 {
1859 nField |= SfxFilterFlags::STARONEFILTER;
1860 continue;
1861 }
1862 if (pNames[i] == FLAGNAME_ALIEN)
1863 {
1864 nField |= SfxFilterFlags::ALIEN;
1865 continue;
1866 }
1867 if (pNames[i] == FLAGNAME_CONSULTSERVICE)
1868 {
1869 nField |= SfxFilterFlags::CONSULTSERVICE;
1870 continue;
1871 }
1872 if (pNames[i] == FLAGNAME_DEFAULT)
1873 {
1874 nField |= SfxFilterFlags::DEFAULT;
1875 continue;
1876 }
1877 if (pNames[i] == FLAGNAME_ENCRYPTION)
1878 {
1879 nField |= SfxFilterFlags::ENCRYPTION;
1880 continue;
1881 }
1882 if (pNames[i] == FLAGNAME_EXOTIC)
1883 {
1884 nField |= SfxFilterFlags::EXOTIC;
1885 continue;
1886 }
1887 if (pNames[i] == FLAGNAME_EXPORT)
1888 {
1889 nField |= SfxFilterFlags::EXPORT;
1890 continue;
1891 }
1892 if (pNames[i] == FLAGNAME_GPGENCRYPTION)
1893 {
1894 nField |= SfxFilterFlags::GPGENCRYPTION;
1895 continue;
1896 }
1897 if (pNames[i] == FLAGNAME_IMPORT)
1898 {
1899 nField |= SfxFilterFlags::IMPORT;
1900 continue;
1901 }
1902 if (pNames[i] == FLAGNAME_INTERNAL)
1903 {
1904 nField |= SfxFilterFlags::INTERNAL;
1905 continue;
1906 }
1907 if (pNames[i] == FLAGNAME_NOTINFILEDIALOG)
1908 {
1909 nField |= SfxFilterFlags::NOTINFILEDLG;
1910 continue;
1911 }
1912 if (pNames[i] == FLAGNAME_NOTINSTALLED)
1913 {
1914 nField |= SfxFilterFlags::MUSTINSTALL;
1915 continue;
1916 }
1917 if (pNames[i] == FLAGNAME_OWN)
1918 {
1919 nField |= SfxFilterFlags::OWN;
1920 continue;
1921 }
1922 if (pNames[i] == FLAGNAME_PACKED)
1923 {
1924 nField |= SfxFilterFlags::PACKED;
1925 continue;
1926 }
1927 if (pNames[i] == FLAGNAME_PASSWORDTOMODIFY)
1928 {
1929 nField |= SfxFilterFlags::PASSWORDTOMODIFY;
1930 continue;
1931 }
1932 if (pNames[i] == FLAGNAME_PREFERRED)
1933 {
1934 nField |= SfxFilterFlags::PREFERED;
1935 continue;
1936 }
1937 if (pNames[i] == FLAGNAME_STARTPRESENTATION)
1938 {
1939 nField |= SfxFilterFlags::STARTPRESENTATION;
1940 continue;
1941 }
1942 if (pNames[i] == FLAGNAME_SUPPORTSSIGNING)
1943 {
1944 nField |= SfxFilterFlags::SUPPORTSSIGNING;
1945 continue;
1946 }
1947 if (pNames[i] == FLAGNAME_READONLY)
1948 {
1949 nField |= SfxFilterFlags::OPENREADONLY;
1950 continue;
1951 }
1952 if (pNames[i] == FLAGNAME_SUPPORTSSELECTION)
1953 {
1954 nField |= SfxFilterFlags::SUPPORTSSELECTION;
1955 continue;
1956 }
1957 if (pNames[i] == FLAGNAME_TEMPLATE)
1958 {
1959 nField |= SfxFilterFlags::TEMPLATE;
1960 continue;
1961 }
1962 if (pNames[i] == FLAGNAME_TEMPLATEPATH)
1963 {
1964 nField |= SfxFilterFlags::TEMPLATEPATH;
1965 continue;
1966 }
1967 if (pNames[i] == FLAGNAME_COMBINED)
1968 {
1969 nField |= SfxFilterFlags::COMBINED;
1970 continue;
1971 }
1972 }
1973
1974 return nField;
1975}
1976
1977
1979 sal_Int32 nProp ,
1980 CacheItem& rItem )
1981{
1982 switch(nProp)
1983 {
1984 // Preferred
1985 case 0: rItem[PROPNAME_PREFERRED] <<= (sValue.toInt32() == 1);
1986 break;
1987 // MediaType
1988 case 1: rItem[PROPNAME_MEDIATYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
1989 break;
1990 // ClipboardFormat
1991 case 2: rItem[PROPNAME_CLIPBOARDFORMAT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
1992 break;
1993 // URLPattern
1995 break;
1996 // Extensions
1998 break;
1999 }
2000}
2001
2002
2004 sal_Int32 nProp ,
2005 CacheItem& rItem )
2006{
2007 switch(nProp)
2008 {
2009 // Order
2010 case 0: {
2011 sal_Int32 nOrder = sValue.toInt32();
2012 if (nOrder > 0)
2013 {
2014 SAL_WARN( "filter.config", "FilterCache::impl_interpretDataVal4Filter()\nCan not move Order value from filter to type on demand!");
2015 }
2016 }
2017 break;
2018 // Type
2019 case 1: rItem[PROPNAME_TYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2020 break;
2021 // DocumentService
2022 case 2: rItem[PROPNAME_DOCUMENTSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2023 break;
2024 // FilterService
2025 case 3: rItem[PROPNAME_FILTERSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2026 break;
2027 // Flags
2028 case 4: rItem[PROPNAME_FLAGS] <<= sValue.toInt32();
2029 break;
2030 // UserData
2032 break;
2033 // FileFormatVersion
2034 case 6: rItem[PROPNAME_FILEFORMATVERSION] <<= sValue.toInt32();
2035 break;
2036 // TemplateName
2037 case 7: rItem[PROPNAME_TEMPLATENAME] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2038 break;
2039 // [optional!] UIComponent
2040 case 8: rItem[PROPNAME_UICOMPONENT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2041 break;
2042 }
2043}
2044
2045/*-----------------------------------------------
2046 TODO work on a cache copy first, which can be flushed afterwards
2047 That would be useful to guarantee a consistent cache.
2048-----------------------------------------------*/
2049void FilterCache::impl_readOldFormat(std::unique_lock<std::mutex>& rGuard)
2050{
2051 // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
2052 // It's optional and should not disturb our normal work!
2053 // E.g. we must check, if the package exists...
2054 try
2055 {
2056 css::uno::Reference< css::uno::XInterface > xInt = impl_openConfig(rGuard, E_PROVIDER_OLD);
2057 css::uno::Reference< css::container::XNameAccess > xCfg(xInt, css::uno::UNO_QUERY_THROW);
2058
2059 OUString TYPES_SET("Types");
2060
2061 // May be there is no type set ...
2062 if (xCfg->hasByName(TYPES_SET))
2063 {
2064 css::uno::Reference< css::container::XNameAccess > xSet;
2065 xCfg->getByName(TYPES_SET) >>= xSet;
2066 const css::uno::Sequence< OUString > lItems = xSet->getElementNames();
2067 for (const OUString& rName : lItems)
2068 m_lTypes[rName] = impl_readOldItem(rGuard, xSet, E_TYPE, rName);
2069 }
2070
2071 OUString FILTER_SET("Filters");
2072 // May be there is no filter set ...
2073 if (xCfg->hasByName(FILTER_SET))
2074 {
2075 css::uno::Reference< css::container::XNameAccess > xSet;
2076 xCfg->getByName(FILTER_SET) >>= xSet;
2077 const css::uno::Sequence< OUString > lItems = xSet->getElementNames();
2078 for (const OUString& rName : lItems)
2079 m_lFilters[rName] = impl_readOldItem(rGuard, xSet, E_FILTER, rName);
2080 }
2081 }
2082 /* corrupt filter addon? Because it's external (optional) code... we can ignore it. Addon won't work then...
2083 but that seems to be acceptable.
2084 see #139088# for further information
2085 */
2086 catch(const css::uno::Exception&)
2087 {
2088 }
2089}
2090
2091CacheItem FilterCache::impl_readOldItem(std::unique_lock<std::mutex>& rGuard,
2092 const css::uno::Reference< css::container::XNameAccess >& xSet ,
2093 EItemType eType,
2094 const OUString& sItem)
2095{
2096 css::uno::Reference< css::container::XNameAccess > xItem;
2097 xSet->getByName(sItem) >>= xItem;
2098 if (!xItem.is())
2099 throw css::uno::Exception("Can not read old item.", css::uno::Reference< css::uno::XInterface >());
2100
2101 CacheItem aItem;
2102 aItem[PROPNAME_NAME] <<= sItem;
2103
2104 // Installed flag ...
2105 // Isn't used any longer!
2106
2107 // UIName
2108 impl_readPatchUINames(rGuard, xItem, aItem);
2109
2110 // Data
2111 OUString sData;
2112 std::vector<OUString> lData;
2113 xItem->getByName( "Data" ) >>= sData;
2114 lData = impl_tokenizeString(sData, ',');
2115 if (
2116 (sData.isEmpty()) ||
2117 (lData.empty() )
2118 )
2119 {
2120 throw css::uno::Exception( "Can not read old item property DATA.", css::uno::Reference< css::uno::XInterface >());
2121 }
2122
2123 sal_Int32 nProp = 0;
2124 for (auto const& prop : lData)
2125 {
2126 switch(eType)
2127 {
2128 case E_TYPE :
2129 impl_interpretDataVal4Type(prop, nProp, aItem);
2130 break;
2131
2132 case E_FILTER :
2133 impl_interpretDataVal4Filter(prop, nProp, aItem);
2134 break;
2135 default: break;
2136 }
2137 ++nProp;
2138 }
2139
2140 return aItem;
2141}
2142
2143
2144std::vector<OUString> FilterCache::impl_tokenizeString(std::u16string_view sData ,
2145 sal_Unicode cSeparator)
2146{
2147 std::vector<OUString> lData ;
2148 sal_Int32 nToken = 0;
2149 do
2150 {
2151 OUString sToken( o3tl::getToken(sData, 0, cSeparator, nToken) );
2152 lData.push_back(sToken);
2153 }
2154 while(nToken >= 0);
2155 return lData;
2156}
2157
2158#if OSL_DEBUG_LEVEL > 0
2159
2160
2161OUString FilterCache::impl_searchFrameLoaderForType(const OUString& sType) const
2162{
2163 for (auto const& frameLoader : m_lFrameLoaders)
2164 {
2165 const OUString& sItem = frameLoader.first;
2166 ::comphelper::SequenceAsHashMap lProps(frameLoader.second);
2167 const css::uno::Sequence<OUString> lTypes =
2168 lProps[PROPNAME_TYPES].get<css::uno::Sequence<OUString> >();
2169
2170 if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2171 return sItem;
2172 }
2173
2174 return OUString();
2175}
2176
2177
2178OUString FilterCache::impl_searchContentHandlerForType(const OUString& sType) const
2179{
2180 for (auto const& contentHandler : m_lContentHandlers)
2181 {
2182 const OUString& sItem = contentHandler.first;
2183 ::comphelper::SequenceAsHashMap lProps(contentHandler.second);
2184 const css::uno::Sequence<OUString> lTypes =
2185 lProps[PROPNAME_TYPES].get<css::uno::Sequence<OUString> >();
2186 if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2187 return sItem;
2188 }
2189
2190 return OUString();
2191}
2192#endif
2193
2194
2195bool FilterCache::impl_isModuleInstalled(std::unique_lock<std::mutex>& /*rGuard*/, const OUString& sModule)
2196{
2197 css::uno::Reference< css::container::XNameAccess > xCfg;
2198
2199 if (!m_xModuleCfg.is())
2200 {
2201 m_xModuleCfg = officecfg::Setup::Office::Factories::get();
2202 }
2203
2204 xCfg = m_xModuleCfg;
2205
2206 if (xCfg.is())
2207 return xCfg->hasByName(sModule);
2208
2209 return false;
2210}
2211
2212} // namespace filter
2213
2214/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
OUString getExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
::std::vector< OUString >::const_iterator getFallback(const ::std::vector< OUString > &rList, const OUString &rReference)
bool Matches(std::u16string_view rStr) const
iterator erase(iterator it)
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
iterator find(const OUString &rKey)
SequenceAsHashMapBase::iterator iterator
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
SequenceAsHashMapBase::const_iterator const_iterator
represent an item of a FilterCache instance.
Definition: cacheitem.hxx:40
css::uno::Sequence< css::beans::PropertyValue > getAsPackedPropertyValueList(bool bFinalized, bool bMandatory) const
convert this structure to a seq< PropertyValue > and ignore all empty properties!
Definition: cacheitem.cxx:80
void validateUINames(const OUString &sActLocale)
because we know two UIName properties (a list with all locales and the value for the current locale o...
Definition: cacheitem.cxx:47
implements a listener, which will update the global filter cache, if the underlying configuration wa ...
implements a cache, which contains all elements of our filter and type detection configuration.
Definition: filtercache.hxx:61
std::unique_ptr< FilterCache > clone() const
creates a copy of this container.
static void impl_interpretDataVal4Filter(const OUString &sValue, sal_Int32 nProp, CacheItem &rItem)
TODO.
std::vector< OUString > m_lChangedContentHandlers
bool hasItems(EItemType eType) const
indicates if the requested sub container contains some items.
void impl_load(std::unique_lock< std::mutex > &rGuard, EFillState eRequiredState)
load the underlying configuration into this cache.
css::uno::Reference< css::uno::XInterface > m_xConfigTypes
holds the used configuration provider alive, which provides access to the list of types.
void impl_readPatchUINames(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< css::container::XNameAccess > &xNode, CacheItem &rItem)
TODO.
css::uno::Reference< css::container::XNameAccess > m_xModuleCfg
readonly access to the module configuration of OOo
OUString impl_searchFrameLoaderForType(const OUString &sType) const
TODO.
std::vector< OUString > getMatchingItemsByProps(EItemType eType, o3tl::span< const css::beans::NamedValue > lIProps, o3tl::span< const css::beans::NamedValue > lEProps={}) const
return a list of key names for items, which match the specified criteria.
static css::uno::Reference< css::uno::XInterface > impl_createConfigAccess(std::unique_lock< std::mutex > &rGuard, const OUString &sRoot, bool bReadOnly, bool bLocalesMode)
tries to open the requested configuration root using the specified modi.
static EItemFlushState impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess > &xSet, const CacheItemList &rList, const OUString &sItem)
specify, which save operation is necessary for the specified item.
css::uno::Reference< css::uno::XInterface > m_xConfigFilters
holds the used configuration provider alive, which provides access to the list of filters.
static css::uno::Any impl_getDirectCFGValue(std::unique_lock< std::mutex > &rGuard, std::u16string_view sDirectKey)
reads the specified configuration key and return its value.
EFillState
indicates, which items already exists inside this cache and which not.
Definition: filtercache.hxx:96
CacheItemRegistration m_lURLPattern2Types
optimize mapping of URL pattern to a type representation, by using patterns as key and a list of inte...
std::vector< OUString > m_lChangedFilters
static std::vector< OUString > impl_tokenizeString(std::u16string_view sData, sal_Unicode cSeparator)
TODO.
CacheItem & impl_getItem(std::unique_lock< std::mutex > &rGuard, EItemType eType, const OUString &sItem)
static css::uno::Sequence< OUString > impl_convertFlagField2FlagNames(SfxFilterFlags nFlags)
convert a flag field value to its list representation of flag names.
const CacheItemList & impl_getItemList(std::unique_lock< std::mutex > &rGuard, EItemType eType) const
return a reference to one of our internal sub container, which contains items of the requested type.
CacheItemRegistration m_lExtensions2Types
optimize mapping of URL extensions to a type representation, by using extensions as key and a list of...
OUString m_sActLocale
contains the current locale of the office and will be used to work with localized configuration value...
void flush()
force writing of all changes (which was made after last flush was called) back to the configuration.
std::vector< OUString > m_lChangedTypes
TODO document me ...
~FilterCache()
standard dtor.
static void impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace > &xNode, const CacheItem &rItem)
TODO.
css::uno::Reference< css::uno::XInterface > m_xConfigOthers
holds the used configuration provider alive, which provides access to the list of other values needed...
static void impl_flushByList(const css::uno::Reference< css::container::XNameAccess > &xSet, EItemType eType, const CacheItemList &rCache, const std::vector< OUString > &lItems)
TODO.
void impl_loadSet(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< css::container::XNameAccess > &xConfig, EItemType eType, EReadOption eOption, CacheItemList *pCache)
read the specified config set into the cache.
static void removeStatePropsFromItem(CacheItem &aValue)
TODO document me.
std::vector< OUString > getItemNames(EItemType eType) const
return a list of all key names, which represent an item inside the specified sub container.
static SfxFilterFlags impl_convertFlagNames2FlagField(const css::uno::Sequence< OUString > &lNames)
convert a list of flag names to its int representation.
bool isFillState(EFillState eRequired) const
return the current fill state of this cache.
bool hasItem(EItemType eType, const OUString &sItem)
check if the required item exist inside this container.
void load(EFillState eRequired)
force special fill state of this cache.
CacheItemList::iterator impl_loadItemOnDemand(std::unique_lock< std::mutex > &rGuard, EItemType eType, const OUString &sItem)
try to load the requested item on demand from the underlying configuration layer.
EConfigProvider
TODO document me.
void refreshItem(EItemType eType, const OUString &sItem)
TODO document me ...
css::uno::Reference< css::uno::XInterface > impl_openConfig(std::unique_lock< std::mutex > &rGuard, EConfigProvider eProvide)
return a valid configuration update access to the underlying configuration package,...
css::uno::Sequence< OUString > m_aStandardProps[4]
standard property names for filter config keyed by EReadOption
CacheItemList m_lFrameLoaders
contains all loaded frame loader with its properties.
EItemType
identify the type of a container item.
Definition: filtercache.hxx:74
css::uno::Any getItemWithStateProps(EItemType eType, const OUString &sItem)
add some implicit properties to the given cache item reference.
void detectFlatForURL(const css::util::URL &aURL, FlatDetection &rFlatTypes) const
supports a flat type detection for given URL.
rtl::Reference< CacheUpdateListener > m_xFiltersChgListener
EFillState m_eFillState
contains status, which cache items/properties was already loaded from the underlying configuration.
EItemFlushState
indicates the state of a configuration set item.
@ E_ITEM_UNCHANGED
indicates an unchanged item (can occur e.g. if an item was added and(!) removed before it was flushed...
@ E_ITEM_REMOVED
indicates an item, which exists inside config layer but not inside our own cache
@ E_ITEM_ADDED
indicates an item, which does not exists inside config layer but inside our own cache
@ E_ITEM_CHANGED
indicates an item, which exists inside config layer and inside our own cache
EReadOption
regulate, which properties of a configured item will be read.
static void impl_interpretDataVal4Type(const OUString &sValue, sal_Int32 nProp, CacheItem &rItem)
TODO.
rtl::Reference< CacheUpdateListener > m_xTypesChglisteners
void removeItem(EItemType eType, const OUString &sItem)
TODO document me ...
void takeOver(const FilterCache &rClone)
copy the cache content or rClone back to this instance.
void impl_validateAndOptimize(std::unique_lock< std::mutex > &rGuard)
validate the whole cache and create structures for optimized items access.
bool impl_isModuleInstalled(std::unique_lock< std::mutex > &rGuard, const OUString &sModule)
check if the specified OOo module is installed.
CacheItemList m_lFilters
contains all loaded filters with its properties.
CacheItem impl_loadItem(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< css::container::XNameAccess > &xSet, EItemType eType, const OUString &sItem, EReadOption eOption)
read the specified container item from the given configuration set.
void impl_addItem2FlushList(EItemType eType, const OUString &sItem)
TODO.
void setItem(EItemType eType, const OUString &sItem, const CacheItem &aValue)
TODO document me ...
CacheItem impl_readOldItem(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< css::container::XNameAccess > &xSet, EItemType eType, const OUString &sItem)
TODO.
void impl_readOldFormat(std::unique_lock< std::mutex > &rGuard)
TODO.
CacheItem getItem(EItemType eType, const OUString &sItem)
return an item, which match the specified type and name.
CacheItemList m_lTypes
contains all loaded types with its properties.
static void impl_saveItem(const css::uno::Reference< css::container::XNameReplace > &xSet, EItemType eType, const CacheItem &aValue)
TODO.
std::vector< OUString > m_lChangedFrameLoaders
css::uno::Sequence< OUString > m_aTypeProps[4]
type property names for filter config keyed by EReadOption
CacheItemList m_lContentHandlers
contains all loaded content handler with its properties.
OUString impl_searchContentHandlerForType(const OUString &sType) const
static bool IsFuzzing()
constexpr OUStringLiteral FLAGNAME_IMPORT
Definition: constant.hxx:103
constexpr OUStringLiteral PROPNAME_FLAGS
Definition: constant.hxx:51
constexpr OUStringLiteral PROPNAME_USERDATA
Definition: constant.hxx:52
constexpr OUStringLiteral SERVICE_CONFIGURATIONACCESS
Definition: constant.hxx:123
constexpr OUStringLiteral FLAGNAME_TEMPLATE
Definition: constant.hxx:114
constexpr OUStringLiteral PROPNAME_MEDIATYPE
Definition: constant.hxx:38
constexpr OUStringLiteral CFGSET_TYPES
used to identify a set of items against the configuration API.
Definition: constant.hxx:75
constexpr OUStringLiteral SERVICE_CONFIGURATIONUPDATEACCESS
some uno service names.
Definition: constant.hxx:122
constexpr OUStringLiteral CFGPACKAGE_TD_TYPES
some configuration paths.
Definition: constant.hxx:127
constexpr OUStringLiteral PROPNAME_EXPORTEXTENSION
Definition: constant.hxx:55
constexpr OUStringLiteral PROPNAME_TEMPLATENAME
Definition: constant.hxx:53
constexpr OUStringLiteral FLAGNAME_ALIEN
Definition: constant.hxx:97
constexpr OUStringLiteral FLAGNAME_PREFERRED
Definition: constant.hxx:110
constexpr OUStringLiteral CFGSET_FILTERS
Definition: constant.hxx:76
constexpr OUStringLiteral PROPNAME_PREFERRED
Definition: constant.hxx:35
constexpr OUStringLiteral FLAGNAME_EXPORT
Definition: constant.hxx:101
constexpr OUStringLiteral PROPNAME_ENABLED
Definition: constant.hxx:56
constexpr OUStringLiteral PROPNAME_PREFERREDFILTER
Definition: constant.hxx:36
constexpr OUStringLiteral CFGDIRECTKEY_DEFAULTFRAMELOADER
Definition: constant.hxx:88
constexpr OUStringLiteral PROPNAME_FILTERSERVICE
Definition: constant.hxx:49
constexpr OUStringLiteral FLAGNAME_CONSULTSERVICE
Definition: constant.hxx:98
constexpr OUStringLiteral PROPNAME_DETECTSERVICE
Definition: constant.hxx:37
constexpr OUStringLiteral FLAGNAME_INTERNAL
Definition: constant.hxx:104
constexpr OUStringLiteral PROPNAME_TYPE
used to identify a filter item property against the configuration API and can be used at all name con...
Definition: constant.hxx:47
constexpr OUStringLiteral FLAGNAME_SUPPORTSSIGNING
Definition: constant.hxx:117
constexpr OUStringLiteral FLAGNAME_NOTINSTALLED
Definition: constant.hxx:106
constexpr OUStringLiteral PROPNAME_UINAME
used to identify a type item property against the configuration API and can be used at all name conta...
Definition: constant.hxx:33
constexpr OUStringLiteral FLAGNAME_GPGENCRYPTION
Definition: constant.hxx:102
constexpr OUStringLiteral PROPNAME_NAME
used to identify a some generic item properties against the configuration API and can be used at all ...
Definition: constant.hxx:27
constexpr OUStringLiteral PROPNAME_MANDATORY
Definition: constant.hxx:72
constexpr OUStringLiteral FLAGNAME_3RDPARTYFILTER
names of filter flags, sorted in alphabetical order
Definition: constant.hxx:96
constexpr OUStringLiteral PROPNAME_UICOMPONENT
Definition: constant.hxx:50
constexpr OUStringLiteral FLAGNAME_READONLY
Definition: constant.hxx:112
constexpr OUStringLiteral CFGDIRECTKEY_OFFICELOCALE
used to address some configuration keys directly.
Definition: constant.hxx:87
constexpr OUStringLiteral CFGSET_FRAMELOADERS
Definition: constant.hxx:77
constexpr OUStringLiteral CFGSET_CONTENTHANDLERS
Definition: constant.hxx:78
constexpr OUStringLiteral CFGPACKAGE_TD_OLD
Definition: constant.hxx:130
constexpr OUStringLiteral FLAGNAME_PACKED
Definition: constant.hxx:108
constexpr OUStringLiteral PROPNAME_URLPATTERN
Definition: constant.hxx:40
constexpr OUStringLiteral FLAGNAME_SUPPORTSSELECTION
Definition: constant.hxx:113
constexpr OUStringLiteral PROPNAME_CLIPBOARDFORMAT
Definition: constant.hxx:39
constexpr OUStringLiteral FLAGNAME_OWN
Definition: constant.hxx:107
constexpr OUStringLiteral FLAGNAME_PASSWORDTOMODIFY
Definition: constant.hxx:109
constexpr OUStringLiteral PROPNAME_FILEFORMATVERSION
Definition: constant.hxx:54
constexpr OUStringLiteral PROPNAME_UINAMES
Definition: constant.hxx:34
constexpr OUStringLiteral PROPNAME_TYPES
used to identify a frame loader or detect service item property against the configuration API and can...
Definition: constant.hxx:62
constexpr OUStringLiteral CFGPACKAGE_TD_FILTERS
Definition: constant.hxx:128
constexpr OUStringLiteral PROPNAME_DOCUMENTSERVICE
Definition: constant.hxx:48
constexpr OUStringLiteral FLAGNAME_NOTINFILEDIALOG
Definition: constant.hxx:105
constexpr OUStringLiteral PROPNAME_FINALIZED
implicit properties.
Definition: constant.hxx:71
constexpr OUStringLiteral CFGPACKAGE_TD_OTHERS
Definition: constant.hxx:129
constexpr OUStringLiteral FLAGNAME_TEMPLATEPATH
Definition: constant.hxx:115
constexpr OUStringLiteral FLAGNAME_EXOTIC
Definition: constant.hxx:118
constexpr OUStringLiteral FLAGNAME_DEFAULT
Definition: constant.hxx:99
constexpr OUStringLiteral FLAGNAME_COMBINED
Definition: constant.hxx:116
constexpr OUStringLiteral FLAGNAME_ENCRYPTION
Definition: constant.hxx:100
constexpr OUStringLiteral DEFAULT_OFFICELOCALE
some default values.
Definition: constant.hxx:134
constexpr OUStringLiteral FLAGNAME_STARTPRESENTATION
Definition: constant.hxx:111
constexpr OUStringLiteral PROPNAME_EXTENSIONS
Definition: constant.hxx:41
#define TOOLS_WARN_EXCEPTION(area, stream)
URL aURL
SfxFilterFlags
float u
Reference< XSingleServiceFactory > xFactory
DocumentType eType
OUString sName
bool bReadOnly
const char * pLocale
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
::std::vector< FlatDetectionInfo > FlatDetection
Definition: cacheitem.hxx:173
std::unordered_map< OUString, CacheItem > CacheItemList
represent an item list of a FilterCache instance.
Definition: cacheitem.hxx:129
Value
int i
Definition: gentoken.py:48
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
DefTokenId nToken
is used to collect all matching types of a URL during type detection.
Definition: cacheitem.hxx:157
E_TYPE
OUString Name
sal_uInt16 sal_Unicode