Line data Source code
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 "filtercache.hxx"
22 : #include "lateinitlistener.hxx"
23 : #include "macros.hxx"
24 : #include "constant.hxx"
25 : #include "cacheupdatelistener.hxx"
26 :
27 : /*TODO see using below ... */
28 : #define AS_ENABLE_FILTER_UINAMES
29 : #define WORKAROUND_EXCEPTION_PROBLEM
30 :
31 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
32 : #include <com/sun/star/util/XChangesBatch.hpp>
33 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 : #include <com/sun/star/beans/NamedValue.hpp>
36 : #include <com/sun/star/beans/XPropertySet.hpp>
37 : #include <com/sun/star/beans/XProperty.hpp>
38 : #include <com/sun/star/beans/PropertyValue.hpp>
39 : #include <com/sun/star/beans/Property.hpp>
40 : #include <com/sun/star/beans/PropertyAttribute.hpp>
41 : #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
42 : #include <comphelper/sequenceasvector.hxx>
43 : #include <comphelper/locale.hxx>
44 : #include <comphelper/processfactory.hxx>
45 :
46 : #include <unotools/configpaths.hxx>
47 : #include <rtl/ustrbuf.hxx>
48 : #include <rtl/logfile.hxx>
49 : #include <rtl/uri.hxx>
50 : #include <tools/urlobj.hxx>
51 : #include <tools/wldcrd.hxx>
52 :
53 : #include <comphelper/configurationhelper.hxx>
54 :
55 :
56 : namespace filter{
57 : namespace config{
58 :
59 54 : FilterCache::FilterCache()
60 : : BaseLock ( )
61 : , m_xSMGR (::comphelper::getProcessServiceFactory())
62 54 : , m_eFillState(E_CONTAINS_NOTHING )
63 : {
64 : RTL_LOGFILE_TRACE("{ (as96863) FilterCache lifetime");
65 54 : }
66 :
67 :
68 :
69 162 : FilterCache::~FilterCache()
70 : {
71 : RTL_LOGFILE_TRACE("} (as96863) FilterCache lifetime");
72 54 : if (m_xTypesChglisteners.is())
73 54 : m_xTypesChglisteners->stopListening();
74 54 : if (m_xFiltersChgListener.is())
75 54 : m_xFiltersChgListener->stopListening();
76 108 : }
77 :
78 :
79 :
80 0 : FilterCache* FilterCache::clone() const
81 : {
82 : // SAFE -> ----------------------------------
83 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
84 :
85 0 : FilterCache* pClone = new FilterCache();
86 :
87 : // Dont copy the configuration access points here.
88 : // They will be created on demand inside the cloned instance,
89 : // if they are needed.
90 :
91 0 : pClone->m_xSMGR = m_xSMGR;
92 :
93 0 : pClone->m_lTypes = m_lTypes;
94 0 : pClone->m_lDetectServices = m_lDetectServices;
95 0 : pClone->m_lFilters = m_lFilters;
96 0 : pClone->m_lFrameLoaders = m_lFrameLoaders;
97 0 : pClone->m_lContentHandlers = m_lContentHandlers;
98 0 : pClone->m_lExtensions2Types = m_lExtensions2Types;
99 0 : pClone->m_lURLPattern2Types = m_lURLPattern2Types;
100 :
101 0 : pClone->m_sActLocale = m_sActLocale;
102 0 : pClone->m_sFormatName = m_sFormatName;
103 0 : pClone->m_sFormatVersion = m_sFormatVersion;
104 :
105 0 : pClone->m_eFillState = m_eFillState;
106 :
107 0 : pClone->m_lChangedTypes = m_lChangedTypes;
108 0 : pClone->m_lChangedFilters = m_lChangedFilters;
109 0 : pClone->m_lChangedDetectServices = m_lChangedDetectServices;
110 0 : pClone->m_lChangedFrameLoaders = m_lChangedFrameLoaders;
111 0 : pClone->m_lChangedContentHandlers = m_lChangedContentHandlers;
112 :
113 0 : return pClone;
114 : // <- SAFE ----------------------------------
115 : }
116 :
117 :
118 :
119 0 : void FilterCache::takeOver(const FilterCache& rClone)
120 : {
121 : // SAFE -> ----------------------------------
122 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
123 :
124 : // a)
125 : // Dont copy the configuration access points here!
126 : // We must use our own ones ...
127 :
128 : // b)
129 : // Further we can ignore the uno service manager.
130 : // We should already have a valid instance.
131 :
132 : // c)
133 : // Take over only changed items!
134 : // Otherwise we risk the following scenario:
135 : // c1) clone_1 contains changed filters
136 : // c2) clone_2 container changed types
137 : // c3) clone_1 take over changed filters and unchanged types
138 : // c4) clone_2 take over unchanged filters(!) and changed types(!)
139 : // c5) c4 overwrites c3!
140 :
141 0 : if (rClone.m_lChangedTypes.size()>0)
142 0 : m_lTypes = rClone.m_lTypes;
143 0 : if (rClone.m_lChangedDetectServices.size()>0)
144 0 : m_lDetectServices = rClone.m_lDetectServices;
145 0 : if (rClone.m_lChangedFilters.size()>0)
146 0 : m_lFilters = rClone.m_lFilters;
147 0 : if (rClone.m_lChangedFrameLoaders.size()>0)
148 0 : m_lFrameLoaders = rClone.m_lFrameLoaders;
149 0 : if (rClone.m_lChangedContentHandlers.size()>0)
150 0 : m_lContentHandlers = rClone.m_lContentHandlers;
151 :
152 0 : m_lChangedTypes.clear();
153 0 : m_lChangedDetectServices.clear();
154 0 : m_lChangedFilters.clear();
155 0 : m_lChangedFrameLoaders.clear();
156 0 : m_lChangedContentHandlers.clear();
157 :
158 0 : m_sActLocale = rClone.m_sActLocale;
159 0 : m_sFormatName = rClone.m_sFormatName;
160 0 : m_sFormatVersion = rClone.m_sFormatVersion;
161 :
162 0 : m_eFillState = rClone.m_eFillState;
163 :
164 : // renew all dependencies and optimizations
165 : // Because we cant be shure, that changed filters on one clone
166 : // and changed types of another clone work together.
167 : // But here we can check against the lates changes ...
168 0 : impl_validateAndOptimize();
169 : // <- SAFE ----------------------------------
170 0 : }
171 :
172 :
173 :
174 52670 : void FilterCache::load(EFillState eRequired,
175 : #if OSL_DEBUG_LEVEL > 1
176 : sal_Bool bByThread
177 : #else
178 : sal_Bool
179 : #endif
180 : )
181 : throw(css::uno::Exception)
182 : {
183 : // SAFE -> ----------------------------------
184 52670 : ::osl::ResettableMutexGuard aLock(m_aLock);
185 :
186 : // check if required fill state is already reached ...
187 : // There is nothing to do then.
188 52670 : if ((m_eFillState & eRequired) == eRequired)
189 52670 : return;
190 :
191 : #if OSL_DEBUG_LEVEL > 1
192 : if (!bByThread && ((eRequired & E_CONTAINS_ALL) == E_CONTAINS_ALL))
193 : {
194 : OSL_FAIL("Who disturb our \"fill cache on demand\" feature and force loading of ALL data during office startup? Please optimize your code, so a full filled filter cache is not realy needed here!");
195 : }
196 : #endif
197 :
198 : // Otherwise load the missing items.
199 :
200 : // ------------------------------------------
201 : // a) load some const values from configration.
202 : // These values are needed there for loading
203 : // config items ...
204 : // Further we load some std items from the
205 : // configuration so we can try to load the first
206 : // office document with a minimal set of values.
207 244 : if (m_eFillState == E_CONTAINS_NOTHING)
208 : {
209 54 : impl_getDirectCFGValue(CFGDIRECTKEY_OFFICELOCALE) >>= m_sActLocale;
210 54 : if (m_sActLocale.isEmpty())
211 : {
212 : _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify office locale => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_OFFICELOCALE));
213 52 : m_sActLocale = DEFAULT_OFFICELOCALE;
214 : }
215 :
216 54 : impl_getDirectCFGValue(CFGDIRECTKEY_FORMATNAME) >>= m_sFormatName;
217 54 : if (m_sFormatName.isEmpty())
218 0 : impl_getDirectCFGValue(CFGDIRECTKEY_PRODUCTNAME) >>= m_sFormatName;
219 :
220 54 : if (m_sFormatName.isEmpty())
221 : {
222 : _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format name => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATNAME));
223 0 : m_sFormatName = DEFAULT_FORMATNAME;
224 : }
225 :
226 54 : impl_getDirectCFGValue(CFGDIRECTKEY_FORMATVERSION) >>= m_sFormatVersion;
227 54 : if (m_sFormatVersion.isEmpty())
228 : {
229 : _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format version => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATVERSION));
230 0 : m_sFormatVersion = DEFAULT_FORMATVERSION;
231 : }
232 :
233 : // Support the old configuration support. Read it only one times during office runtime!
234 54 : impl_readOldFormat();
235 :
236 : // enable "loadOnDemand" feature ...
237 : // Create uno listener, which waits for finishing the office startup
238 : // and starts a thread, which calls loadAll() at this filter cache.
239 : // Note: Its not a leak to create this listener with new here.
240 : // It kills itself after working!
241 54 : /* LateInitListener* pLateInit = */ new LateInitListener(comphelper::getComponentContext(m_xSMGR));
242 : }
243 :
244 : // ------------------------------------------
245 : // b) If the required fill state was not reached
246 : // but std values was already loaded ...
247 : // we must load some further missing items.
248 244 : impl_load(eRequired);
249 : // <- SAFE
250 : }
251 :
252 :
253 :
254 4876 : sal_Bool FilterCache::isFillState(FilterCache::EFillState eState) const
255 : throw(css::uno::Exception)
256 : {
257 : // SAFE ->
258 4876 : ::osl::ResettableMutexGuard aLock(m_aLock);
259 4876 : return ((m_eFillState & eState) == eState);
260 : // <- SAFE
261 : }
262 :
263 :
264 :
265 13948 : OUStringList FilterCache::getMatchingItemsByProps( EItemType eType ,
266 : const CacheItem& lIProps,
267 : const CacheItem& lEProps) const
268 : throw(css::uno::Exception)
269 : {
270 : // SAFE ->
271 13948 : ::osl::ResettableMutexGuard aLock(m_aLock);
272 :
273 : // search for right list
274 : // An exception is thrown - "eType" is unknown.
275 : // => rList will be valid everytimes next line is reached.
276 13948 : const CacheItemList& rList = impl_getItemList(eType);
277 :
278 13948 : OUStringList lKeys;
279 :
280 : // search items, which provides all needed properties of set "lIProps"
281 : // but not of set "lEProps"!
282 1547334 : for (CacheItemList::const_iterator pIt = rList.begin();
283 1031556 : pIt != rList.end() ;
284 : ++pIt )
285 : {
286 : _FILTER_CONFIG_LOG_1_("getMatchingProps for \"%s\" ...\n",
287 : _FILTER_CONFIG_TO_ASCII_(pIt->first))
288 505952 : if (
289 501830 : (pIt->second.haveProps(lIProps) ) &&
290 4122 : (pIt->second.dontHaveProps(lEProps))
291 : )
292 : {
293 4122 : lKeys.push_back(pIt->first);
294 : }
295 : }
296 :
297 13948 : return lKeys;
298 : // <- SAFE
299 : }
300 :
301 :
302 :
303 0 : sal_Bool FilterCache::hasItems(EItemType eType) const
304 : throw(css::uno::Exception)
305 : {
306 : // SAFE ->
307 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
308 :
309 : // search for right list
310 : // An exception is thrown - "eType" is unknown.
311 : // => rList will be valid everytimes next line is reached.
312 0 : const CacheItemList& rList = impl_getItemList(eType);
313 :
314 0 : return !rList.empty();
315 : // <- SAFE
316 : }
317 :
318 :
319 :
320 376 : OUStringList FilterCache::getItemNames(EItemType eType) const
321 : throw(css::uno::Exception)
322 : {
323 : // SAFE ->
324 376 : ::osl::ResettableMutexGuard aLock(m_aLock);
325 :
326 : // search for right list
327 : // An exception is thrown - "eType" is unknown.
328 : // => rList will be valid everytimes next line is reached.
329 376 : const CacheItemList& rList = impl_getItemList(eType);
330 :
331 376 : OUStringList lKeys;
332 108882 : for (CacheItemList::const_iterator pIt = rList.begin();
333 72588 : pIt != rList.end() ;
334 : ++pIt )
335 : {
336 35918 : lKeys.push_back(pIt->first);
337 : }
338 376 : return lKeys;
339 : // <- SAFE
340 : }
341 :
342 :
343 :
344 3027 : sal_Bool FilterCache::hasItem( EItemType eType,
345 : const ::rtl::OUString& sItem)
346 : throw(css::uno::Exception)
347 : {
348 : // SAFE ->
349 3027 : ::osl::ResettableMutexGuard aLock(m_aLock);
350 :
351 : // search for right list
352 : // An exception is thrown - "eType" is unknown.
353 : // => rList will be valid everytimes next line is reached.
354 3027 : const CacheItemList& rList = impl_getItemList(eType);
355 :
356 : // if item could not be found - check if it can be loaded
357 : // from the underlying configuration layer. Might it was not already
358 : // loaded into this FilterCache object before.
359 3027 : CacheItemList::const_iterator pIt = rList.find(sItem);
360 3027 : if (pIt != rList.end())
361 3015 : return sal_True;
362 :
363 : try
364 : {
365 12 : impl_loadItemOnDemand(eType, sItem);
366 : // no exception => item could be loaded!
367 0 : return sal_True;
368 : }
369 12 : catch(const css::container::NoSuchElementException&)
370 : {}
371 :
372 12 : return sal_False;
373 : // <- SAFE
374 : }
375 :
376 :
377 :
378 12463 : CacheItem FilterCache::getItem( EItemType eType,
379 : const ::rtl::OUString& sItem)
380 : throw(css::uno::Exception)
381 : {
382 : // SAFE ->
383 12463 : ::osl::ResettableMutexGuard aLock(m_aLock);
384 :
385 : // search for right list
386 : // An exception is thrown if "eType" is unknown.
387 : // => rList will be valid everytimes next line is reached.
388 12463 : CacheItemList& rList = impl_getItemList(eType);
389 :
390 : // check if item exists ...
391 12463 : CacheItemList::iterator pIt = rList.find(sItem);
392 12463 : if (pIt == rList.end())
393 : {
394 : // ... or load it on demand from the
395 : // underlying configuration layer.
396 : // Note: NoSuchElementException is thrown automaticly here if
397 : // item could not be loaded!
398 15 : pIt = impl_loadItemOnDemand(eType, sItem);
399 : }
400 :
401 : /* Workaround for #137955#
402 : Draw types and filters are installed ... but draw was disabled during setup.
403 : We must supress accessing these filters. Otherwise the office can crash.
404 : Solution for the next major release: do not install those filters !
405 : */
406 12457 : if (eType == E_FILTER)
407 : {
408 6043 : CacheItem& rFilter = pIt->second;
409 6043 : ::rtl::OUString sDocService;
410 6043 : rFilter[PROPNAME_DOCUMENTSERVICE] >>= sDocService;
411 :
412 : // In Standalone-Impress the module WriterWeb is not installed
413 : // but it is there to load help pages
414 6043 : bool bIsHelpFilter = sItem == "writer_web_HTML_help";
415 :
416 6043 : if ( !bIsHelpFilter && !impl_isModuleInstalled(sDocService) )
417 : {
418 0 : ::rtl::OUStringBuffer sMsg(256);
419 0 : sMsg.appendAscii("The requested filter '" );
420 0 : sMsg.append (sItem );
421 0 : sMsg.appendAscii("' exists ... but it shouldnt; because the corresponding OOo module was not installed.");
422 0 : throw css::container::NoSuchElementException(sMsg.makeStringAndClear(), css::uno::Reference< css::uno::XInterface >());
423 6043 : }
424 : }
425 :
426 12463 : return pIt->second;
427 : // <- SAFE
428 : }
429 :
430 :
431 :
432 0 : void FilterCache::removeItem( EItemType eType,
433 : const ::rtl::OUString& sItem)
434 : throw(css::uno::Exception)
435 : {
436 : // SAFE ->
437 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
438 :
439 : // search for right list
440 : // An exception is thrown - "eType" is unknown.
441 : // => rList will be valid everytimes next line is reached.
442 0 : CacheItemList& rList = impl_getItemList(eType);
443 :
444 0 : CacheItemList::iterator pItem = rList.find(sItem);
445 0 : if (pItem == rList.end())
446 0 : pItem = impl_loadItemOnDemand(eType, sItem); // throws NoSuchELementException!
447 0 : rList.erase(pItem);
448 :
449 0 : impl_addItem2FlushList(eType, sItem);
450 0 : }
451 :
452 :
453 :
454 0 : void FilterCache::setItem( EItemType eType ,
455 : const ::rtl::OUString& sItem ,
456 : const CacheItem& aValue)
457 : throw(css::uno::Exception)
458 : {
459 : // SAFE ->
460 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
461 :
462 : // search for right list
463 : // An exception is thrown - "eType" is unknown.
464 : // => rList will be valid everytimes next line is reached.
465 0 : CacheItemList& rList = impl_getItemList(eType);
466 :
467 : // name must be part of the property set too ... otherwhise our
468 : // container query cant work correctly
469 0 : CacheItem aItem = aValue;
470 0 : aItem[PROPNAME_NAME] <<= sItem;
471 0 : aItem.validateUINames(m_sActLocale);
472 :
473 : // remove implicit properties as e.g. FINALIZED or MANDATORY
474 : // They cant be saved here and must be readed on demand later, if they are needed.
475 0 : removeStatePropsFromItem(aItem);
476 :
477 0 : rList[sItem] = aItem;
478 :
479 0 : impl_addItem2FlushList(eType, sItem);
480 0 : }
481 :
482 : //-----------------------------------------------
483 0 : void FilterCache::refreshItem( EItemType eType,
484 : const ::rtl::OUString& sItem)
485 : throw(css::uno::Exception)
486 : {
487 : // SAFE ->
488 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
489 0 : impl_loadItemOnDemand(eType, sItem);
490 0 : }
491 :
492 :
493 :
494 9994 : void FilterCache::addStatePropsToItem( EItemType eType,
495 : const ::rtl::OUString& sItem,
496 : CacheItem& rItem)
497 : throw(css::uno::Exception)
498 : {
499 : // SAFE ->
500 9994 : ::osl::ResettableMutexGuard aLock(m_aLock);
501 :
502 : // Note: Opening of the configuration layer throws some exceptions
503 : // if it failed. So we dont must check any reference here ...
504 9994 : css::uno::Reference< css::container::XNameAccess > xPackage;
505 9994 : css::uno::Reference< css::container::XNameAccess > xSet;
506 9994 : switch(eType)
507 : {
508 : case E_TYPE :
509 : {
510 4503 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
511 4503 : xPackage->getByName(CFGSET_TYPES) >>= xSet;
512 : }
513 4503 : break;
514 :
515 : case E_FILTER :
516 : {
517 4983 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
518 4983 : xPackage->getByName(CFGSET_FILTERS) >>= xSet;
519 : }
520 4983 : break;
521 :
522 : case E_FRAMELOADER :
523 : {
524 : /* TODO
525 : Hack -->
526 : The default frame loader cant be located inside te normal set of frame loaders.
527 : Its an atomic property inside the misc cfg package. So we cant retrieve the information
528 : about FINALIZED and MANDATORY very easy ... :-(
529 : => set it to readonly/required everytimes :-)
530 : */
531 508 : css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
532 508 : ::rtl::OUString sDefaultFrameLoader;
533 1524 : if (
534 508 : (aDirectValue >>= sDefaultFrameLoader) &&
535 508 : (!sDefaultFrameLoader.isEmpty() ) &&
536 508 : (sItem.equals(sDefaultFrameLoader) )
537 : )
538 : {
539 508 : rItem[PROPNAME_FINALIZED] <<= sal_True;
540 508 : rItem[PROPNAME_MANDATORY] <<= sal_True;
541 9994 : return;
542 : }
543 : /* <-- HACK */
544 :
545 0 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
546 0 : xPackage->getByName(CFGSET_FRAMELOADERS) >>= xSet;
547 : }
548 0 : break;
549 :
550 : case E_CONTENTHANDLER :
551 : {
552 0 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
553 0 : xPackage->getByName(CFGSET_CONTENTHANDLERS) >>= xSet;
554 : }
555 0 : break;
556 0 : default: break;
557 : }
558 :
559 : try
560 : {
561 9486 : css::uno::Reference< css::beans::XProperty > xItem;
562 9486 : xSet->getByName(sItem) >>= xItem;
563 9486 : css::beans::Property aDescription = xItem->getAsProperty();
564 :
565 9486 : sal_Bool bFinalized = ((aDescription.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
566 9486 : sal_Bool bMandatory = ((aDescription.Attributes & css::beans::PropertyAttribute::REMOVEABLE) != css::beans::PropertyAttribute::REMOVEABLE);
567 :
568 9486 : rItem[PROPNAME_FINALIZED] <<= bFinalized;
569 9486 : rItem[PROPNAME_MANDATORY] <<= bMandatory;
570 : }
571 0 : catch(const css::container::NoSuchElementException&)
572 : {
573 : /* Ignore exceptions for missing elements inside configuration.
574 : May by the following reason exists:
575 : - The item does not exists inside the new configuration package org.openoffice.TypeDetection - but
576 : we got it from the old package org.openoffice.Office/TypeDetection. We dont migrate such items
577 : automaticly to the new format. Because it will disturb e.g. the deinstallation of an external filter
578 : package. Because such external filter can remove the old file - but not the automaticly created new one ...
579 :
580 : => mark item as FINALIZED / MANDATORY, we dont support writing to the old format
581 : */
582 0 : rItem[PROPNAME_FINALIZED] <<= sal_True;
583 0 : rItem[PROPNAME_MANDATORY] <<= sal_True;
584 9994 : }
585 :
586 : // <- SAFE
587 : }
588 :
589 :
590 :
591 0 : void FilterCache::removeStatePropsFromItem(CacheItem& rItem)
592 : throw(css::uno::Exception)
593 : {
594 0 : CacheItem::iterator pIt;
595 0 : pIt = rItem.find(PROPNAME_FINALIZED);
596 0 : if (pIt != rItem.end())
597 0 : rItem.erase(pIt);
598 0 : pIt = rItem.find(PROPNAME_MANDATORY);
599 0 : if (pIt != rItem.end())
600 0 : rItem.erase(pIt);
601 0 : }
602 :
603 :
604 :
605 0 : void FilterCache::flush()
606 : throw(css::uno::Exception)
607 : {
608 : // SAFE ->
609 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
610 :
611 : // renew all dependencies and optimizations
612 0 : impl_validateAndOptimize();
613 :
614 0 : if (m_lChangedTypes.size() > 0)
615 : {
616 0 : css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
617 0 : css::uno::Reference< css::container::XNameAccess > xSet ;
618 :
619 0 : xConfig->getByName(CFGSET_TYPES) >>= xSet;
620 0 : impl_flushByList(xSet, E_TYPE, m_lTypes, m_lChangedTypes);
621 :
622 0 : css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
623 0 : xFlush->commitChanges();
624 : }
625 :
626 0 : if (m_lChangedFilters.size() > 0)
627 : {
628 0 : css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
629 0 : css::uno::Reference< css::container::XNameAccess > xSet ;
630 :
631 0 : xConfig->getByName(CFGSET_FILTERS) >>= xSet;
632 0 : impl_flushByList(xSet, E_FILTER, m_lFilters, m_lChangedFilters);
633 :
634 0 : css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
635 0 : xFlush->commitChanges();
636 0 : }
637 :
638 : /*TODO FrameLoader/ContentHandler must be flushed here too ... */
639 0 : }
640 :
641 :
642 :
643 0 : void FilterCache::impl_flushByList(const css::uno::Reference< css::container::XNameAccess >& xSet ,
644 : EItemType eType ,
645 : const CacheItemList& rCache,
646 : const OUStringList& lItems)
647 : throw(css::uno::Exception)
648 : {
649 0 : css::uno::Reference< css::container::XNameContainer > xAddRemoveSet = css::uno::Reference< css::container::XNameContainer > (xSet, css::uno::UNO_QUERY);
650 0 : css::uno::Reference< css::container::XNameReplace > xReplaceeSet = css::uno::Reference< css::container::XNameReplace > (xSet, css::uno::UNO_QUERY);
651 0 : css::uno::Reference< css::lang::XSingleServiceFactory > xFactory = css::uno::Reference< css::lang::XSingleServiceFactory >(xSet, css::uno::UNO_QUERY);
652 :
653 0 : for (OUStringList::const_iterator pIt = lItems.begin();
654 0 : pIt != lItems.end() ;
655 : ++pIt )
656 : {
657 0 : const ::rtl::OUString& sItem = *pIt;
658 0 : EItemFlushState eState = impl_specifyFlushOperation(xSet, rCache, sItem);
659 0 : switch(eState)
660 : {
661 : case E_ITEM_REMOVED :
662 : {
663 0 : xAddRemoveSet->removeByName(sItem);
664 : }
665 0 : break;
666 :
667 : case E_ITEM_ADDED :
668 : {
669 0 : css::uno::Reference< css::container::XNameReplace > xItem (xFactory->createInstance(), css::uno::UNO_QUERY);
670 :
671 : // special case. no exception - but not a valid item => set must be finalized or mandatory!
672 : // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
673 0 : if (!xItem.is())
674 : throw css::uno::Exception(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cant add item. Set is finalized or mandatory!" )),
675 0 : css::uno::Reference< css::uno::XInterface >() );
676 :
677 0 : CacheItemList::const_iterator pItem = rCache.find(sItem);
678 0 : impl_saveItem(xItem, eType, pItem->second);
679 0 : xAddRemoveSet->insertByName(sItem, css::uno::makeAny(xItem));
680 : }
681 0 : break;
682 :
683 : case E_ITEM_CHANGED :
684 : {
685 0 : css::uno::Reference< css::container::XNameReplace > xItem;
686 0 : xSet->getByName(sItem) >>= xItem;
687 :
688 : // special case. no exception - but not a valid item => it must be finalized or mandatory!
689 : // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
690 0 : if (!xItem.is())
691 : throw css::uno::Exception(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cant change item. Its finalized or mandatory!" )),
692 0 : css::uno::Reference< css::uno::XInterface >() );
693 :
694 0 : CacheItemList::const_iterator pItem = rCache.find(sItem);
695 0 : impl_saveItem(xItem, eType, pItem->second);
696 : }
697 0 : break;
698 0 : default: break;
699 : }
700 0 : }
701 0 : }
702 :
703 :
704 :
705 5777 : void FilterCache::detectFlatForURL(const css::util::URL& aURL ,
706 : FlatDetection& rFlatTypes) const
707 : throw(css::uno::Exception)
708 : {
709 : // extract extension from URL, so it can be used directly as key into our hash map!
710 : // Note further: It must be converted to lower case, because the optimize hash
711 : // (which maps extensions to types) work with lower case key strings!
712 5777 : INetURLObject aParser (aURL.Main);
713 : ::rtl::OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
714 : sal_True ,
715 5777 : INetURLObject::DECODE_WITH_CHARSET);
716 5777 : sExtension = sExtension.toAsciiLowerCase();
717 :
718 : // SAFE -> ----------------------------------
719 5777 : ::osl::ResettableMutexGuard aLock(m_aLock);
720 :
721 : //*******************************************
722 : // i) Step over all well known URL pattern
723 : // and add registered types to the return list too
724 : // Do it as first one - because: if a type match by a
725 : // pattern a following deep detection can be supressed!
726 : // Further we can stop after first match ...
727 225312 : for (CacheItemRegistration::const_iterator pPattReg = m_lURLPattern2Types.begin();
728 150208 : pPattReg != m_lURLPattern2Types.end() ;
729 : ++pPattReg )
730 : {
731 69327 : WildCard aPatternCheck(pPattReg->first);
732 69327 : if (aPatternCheck.Matches(aURL.Main))
733 : {
734 5 : const OUStringList& rTypesForPattern = pPattReg->second;
735 :
736 5 : FlatDetectionInfo aInfo;
737 5 : aInfo.sType = *(rTypesForPattern.begin());
738 5 : aInfo.bMatchByPattern = sal_True;
739 :
740 5 : rFlatTypes.push_back(aInfo);
741 : // return;
742 : }
743 69327 : }
744 :
745 : //*******************************************
746 : // ii) search types matching to the given extension.
747 : // Copy every macthing type without changing its order!
748 : // Because preferred types was added as first one during
749 : // loading configuration.
750 5777 : CacheItemRegistration::const_iterator pExtReg = m_lExtensions2Types.find(sExtension);
751 5777 : if (pExtReg != m_lExtensions2Types.end())
752 : {
753 774 : const OUStringList& rTypesForExtension = pExtReg->second;
754 6354 : for (OUStringList::const_iterator pIt = rTypesForExtension.begin();
755 4236 : pIt != rTypesForExtension.end() ;
756 : ++pIt )
757 : {
758 1344 : FlatDetectionInfo aInfo;
759 1344 : aInfo.sType = *pIt;
760 1344 : aInfo.bMatchByExtension = sal_True;
761 :
762 1344 : rFlatTypes.push_back(aInfo);
763 1344 : }
764 : }
765 :
766 5777 : aLock.clear();
767 : // <- SAFE ----------------------------------
768 5777 : }
769 :
770 14324 : const CacheItemList& FilterCache::impl_getItemList(EItemType eType) const
771 : {
772 : // SAFE -> ----------------------------------
773 14324 : ::osl::ResettableMutexGuard aLock(m_aLock);
774 :
775 14324 : switch(eType)
776 : {
777 2889 : case E_TYPE : return m_lTypes ;
778 666 : case E_FILTER : return m_lFilters ;
779 5771 : case E_FRAMELOADER : return m_lFrameLoaders ;
780 4876 : case E_CONTENTHANDLER : return m_lContentHandlers;
781 122 : case E_DETECTSERVICE : return m_lDetectServices ;
782 :
783 : }
784 :
785 : throw css::uno::Exception(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown sub container requested." )),
786 0 : css::uno::Reference< css::uno::XInterface >() );
787 : // <- SAFE ----------------------------------
788 : }
789 :
790 15490 : CacheItemList& FilterCache::impl_getItemList(EItemType eType)
791 : {
792 : // SAFE -> ----------------------------------
793 15490 : ::osl::ResettableMutexGuard aLock(m_aLock);
794 :
795 15490 : switch(eType)
796 : {
797 6819 : case E_TYPE : return m_lTypes ;
798 7147 : case E_FILTER : return m_lFilters ;
799 1524 : case E_FRAMELOADER : return m_lFrameLoaders ;
800 0 : case E_CONTENTHANDLER : return m_lContentHandlers;
801 0 : case E_DETECTSERVICE : return m_lDetectServices ;
802 :
803 : }
804 :
805 : throw css::uno::Exception(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown sub container requested." )),
806 0 : css::uno::Reference< css::uno::XInterface >() );
807 : // <- SAFE ----------------------------------
808 : }
809 :
810 9797 : css::uno::Reference< css::uno::XInterface > FilterCache::impl_openConfig(EConfigProvider eProvider)
811 : throw(css::uno::Exception)
812 : {
813 9797 : ::osl::ResettableMutexGuard aLock(m_aLock);
814 :
815 9797 : ::rtl::OUString sPath ;
816 9797 : css::uno::Reference< css::uno::XInterface >* pConfig = 0;
817 9797 : css::uno::Reference< css::uno::XInterface > xOld ;
818 9797 : ::rtl::OString sRtlLog ;
819 :
820 9797 : switch(eProvider)
821 : {
822 : case E_PROVIDER_TYPES :
823 : {
824 4629 : if (m_xConfigTypes.is())
825 4575 : return m_xConfigTypes;
826 54 : sPath = CFGPACKAGE_TD_TYPES;
827 54 : pConfig = &m_xConfigTypes;
828 54 : sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_TYPES)");
829 : }
830 54 : break;
831 :
832 : case E_PROVIDER_FILTERS :
833 : {
834 5046 : if (m_xConfigFilters.is())
835 4992 : return m_xConfigFilters;
836 54 : sPath = CFGPACKAGE_TD_FILTERS;
837 54 : pConfig = &m_xConfigFilters;
838 54 : sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_FILTERS)");
839 : }
840 54 : break;
841 :
842 : case E_PROVIDER_OTHERS :
843 : {
844 68 : if (m_xConfigOthers.is())
845 24 : return m_xConfigOthers;
846 44 : sPath = CFGPACKAGE_TD_OTHERS;
847 44 : pConfig = &m_xConfigOthers;
848 44 : sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OTHERS)");
849 : }
850 44 : break;
851 :
852 : case E_PROVIDER_OLD :
853 : {
854 : // This special provider is used to work with
855 : // the old configuration format only. Its not cached!
856 54 : sPath = CFGPACKAGE_TD_OLD;
857 54 : pConfig = &xOld;
858 54 : sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OLD)");
859 : }
860 54 : break;
861 :
862 0 : default : throw css::uno::Exception(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "These configuration node isnt supported here for open!" )), 0);
863 : }
864 :
865 : {
866 : RTL_LOGFILE_CONTEXT(aLog, sRtlLog.getStr());
867 : *pConfig = impl_createConfigAccess(sPath ,
868 : sal_False, // bReadOnly
869 206 : sal_True ); // bLocalesMode
870 : }
871 :
872 :
873 : // Start listening for changes on that configuration access.
874 206 : switch(eProvider)
875 : {
876 : case E_PROVIDER_TYPES:
877 : {
878 54 : m_xTypesChglisteners.set(new CacheUpdateListener(m_xSMGR, *this, *pConfig, FilterCache::E_TYPE));
879 54 : m_xTypesChglisteners->startListening();
880 : }
881 54 : break;
882 : case E_PROVIDER_FILTERS:
883 : {
884 54 : m_xFiltersChgListener.set(new CacheUpdateListener(m_xSMGR, *this, *pConfig, FilterCache::E_FILTER));
885 54 : m_xFiltersChgListener->startListening();
886 : }
887 54 : break;
888 : default:
889 98 : break;
890 : }
891 :
892 206 : return *pConfig;
893 : }
894 :
895 :
896 :
897 914 : css::uno::Any FilterCache::impl_getDirectCFGValue(const ::rtl::OUString& sDirectKey)
898 : {
899 914 : ::rtl::OUString sRoot;
900 914 : ::rtl::OUString sKey ;
901 :
902 2742 : if (
903 914 : (!::utl::splitLastFromConfigurationPath(sDirectKey, sRoot, sKey)) ||
904 914 : (sRoot.isEmpty() ) ||
905 914 : (sKey.isEmpty() )
906 : )
907 0 : return css::uno::Any();
908 :
909 : css::uno::Reference< css::uno::XInterface > xCfg = impl_createConfigAccess(sRoot ,
910 : sal_True , // bReadOnly
911 914 : sal_False); // bLocalesMode
912 914 : if (!xCfg.is())
913 0 : return css::uno::Any();
914 :
915 914 : css::uno::Reference< css::container::XNameAccess > xAccess(xCfg, css::uno::UNO_QUERY);
916 914 : if (!xAccess.is())
917 0 : return css::uno::Any();
918 :
919 914 : css::uno::Any aValue;
920 : try
921 : {
922 914 : aValue = xAccess->getByName(sKey);
923 : }
924 0 : catch(const css::uno::RuntimeException&)
925 0 : { throw; }
926 : #if OSL_DEBUG_LEVEL > 0
927 : catch(const css::uno::Exception& ex)
928 : #else
929 0 : catch(const css::uno::Exception&)
930 : #endif
931 : {
932 : #if OSL_DEBUG_LEVEL > 0
933 : OSL_FAIL(::rtl::OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
934 : #endif
935 0 : aValue.clear();
936 : }
937 :
938 914 : return aValue;
939 : }
940 :
941 :
942 :
943 1120 : css::uno::Reference< css::uno::XInterface > FilterCache::impl_createConfigAccess(const ::rtl::OUString& sRoot ,
944 : sal_Bool bReadOnly ,
945 : sal_Bool bLocalesMode)
946 : {
947 : // SAFE ->
948 1120 : ::osl::ResettableMutexGuard aLock(m_aLock);
949 :
950 1120 : css::uno::Reference< css::uno::XInterface > xCfg;
951 :
952 : try
953 : {
954 : css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
955 : css::configuration::theDefaultProvider::get(
956 1120 : comphelper::getComponentContext(m_xSMGR)));
957 :
958 1120 : ::comphelper::SequenceAsVector< css::uno::Any > lParams;
959 1120 : css::beans::NamedValue aParam;
960 :
961 : // set root path
962 1120 : aParam.Name = _FILTER_CONFIG_FROM_ASCII_("nodepath");
963 1120 : aParam.Value <<= sRoot;
964 1120 : lParams.push_back(css::uno::makeAny(aParam));
965 :
966 : // enable "all locales mode" ... if required
967 1120 : if (bLocalesMode)
968 : {
969 206 : aParam.Name = _FILTER_CONFIG_FROM_ASCII_("locale");
970 206 : aParam.Value <<= _FILTER_CONFIG_FROM_ASCII_("*" );
971 206 : lParams.push_back(css::uno::makeAny(aParam));
972 : }
973 :
974 : // open it
975 1120 : if (bReadOnly)
976 914 : xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS, lParams.getAsConstList());
977 : else
978 206 : xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS, lParams.getAsConstList());
979 :
980 : // If configuration could not be opened ... but factory method does not throwed an exception
981 : // trigger throwing of our own CorruptedFilterConfigurationException.
982 : // Let message empty. The normal exception text show enough informations to the user.
983 1120 : if (! xCfg.is())
984 : throw css::uno::Exception(
985 : _FILTER_CONFIG_FROM_ASCII_("Got NULL reference on opening configuration file ... but no exception."),
986 0 : css::uno::Reference< css::uno::XInterface >());
987 : }
988 0 : catch(const css::uno::Exception& ex)
989 : {
990 : throw css::document::CorruptedFilterConfigurationException(
991 0 : "filter configuration, caught: " + ex.Message,
992 : css::uno::Reference< css::uno::XInterface >(),
993 0 : ex.Message);
994 : }
995 :
996 1120 : return xCfg;
997 : // <- SAFE
998 : }
999 :
1000 :
1001 :
1002 244 : void FilterCache::impl_validateAndOptimize()
1003 : throw(css::uno::Exception)
1004 : {
1005 : // SAFE ->
1006 244 : ::osl::ResettableMutexGuard aLock(m_aLock);
1007 :
1008 : RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::impl_validateAndOptimize");
1009 :
1010 : // First check if any filter or type could be readed
1011 : // from the underlying configuration!
1012 244 : sal_Bool bSomeTypesShouldExist = ((m_eFillState & E_CONTAINS_STANDARD ) == E_CONTAINS_STANDARD );
1013 244 : sal_Bool bAllFiltersShouldExist = ((m_eFillState & E_CONTAINS_FILTERS ) == E_CONTAINS_FILTERS );
1014 :
1015 : #if OSL_DEBUG_LEVEL > 0
1016 :
1017 : sal_Int32 nWarnings = 0;
1018 :
1019 : // sal_Bool bAllTypesShouldExist = ((m_eFillState & E_CONTAINS_TYPES ) == E_CONTAINS_TYPES );
1020 : sal_Bool bAllLoadersShouldExist = ((m_eFillState & E_CONTAINS_FRAMELOADERS ) == E_CONTAINS_FRAMELOADERS );
1021 : sal_Bool bAllHandlersShouldExist = ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS);
1022 : #endif
1023 :
1024 602 : if (
1025 : (
1026 : (bSomeTypesShouldExist) &&
1027 244 : (m_lTypes.size() < 1 )
1028 : ) ||
1029 : (
1030 : (bAllFiltersShouldExist) &&
1031 114 : (m_lFilters.size() < 1 )
1032 : )
1033 : )
1034 : {
1035 : throw css::document::CorruptedFilterConfigurationException(
1036 : "filter configuration: the list of types or filters is empty",
1037 : css::uno::Reference< css::uno::XInterface >(),
1038 0 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The list of types or filters is empty." )));
1039 : }
1040 :
1041 : // Create a log for all detected problems, which
1042 : // occur in the next few lines.
1043 : // If there are some real errors throw a RuntimException!
1044 : // If there are some warnings only, show an assertion.
1045 244 : sal_Int32 nErrors = 0;
1046 244 : ::rtl::OUStringBuffer sLog(256);
1047 :
1048 244 : CacheItemList::iterator pIt;
1049 :
1050 31740 : for (pIt = m_lTypes.begin(); pIt != m_lTypes.end(); ++pIt)
1051 : {
1052 31496 : ::rtl::OUString sType = pIt->first;
1053 31496 : CacheItem aType = pIt->second;
1054 :
1055 : // create list of all known detect services / frame loader / content handler on demand
1056 : // Because these informations are available as type properties!
1057 31496 : ::rtl::OUString sDetectService;
1058 31496 : aType[PROPNAME_DETECTSERVICE ] >>= sDetectService;
1059 31496 : if (!sDetectService.isEmpty())
1060 29056 : impl_resolveItem4TypeRegistration(&m_lDetectServices, sDetectService, sType);
1061 :
1062 : // get its registration for file Extensions AND(!) URLPattern ...
1063 : // It doesnt matter if these items exists or if our
1064 : // used index access create some default ones ...
1065 : // only in case there is no filled set of Extensions AND
1066 : // no filled set of URLPattern -> we must try to remove this invalid item
1067 : // from this cache!
1068 31496 : css::uno::Sequence< ::rtl::OUString > lExtensions;
1069 31496 : css::uno::Sequence< ::rtl::OUString > lURLPattern;
1070 31496 : aType[PROPNAME_EXTENSIONS] >>= lExtensions;
1071 31496 : aType[PROPNAME_URLPATTERN] >>= lURLPattern;
1072 31496 : sal_Int32 ce = lExtensions.getLength();
1073 31496 : sal_Int32 cu = lURLPattern.getLength();
1074 :
1075 : #if OSL_DEBUG_LEVEL > 0
1076 :
1077 : ::rtl::OUString sInternalTypeNameCheck;
1078 : aType[PROPNAME_NAME] >>= sInternalTypeNameCheck;
1079 : if (!sInternalTypeNameCheck.equals(sType))
1080 : {
1081 : sLog.appendAscii("Warning\t:\t");
1082 : sLog.appendAscii("The type \"" );
1083 : sLog.append (sType );
1084 : sLog.appendAscii("\" does support the property \"Name\" correctly.\n");
1085 : ++nWarnings;
1086 : }
1087 :
1088 : if (!ce && !cu)
1089 : {
1090 : sLog.appendAscii("Warning\t:\t");
1091 : sLog.appendAscii("The type \"" );
1092 : sLog.append (sType );
1093 : sLog.appendAscii("\" does not contain any URL pattern nor any extensions.\n");
1094 : ++nWarnings;
1095 : }
1096 : #endif
1097 :
1098 : // create an optimized registration for this type to
1099 : // its set list of extensions/url pattern. If its a "normal" type
1100 : // set it at the end of this optimized list. But if its
1101 : // a "Preferred" one - set it to the front of this list.
1102 : // Of course multiple "Preferred" registrations can occur
1103 : // (they shouldn't - but they can!) ... Ignore it. The last
1104 : // preferred type is useable in the same manner then every
1105 : // other type!
1106 31496 : sal_Bool bPreferred = sal_False;
1107 31496 : aType[PROPNAME_PREFERRED] >>= bPreferred;
1108 :
1109 31496 : const ::rtl::OUString* pExtensions = lExtensions.getConstArray();
1110 75680 : for (sal_Int32 e=0; e<ce; ++e)
1111 : {
1112 : // Note: We must be sure that address the right hash entry
1113 : // does not depend from any upper/lower case problems ...
1114 44184 : ::rtl::OUString sNormalizedExtension = pExtensions[e].toAsciiLowerCase();
1115 :
1116 44184 : OUStringList& lTypesForExtension = m_lExtensions2Types[sNormalizedExtension];
1117 44184 : if (::std::find(lTypesForExtension.begin(), lTypesForExtension.end(), sType) != lTypesForExtension.end())
1118 34406 : continue;
1119 :
1120 9778 : if (bPreferred)
1121 2054 : lTypesForExtension.insert(lTypesForExtension.begin(), sType);
1122 : else
1123 7724 : lTypesForExtension.push_back(sType);
1124 44184 : }
1125 :
1126 31496 : const ::rtl::OUString* pURLPattern = lURLPattern.getConstArray();
1127 34434 : for (sal_Int32 u=0; u<cu; ++u)
1128 : {
1129 2938 : OUStringList& lTypesForURLPattern = m_lURLPattern2Types[pURLPattern[u]];
1130 2938 : if (::std::find(lTypesForURLPattern.begin(), lTypesForURLPattern.end(), sType) != lTypesForURLPattern.end())
1131 2288 : continue;
1132 :
1133 650 : if (bPreferred)
1134 0 : lTypesForURLPattern.insert(lTypesForURLPattern.begin(), sType);
1135 : else
1136 650 : lTypesForURLPattern.push_back(sType);
1137 : }
1138 :
1139 : #if OSL_DEBUG_LEVEL > 0
1140 :
1141 : // Dont check cross references between types and filters, if
1142 : // not all filters read from disk!
1143 : // OK - this cache can read single filters on demand too ...
1144 : // but then the fill state of this cache shouldnt be set to E_CONTAINS_FILTERS!
1145 : if (!bAllFiltersShouldExist)
1146 : continue;
1147 :
1148 : ::rtl::OUString sPrefFilter;
1149 : aType[PROPNAME_PREFERREDFILTER] >>= sPrefFilter;
1150 : if (sPrefFilter.isEmpty())
1151 : {
1152 : // OK - there is no filter for this type. But thats not an error.
1153 : // May be it can be handled by a ContentHandler ...
1154 : // But at this time its not guaranteed that there is any ContentHandler
1155 : // or FrameLoader inside this cache ... but on disk ...
1156 : sal_Bool bReferencedByLoader = sal_True;
1157 : sal_Bool bReferencedByHandler = sal_True;
1158 : if (bAllLoadersShouldExist)
1159 : bReferencedByLoader = !impl_searchFrameLoaderForType(sType).isEmpty();
1160 :
1161 : if (bAllHandlersShouldExist)
1162 : bReferencedByHandler = !impl_searchContentHandlerForType(sType).isEmpty();
1163 :
1164 : if (
1165 : (!bReferencedByLoader ) &&
1166 : (!bReferencedByHandler)
1167 : )
1168 : {
1169 : sLog.appendAscii("Warning\t:\t" );
1170 : sLog.appendAscii("The type \"" );
1171 : sLog.append (sType );
1172 : sLog.appendAscii("\" isnt used by any filter, loader or content handler.\n");
1173 : ++nWarnings;
1174 : }
1175 : }
1176 :
1177 : if (!sPrefFilter.isEmpty())
1178 : {
1179 : CacheItemList::const_iterator pIt2 = m_lFilters.find(sPrefFilter);
1180 : if (pIt2 == m_lFilters.end())
1181 : {
1182 : if (bAllFiltersShouldExist)
1183 : {
1184 : ++nWarnings; // preferred filters can point to a non-installed office module ! no error ... it's a warning only .-(
1185 : sLog.appendAscii("error\t:\t");
1186 : }
1187 : else
1188 : {
1189 : ++nWarnings;
1190 : sLog.appendAscii("warning\t:\t");
1191 : }
1192 :
1193 : sLog.appendAscii("The type \"" );
1194 : sLog.append (sType );
1195 : sLog.appendAscii("\" points to an invalid filter \"");
1196 : sLog.append (sPrefFilter );
1197 : sLog.appendAscii("\".\n" );
1198 :
1199 : continue;
1200 : }
1201 :
1202 : CacheItem aPrefFilter = pIt2->second;
1203 : ::rtl::OUString sFilterTypeReg;
1204 : aPrefFilter[PROPNAME_TYPE] >>= sFilterTypeReg;
1205 : if (sFilterTypeReg != sType)
1206 : {
1207 : sLog.appendAscii("error\t:\t" );
1208 : sLog.appendAscii("The preferred filter \"" );
1209 : sLog.append (sPrefFilter );
1210 : sLog.appendAscii("\" of type \"" );
1211 : sLog.append (sType );
1212 : sLog.appendAscii("is registered for another type \"");
1213 : sLog.append (sFilterTypeReg );
1214 : sLog.appendAscii("\".\n" );
1215 : ++nErrors;
1216 : }
1217 :
1218 : sal_Int32 nFlags = 0;
1219 : aPrefFilter[PROPNAME_FLAGS] >>= nFlags;
1220 : if ((nFlags & FLAGVAL_IMPORT) != FLAGVAL_IMPORT)
1221 : {
1222 : sLog.appendAscii("error\t:\t" );
1223 : sLog.appendAscii("The preferred filter \"" );
1224 : sLog.append (sPrefFilter );
1225 : sLog.appendAscii("\" of type \"" );
1226 : sLog.append (sType );
1227 : sLog.appendAscii("\" is not an IMPORT filter!\n");
1228 : ++nErrors;
1229 : }
1230 :
1231 : ::rtl::OUString sInternalFilterNameCheck;
1232 : aPrefFilter[PROPNAME_NAME] >>= sInternalFilterNameCheck;
1233 : if (!sInternalFilterNameCheck.equals(sPrefFilter))
1234 : {
1235 : sLog.appendAscii("Warning\t:\t" );
1236 : sLog.appendAscii("The filter \"" );
1237 : sLog.append (sPrefFilter );
1238 : sLog.appendAscii("\" does support the property \"Name\" correctly.\n");
1239 : ++nWarnings;
1240 : }
1241 : }
1242 : #endif
1243 31496 : }
1244 :
1245 : // create dependencies between the global default frame loader
1246 : // and all types (and of course if registered filters), which
1247 : // does not registered for any other loader.
1248 244 : css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
1249 244 : ::rtl::OUString sDefaultFrameLoader;
1250 :
1251 488 : if (
1252 244 : (!(aDirectValue >>= sDefaultFrameLoader)) ||
1253 244 : (sDefaultFrameLoader.isEmpty() )
1254 : )
1255 : {
1256 0 : sLog.appendAscii("error\t:\t" );
1257 0 : sLog.appendAscii("There is no valid default frame loader!?\n");
1258 0 : ++nErrors;
1259 : }
1260 :
1261 : // a) get list of all well known types
1262 : // b) step over all well known frame loader services
1263 : // and remove all types from list a), which already
1264 : // referenced by a loader b)
1265 244 : OUStringList lTypes = getItemNames(E_TYPE);
1266 3282 : for ( pIt = m_lFrameLoaders.begin();
1267 2188 : pIt != m_lFrameLoaders.end() ;
1268 : ++pIt )
1269 : {
1270 : // Note: of course the default loader must be ignored here.
1271 : // Because we replace its registration later completly with all
1272 : // types, which are not referenced by any other loader.
1273 : // So we can avaoid our code against the complexity of a diff!
1274 850 : ::rtl::OUString sLoader = pIt->first;
1275 850 : if (sLoader.equals(sDefaultFrameLoader))
1276 190 : continue;
1277 :
1278 660 : CacheItem& rLoader = pIt->second;
1279 660 : css::uno::Any& rTypesReg = rLoader[PROPNAME_TYPES];
1280 660 : OUStringList lTypesReg (rTypesReg);
1281 :
1282 5940 : for (OUStringList::const_iterator pTypesReg = lTypesReg.begin();
1283 3960 : pTypesReg != lTypesReg.end() ;
1284 : ++pTypesReg )
1285 : {
1286 1320 : OUStringList::iterator pTypeCheck = ::std::find(lTypes.begin(), lTypes.end(), *pTypesReg);
1287 1320 : if (pTypeCheck != lTypes.end())
1288 825 : lTypes.erase(pTypeCheck);
1289 : }
1290 660 : }
1291 :
1292 244 : CacheItem& rDefaultLoader = m_lFrameLoaders[sDefaultFrameLoader];
1293 244 : rDefaultLoader[PROPNAME_NAME ] <<= sDefaultFrameLoader;
1294 244 : rDefaultLoader[PROPNAME_TYPES] <<= lTypes.getAsConstList();
1295 :
1296 244 : ::rtl::OUString sLogOut = sLog.makeStringAndClear();
1297 : OSL_ENSURE(!nErrors, ::rtl::OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1298 244 : if (nErrors>0)
1299 : throw css::document::CorruptedFilterConfigurationException(
1300 : "filter configuration: " + sLogOut,
1301 : css::uno::Reference< css::uno::XInterface >(),
1302 0 : sLogOut);
1303 244 : OSL_ENSURE(!nWarnings, ::rtl::OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1304 :
1305 : // <- SAFE
1306 244 : }
1307 :
1308 :
1309 :
1310 0 : void FilterCache::impl_addItem2FlushList( EItemType eType,
1311 : const ::rtl::OUString& sItem)
1312 : throw(css::uno::Exception)
1313 : {
1314 0 : OUStringList* pList = 0;
1315 0 : switch(eType)
1316 : {
1317 : case E_TYPE :
1318 0 : pList = &m_lChangedTypes;
1319 0 : break;
1320 :
1321 : case E_FILTER :
1322 0 : pList = &m_lChangedFilters;
1323 0 : break;
1324 :
1325 : case E_FRAMELOADER :
1326 0 : pList = &m_lChangedFrameLoaders;
1327 0 : break;
1328 :
1329 : case E_CONTENTHANDLER :
1330 0 : pList = &m_lChangedContentHandlers;
1331 0 : break;
1332 :
1333 : case E_DETECTSERVICE :
1334 0 : pList = &m_lChangedDetectServices;
1335 0 : break;
1336 :
1337 0 : default : throw css::uno::Exception(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unsupported item type" )), 0);
1338 : }
1339 :
1340 0 : OUStringList::const_iterator pItem = ::std::find(pList->begin(), pList->end(), sItem);
1341 0 : if (pItem == pList->end())
1342 0 : pList->push_back(sItem);
1343 0 : }
1344 :
1345 :
1346 :
1347 0 : FilterCache::EItemFlushState FilterCache::impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1348 : const CacheItemList& rList,
1349 : const ::rtl::OUString& sItem)
1350 : throw(css::uno::Exception)
1351 : {
1352 0 : sal_Bool bExistsInConfigLayer = xSet->hasByName(sItem);
1353 0 : sal_Bool bExistsInMemory = (rList.find(sItem) != rList.end());
1354 :
1355 0 : EItemFlushState eState( E_ITEM_UNCHANGED );
1356 :
1357 : // !? ... such situation can occur, if an item was added and(!) removed before it was flushed :-)
1358 0 : if (!bExistsInConfigLayer && !bExistsInMemory)
1359 0 : eState = E_ITEM_UNCHANGED;
1360 : else
1361 0 : if (!bExistsInConfigLayer && bExistsInMemory)
1362 0 : eState = E_ITEM_ADDED;
1363 : else
1364 0 : if (bExistsInConfigLayer && bExistsInMemory)
1365 0 : eState = E_ITEM_CHANGED;
1366 : else
1367 0 : if (bExistsInConfigLayer && !bExistsInMemory)
1368 0 : eState = E_ITEM_REMOVED;
1369 :
1370 0 : return eState;
1371 : }
1372 :
1373 :
1374 :
1375 29056 : void FilterCache::impl_resolveItem4TypeRegistration( CacheItemList* pList,
1376 : const ::rtl::OUString& sItem,
1377 : const ::rtl::OUString& sType)
1378 : throw(css::uno::Exception)
1379 : {
1380 29056 : CacheItem& rItem = (*pList)[sItem];
1381 : // In case its a new created entry (automaticly done by the boost::unordered_map index operator!)
1382 : // we must be shure, that this entry has its own name as property available.
1383 : // Its needed later at our container interface!
1384 29056 : rItem[PROPNAME_NAME] <<= sItem;
1385 :
1386 29056 : OUStringList lTypeRegs(rItem[PROPNAME_TYPES]);
1387 29056 : if (::std::find(lTypeRegs.begin(), lTypeRegs.end(), sType) == lTypeRegs.end())
1388 : {
1389 6430 : lTypeRegs.push_back(sType);
1390 6430 : rItem[PROPNAME_TYPES] <<= lTypeRegs.getAsConstList();
1391 29056 : }
1392 29056 : }
1393 :
1394 :
1395 :
1396 244 : void FilterCache::impl_load(EFillState eRequiredState)
1397 : throw(css::uno::Exception)
1398 : {
1399 : // SAFE ->
1400 244 : ::osl::ResettableMutexGuard aLock(m_aLock);
1401 :
1402 : // Attention: Detect services are part of the standard set!
1403 : // So there is no need to handle it seperatly.
1404 :
1405 : // ------------------------------------------
1406 : // a) The standard set of config value is needed.
1407 244 : if (
1408 : ((eRequiredState & E_CONTAINS_STANDARD) == E_CONTAINS_STANDARD) &&
1409 : ((m_eFillState & E_CONTAINS_STANDARD) != E_CONTAINS_STANDARD)
1410 : )
1411 : {
1412 : // Attention! If config couldnt be opened successfully
1413 : // and exception os thrown automaticly and must be forwarded
1414 : // to our calli ...
1415 54 : css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1416 : {
1417 : RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load std");
1418 54 : impl_loadSet(xTypes, E_TYPE, E_READ_STANDARD, &m_lTypes);
1419 54 : }
1420 : }
1421 :
1422 : // ------------------------------------------
1423 : // b) We need all type informations ...
1424 244 : if (
1425 : ((eRequiredState & E_CONTAINS_TYPES) == E_CONTAINS_TYPES) &&
1426 : ((m_eFillState & E_CONTAINS_TYPES) != E_CONTAINS_TYPES)
1427 : )
1428 : {
1429 : // Attention! If config couldnt be opened successfully
1430 : // and exception os thrown automaticly and must be forwarded
1431 : // to our calli ...
1432 54 : css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1433 : {
1434 : RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all types");
1435 54 : impl_loadSet(xTypes, E_TYPE, E_READ_UPDATE, &m_lTypes);
1436 54 : }
1437 : }
1438 :
1439 : // ------------------------------------------
1440 : // c) We need all filter informations ...
1441 244 : if (
1442 : ((eRequiredState & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) &&
1443 : ((m_eFillState & E_CONTAINS_FILTERS) != E_CONTAINS_FILTERS)
1444 : )
1445 : {
1446 : // Attention! If config couldnt be opened successfully
1447 : // and exception os thrown automaticly and must be forwarded
1448 : // to our calli ...
1449 54 : css::uno::Reference< css::container::XNameAccess > xFilters(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
1450 : {
1451 : RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all filters");
1452 54 : impl_loadSet(xFilters, E_FILTER, E_READ_ALL, &m_lFilters);
1453 54 : }
1454 : }
1455 :
1456 : // ------------------------------------------
1457 : // c) We need all frame loader informations ...
1458 244 : if (
1459 : ((eRequiredState & E_CONTAINS_FRAMELOADERS) == E_CONTAINS_FRAMELOADERS) &&
1460 : ((m_eFillState & E_CONTAINS_FRAMELOADERS) != E_CONTAINS_FRAMELOADERS)
1461 : )
1462 : {
1463 : // Attention! If config couldnt be opened successfully
1464 : // and exception os thrown automaticly and must be forwarded
1465 : // to our calli ...
1466 44 : css::uno::Reference< css::container::XNameAccess > xLoaders(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1467 : {
1468 : RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all frame loader");
1469 44 : impl_loadSet(xLoaders, E_FRAMELOADER, E_READ_ALL, &m_lFrameLoaders);
1470 44 : }
1471 : }
1472 :
1473 : // ------------------------------------------
1474 : // d) We need all content handler informations ...
1475 244 : if (
1476 : ((eRequiredState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS) &&
1477 : ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) != E_CONTAINS_CONTENTHANDLERS)
1478 : )
1479 : {
1480 : // Attention! If config couldnt be opened successfully
1481 : // and exception os thrown automaticly and must be forwarded
1482 : // to our calli ...
1483 24 : css::uno::Reference< css::container::XNameAccess > xHandlers(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1484 : {
1485 : RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all content handler");
1486 24 : impl_loadSet(xHandlers, E_CONTENTHANDLER, E_READ_ALL, &m_lContentHandlers);
1487 24 : }
1488 : }
1489 :
1490 : // update fill state. Note: its a bit field, which combines different parts.
1491 244 : m_eFillState = (EFillState) ((sal_Int32)m_eFillState | (sal_Int32)eRequiredState);
1492 :
1493 : // any data readed?
1494 : // yes! => validate it and update optimized structures.
1495 244 : impl_validateAndOptimize();
1496 :
1497 : // <- SAFE
1498 244 : }
1499 :
1500 :
1501 :
1502 230 : void FilterCache::impl_loadSet(const css::uno::Reference< css::container::XNameAccess >& xConfig,
1503 : EItemType eType ,
1504 : EReadOption eOption,
1505 : CacheItemList* pCache )
1506 : throw(css::uno::Exception)
1507 : {
1508 : // get access to the right configuration set
1509 230 : ::rtl::OUString sSetName;
1510 230 : switch(eType)
1511 : {
1512 : case E_TYPE :
1513 108 : sSetName = CFGSET_TYPES;
1514 108 : break;
1515 :
1516 : case E_FILTER :
1517 54 : sSetName = CFGSET_FILTERS;
1518 54 : break;
1519 :
1520 : case E_FRAMELOADER :
1521 44 : sSetName = CFGSET_FRAMELOADERS;
1522 44 : break;
1523 :
1524 : case E_CONTENTHANDLER :
1525 24 : sSetName = CFGSET_CONTENTHANDLERS;
1526 24 : break;
1527 0 : default: break;
1528 : }
1529 :
1530 230 : css::uno::Reference< css::container::XNameAccess > xSet;
1531 230 : css::uno::Sequence< ::rtl::OUString > lItems;
1532 :
1533 : try
1534 : {
1535 230 : css::uno::Any aVal = xConfig->getByName(sSetName);
1536 230 : if (!(aVal >>= xSet) || !xSet.is())
1537 : {
1538 0 : ::rtl::OUStringBuffer sMsg(256);
1539 0 : sMsg.appendAscii("Could not open configuration set \"");
1540 0 : sMsg.append (sSetName );
1541 0 : sMsg.appendAscii("\"." );
1542 : throw css::uno::Exception(
1543 : sMsg.makeStringAndClear(),
1544 0 : css::uno::Reference< css::uno::XInterface >());
1545 : }
1546 230 : lItems = xSet->getElementNames();
1547 : }
1548 0 : catch(const css::uno::Exception& ex)
1549 : {
1550 : throw css::document::CorruptedFilterConfigurationException(
1551 0 : "filter configuration, caught: " + ex.Message,
1552 : css::uno::Reference< css::uno::XInterface >(),
1553 0 : ex.Message);
1554 : }
1555 :
1556 : // get names of all existing sub items of this set
1557 : // step over it and fill internal cache structures.
1558 :
1559 : // But dont update optimized structures like e.g. hash
1560 : // for mapping extensions to its types!
1561 :
1562 230 : const ::rtl::OUString* pItems = lItems.getConstArray();
1563 230 : sal_Int32 c = lItems.getLength();
1564 24456 : for (sal_Int32 i=0; i<c; ++i)
1565 : {
1566 24226 : CacheItemList::iterator pItem = pCache->find(pItems[i]);
1567 24226 : switch(eOption)
1568 : {
1569 : // a) read a standard set of properties only or read all
1570 : case E_READ_STANDARD :
1571 : case E_READ_ALL :
1572 : {
1573 : try
1574 : {
1575 17256 : (*pCache)[pItems[i]] = impl_loadItem(xSet, eType, pItems[i], eOption);
1576 : }
1577 0 : catch(const css::uno::Exception& ex)
1578 : {
1579 : throw css::document::CorruptedFilterConfigurationException(
1580 0 : "filter configuration, caught: " + ex.Message,
1581 : css::uno::Reference< css::uno::XInterface >(),
1582 0 : ex.Message);
1583 : }
1584 : }
1585 17256 : break;
1586 :
1587 : // b) read optional properties only!
1588 : // All items must already exist inside our cache.
1589 : // But they must be updated.
1590 : case E_READ_UPDATE :
1591 : {
1592 6970 : if (pItem == pCache->end())
1593 : {
1594 0 : ::rtl::OUStringBuffer sMsg(256);
1595 0 : sMsg.appendAscii("item \"" );
1596 0 : sMsg.append (pItems[i] );
1597 0 : sMsg.appendAscii("\" not found for update!");
1598 : throw css::uno::Exception(sMsg.makeStringAndClear() ,
1599 0 : css::uno::Reference< css::uno::XInterface >());
1600 : }
1601 : try
1602 : {
1603 6970 : CacheItem aItem = impl_loadItem(xSet, eType, pItems[i], eOption);
1604 6970 : pItem->second.update(aItem);
1605 : }
1606 0 : catch(const css::uno::Exception& ex)
1607 : {
1608 : throw css::document::CorruptedFilterConfigurationException(
1609 0 : "filter configuration, caught: " + ex.Message,
1610 : css::uno::Reference< css::uno::XInterface >(),
1611 0 : ex.Message);
1612 : }
1613 : }
1614 6970 : break;
1615 0 : default: break;
1616 : }
1617 230 : }
1618 230 : }
1619 :
1620 :
1621 :
1622 17041 : void FilterCache::impl_readPatchUINames(const css::uno::Reference< css::container::XNameAccess >& xNode,
1623 : CacheItem& rItem)
1624 : throw(css::uno::Exception)
1625 : {
1626 :
1627 : // SAFE -> ----------------------------------
1628 17041 : ::osl::ResettableMutexGuard aLock(m_aLock);
1629 17041 : ::rtl::OUString sFormatName = m_sFormatName ;
1630 17041 : ::rtl::OUString sFormatVersion = m_sFormatVersion;
1631 17041 : ::rtl::OUString sActLocale = m_sActLocale ;
1632 17041 : aLock.clear();
1633 : // <- SAFE ----------------------------------
1634 :
1635 17041 : css::uno::Any aVal = xNode->getByName(PROPNAME_UINAME);
1636 17041 : css::uno::Reference< css::container::XNameAccess > xUIName;
1637 17041 : if (!(aVal >>= xUIName) && !xUIName.is())
1638 : return;
1639 :
1640 17041 : const ::comphelper::SequenceAsVector< ::rtl::OUString > lLocales(xUIName->getElementNames());
1641 17041 : ::comphelper::SequenceAsVector< ::rtl::OUString >::const_iterator pLocale ;
1642 17041 : ::comphelper::SequenceAsHashMap lUINames;
1643 :
1644 17041 : const char FORMATNAME_VAR[] = "%productname%";
1645 17041 : const char FORMATVERSION_VAR[] = "%formatversion%";
1646 : // patch %PRODUCTNAME and %FORMATNAME
1647 93216 : for ( pLocale = lLocales.begin();
1648 62144 : pLocale != lLocales.end() ;
1649 : ++pLocale )
1650 : {
1651 14031 : const ::rtl::OUString& sLocale = *pLocale;
1652 :
1653 14031 : ::rtl::OUString sValue;
1654 14031 : xUIName->getByName(sLocale) >>= sValue;
1655 :
1656 : // replace %productname%
1657 14031 : sal_Int32 nIndex = sValue.indexOf(FORMATNAME_VAR);
1658 28312 : while(nIndex != -1)
1659 : {
1660 250 : sValue = sValue.replaceAt(nIndex, RTL_CONSTASCII_LENGTH(FORMATNAME_VAR), sFormatName);
1661 250 : nIndex = sValue.indexOf(FORMATNAME_VAR, nIndex);
1662 : }
1663 : // replace %formatversion%
1664 14031 : nIndex = sValue.indexOf(FORMATVERSION_VAR);
1665 28310 : while(nIndex != -1)
1666 : {
1667 248 : sValue = sValue.replaceAt(nIndex, RTL_CONSTASCII_LENGTH(FORMATVERSION_VAR), sFormatVersion);
1668 248 : nIndex = sValue.indexOf(FORMATVERSION_VAR, nIndex);
1669 : }
1670 :
1671 14031 : lUINames[sLocale] <<= sValue;
1672 14031 : }
1673 :
1674 17041 : aVal <<= lUINames.getAsConstPropertyValueList();
1675 17041 : rItem[PROPNAME_UINAMES] = aVal;
1676 :
1677 : // find right UIName for current office locale
1678 : // Use fallbacks too!
1679 17041 : pLocale = ::comphelper::Locale::getFallback(lLocales, sActLocale);
1680 17041 : if (pLocale == lLocales.end())
1681 : {
1682 : #if OSL_DEBUG_LEVEL > 0
1683 : if ( sActLocale == "en-US" )
1684 : return;
1685 : ::rtl::OUString sName = rItem.getUnpackedValueOrDefault(PROPNAME_NAME, ::rtl::OUString());
1686 :
1687 : ::rtl::OUStringBuffer sMsg(256);
1688 : sMsg.appendAscii("Fallback scenario for filter or type '" );
1689 : sMsg.append (sName );
1690 : sMsg.appendAscii("' and locale '" );
1691 : sMsg.append (sActLocale );
1692 : sMsg.appendAscii("' failed. Please check your filter configuration.");
1693 :
1694 : OSL_FAIL(_FILTER_CONFIG_TO_ASCII_(sMsg.makeStringAndClear()));
1695 : #endif
1696 : return;
1697 : }
1698 :
1699 14021 : const ::rtl::OUString& sLocale = *pLocale;
1700 14021 : ::comphelper::SequenceAsHashMap::const_iterator pUIName = lUINames.find(sLocale);
1701 14021 : if (pUIName != lUINames.end())
1702 14021 : rItem[PROPNAME_UINAME] = pUIName->second;
1703 : }
1704 :
1705 :
1706 :
1707 0 : void FilterCache::impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
1708 : const CacheItem& rItem)
1709 : throw(css::uno::Exception)
1710 : {
1711 0 : css::uno::Reference< css::container::XNameContainer > xAdd (xNode, css::uno::UNO_QUERY);
1712 0 : css::uno::Reference< css::container::XNameAccess > xCheck(xNode, css::uno::UNO_QUERY);
1713 :
1714 0 : css::uno::Sequence< css::beans::PropertyValue > lUINames = rItem.getUnpackedValueOrDefault(PROPNAME_UINAMES, css::uno::Sequence< css::beans::PropertyValue >());
1715 0 : sal_Int32 c = lUINames.getLength();
1716 0 : const css::beans::PropertyValue* pUINames = lUINames.getConstArray();
1717 :
1718 0 : for (sal_Int32 i=0; i<c; ++i)
1719 : {
1720 0 : if (xCheck->hasByName(pUINames[i].Name))
1721 0 : xNode->replaceByName(pUINames[i].Name, pUINames[i].Value);
1722 : else
1723 0 : xAdd->insertByName(pUINames[i].Name, pUINames[i].Value);
1724 0 : }
1725 0 : }
1726 :
1727 : /*-----------------------------------------------
1728 : TODO
1729 : clarify, how the real problem behind the
1730 : wrong constructed CacheItem instance (which
1731 : will force a crash during destruction)
1732 : can be solved ...
1733 : -----------------------------------------------*/
1734 24235 : CacheItem FilterCache::impl_loadItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1735 : EItemType eType ,
1736 : const ::rtl::OUString& sItem ,
1737 : EReadOption eOption)
1738 : throw(css::uno::Exception)
1739 : {
1740 : // try to get an API object, which points directly to the
1741 : // requested item. If it fail an exception should occur and
1742 : // break this operation. Of course returned API object must be
1743 : // checked too.
1744 24235 : css::uno::Reference< css::container::XNameAccess > xItem;
1745 : #ifdef WORKAROUND_EXCEPTION_PROBLEM
1746 : try
1747 : {
1748 : #endif
1749 24235 : css::uno::Any aVal = xSet->getByName(sItem);
1750 24235 : if (!(aVal >>= xItem) || !xItem.is())
1751 : {
1752 0 : ::rtl::OUStringBuffer sMsg(256);
1753 0 : sMsg.appendAscii("found corrupted item \"");
1754 0 : sMsg.append (sItem );
1755 0 : sMsg.appendAscii("\"." );
1756 : throw css::uno::Exception(sMsg.makeStringAndClear() ,
1757 0 : css::uno::Reference< css::uno::XInterface >());
1758 24235 : }
1759 : #ifdef WORKAROUND_EXCEPTION_PROBLEM
1760 : }
1761 0 : catch(const css::container::NoSuchElementException&)
1762 : {
1763 0 : throw;
1764 : }
1765 : #endif
1766 :
1767 : // The internal name of an item must(!) be part of the property
1768 : // set too. Of course its already used as key into the e.g. outside
1769 : // used hash map ... but some of our API methods provide
1770 : // this property set as result only. But the user of this CacheItem
1771 : // should know, which value the key names has :-) ITS IMPORTANT!
1772 24235 : CacheItem aItem;
1773 24235 : aItem[PROPNAME_NAME] = css::uno::makeAny(sItem);
1774 24235 : switch(eType)
1775 : {
1776 : //---------------------------------------
1777 : case E_TYPE :
1778 : {
1779 : // read standard properties of a type
1780 13940 : if (
1781 : (eOption == E_READ_STANDARD) ||
1782 : (eOption == E_READ_ALL )
1783 : )
1784 : {
1785 6970 : aItem[PROPNAME_PREFERREDFILTER] = xItem->getByName(PROPNAME_PREFERREDFILTER);
1786 6970 : aItem[PROPNAME_DETECTSERVICE ] = xItem->getByName(PROPNAME_DETECTSERVICE );
1787 6970 : aItem[PROPNAME_URLPATTERN ] = xItem->getByName(PROPNAME_URLPATTERN );
1788 6970 : aItem[PROPNAME_EXTENSIONS ] = xItem->getByName(PROPNAME_EXTENSIONS );
1789 6970 : aItem[PROPNAME_PREFERRED ] = xItem->getByName(PROPNAME_PREFERRED );
1790 6970 : aItem[PROPNAME_CLIPBOARDFORMAT] = xItem->getByName(PROPNAME_CLIPBOARDFORMAT);
1791 : }
1792 : // read optional properties of a type
1793 : // no else here! Is an additional switch ...
1794 13940 : if (
1795 : (eOption == E_READ_UPDATE) ||
1796 : (eOption == E_READ_ALL )
1797 : )
1798 : {
1799 6970 : aItem[PROPNAME_MEDIATYPE ] = xItem->getByName(PROPNAME_MEDIATYPE );
1800 6970 : impl_readPatchUINames(xItem, aItem);
1801 : }
1802 : }
1803 13940 : break;
1804 :
1805 : //---------------------------------------
1806 : case E_FILTER :
1807 : {
1808 : // read standard properties of a filter
1809 10071 : if (
1810 : (eOption == E_READ_STANDARD) ||
1811 : (eOption == E_READ_ALL )
1812 : )
1813 : {
1814 10071 : aItem[PROPNAME_TYPE ] = xItem->getByName(PROPNAME_TYPE );
1815 10071 : aItem[PROPNAME_FILEFORMATVERSION] = xItem->getByName(PROPNAME_FILEFORMATVERSION);
1816 10071 : aItem[PROPNAME_UICOMPONENT ] = xItem->getByName(PROPNAME_UICOMPONENT );
1817 10071 : aItem[PROPNAME_FILTERSERVICE ] = xItem->getByName(PROPNAME_FILTERSERVICE );
1818 10071 : aItem[PROPNAME_DOCUMENTSERVICE ] = xItem->getByName(PROPNAME_DOCUMENTSERVICE );
1819 10071 : aItem[PROPNAME_EXPORTEXTENSION ] = xItem->getByName(PROPNAME_EXPORTEXTENSION );
1820 :
1821 : // special handling for flags! Convert it from a list of names to its
1822 : // int representation ...
1823 10071 : css::uno::Sequence< ::rtl::OUString > lFlagNames;
1824 10071 : if (xItem->getByName(PROPNAME_FLAGS) >>= lFlagNames)
1825 10071 : aItem[PROPNAME_FLAGS] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
1826 : }
1827 : // read optional properties of a filter
1828 : // no else here! Is an additional switch ...
1829 10071 : if (
1830 : (eOption == E_READ_UPDATE) ||
1831 : (eOption == E_READ_ALL )
1832 : )
1833 : {
1834 10071 : aItem[PROPNAME_USERDATA ] = xItem->getByName(PROPNAME_USERDATA );
1835 10071 : aItem[PROPNAME_TEMPLATENAME] = xItem->getByName(PROPNAME_TEMPLATENAME);
1836 : //TODO remove it if moving of filter uinames to type uinames
1837 : // will be finished realy
1838 : #ifdef AS_ENABLE_FILTER_UINAMES
1839 10071 : impl_readPatchUINames(xItem, aItem);
1840 : #endif // AS_ENABLE_FILTER_UINAMES
1841 : }
1842 : }
1843 10071 : break;
1844 :
1845 : //---------------------------------------
1846 : case E_FRAMELOADER :
1847 : case E_CONTENTHANDLER :
1848 : {
1849 224 : aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
1850 : }
1851 224 : break;
1852 0 : default: break;
1853 : }
1854 :
1855 24235 : return aItem;
1856 : }
1857 :
1858 :
1859 :
1860 27 : CacheItemList::iterator FilterCache::impl_loadItemOnDemand( EItemType eType,
1861 : const ::rtl::OUString& sItem)
1862 : throw(css::uno::Exception)
1863 : {
1864 27 : CacheItemList* pList = 0;
1865 27 : css::uno::Reference< css::uno::XInterface > xConfig ;
1866 27 : ::rtl::OUString sSet ;
1867 :
1868 27 : switch(eType)
1869 : {
1870 : case E_TYPE :
1871 : {
1872 18 : pList = &m_lTypes;
1873 18 : xConfig = impl_openConfig(E_PROVIDER_TYPES);
1874 18 : sSet = CFGSET_TYPES;
1875 : }
1876 18 : break;
1877 :
1878 : case E_FILTER :
1879 : {
1880 9 : pList = &m_lFilters;
1881 9 : xConfig = impl_openConfig(E_PROVIDER_FILTERS);
1882 9 : sSet = CFGSET_FILTERS;
1883 : }
1884 9 : break;
1885 :
1886 : case E_FRAMELOADER :
1887 : {
1888 0 : pList = &m_lFrameLoaders;
1889 0 : xConfig = impl_openConfig(E_PROVIDER_OTHERS);
1890 0 : sSet = CFGSET_FRAMELOADERS;
1891 : }
1892 0 : break;
1893 :
1894 : case E_CONTENTHANDLER :
1895 : {
1896 0 : pList = &m_lContentHandlers;
1897 0 : xConfig = impl_openConfig(E_PROVIDER_OTHERS);
1898 0 : sSet = CFGSET_CONTENTHANDLERS;
1899 : }
1900 0 : break;
1901 :
1902 : case E_DETECTSERVICE :
1903 : {
1904 : OSL_FAIL("Cant load detect services on demand. Who use this unsupported feature?");
1905 : }
1906 0 : break;
1907 : }
1908 :
1909 27 : css::uno::Reference< css::container::XNameAccess > xRoot(xConfig, css::uno::UNO_QUERY_THROW);
1910 27 : css::uno::Reference< css::container::XNameAccess > xSet ;
1911 27 : xRoot->getByName(sSet) >>= xSet;
1912 :
1913 27 : CacheItemList::iterator pItemInCache = pList->find(sItem);
1914 27 : sal_Bool bItemInConfig = xSet->hasByName(sItem);
1915 :
1916 27 : if (bItemInConfig)
1917 : {
1918 9 : (*pList)[sItem] = impl_loadItem(xSet, eType, sItem, E_READ_ALL);
1919 : _FILTER_CONFIG_LOG_2_("impl_loadItemOnDemand(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(sItem).getStr())
1920 : }
1921 : else
1922 : {
1923 18 : if (pItemInCache != pList->end())
1924 0 : pList->erase(pItemInCache);
1925 : // OK - this item does not exists inside configuration.
1926 : // And we already updated our internal cache.
1927 : // But the outside code needs this NoSuchElementException
1928 : // to know, that this item does notexists.
1929 : // Nobody checks the iterator!
1930 18 : throw css::container::NoSuchElementException();
1931 : }
1932 :
1933 36 : return pList->find(sItem);
1934 : }
1935 :
1936 :
1937 :
1938 0 : void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem,
1939 : EItemType eType,
1940 : const CacheItem& aItem)
1941 : throw(css::uno::Exception)
1942 : {
1943 0 : CacheItem::const_iterator pIt;
1944 0 : switch(eType)
1945 : {
1946 : //---------------------------------------
1947 : case E_TYPE :
1948 : {
1949 0 : pIt = aItem.find(PROPNAME_PREFERREDFILTER);
1950 0 : if (pIt != aItem.end())
1951 0 : xItem->replaceByName(PROPNAME_PREFERREDFILTER, pIt->second);
1952 0 : pIt = aItem.find(PROPNAME_DETECTSERVICE);
1953 0 : if (pIt != aItem.end())
1954 0 : xItem->replaceByName(PROPNAME_DETECTSERVICE, pIt->second);
1955 0 : pIt = aItem.find(PROPNAME_URLPATTERN);
1956 0 : if (pIt != aItem.end())
1957 0 : xItem->replaceByName(PROPNAME_URLPATTERN, pIt->second);
1958 0 : pIt = aItem.find(PROPNAME_EXTENSIONS);
1959 0 : if (pIt != aItem.end())
1960 0 : xItem->replaceByName(PROPNAME_EXTENSIONS, pIt->second);
1961 0 : pIt = aItem.find(PROPNAME_PREFERRED);
1962 0 : if (pIt != aItem.end())
1963 0 : xItem->replaceByName(PROPNAME_PREFERRED, pIt->second);
1964 0 : pIt = aItem.find(PROPNAME_MEDIATYPE);
1965 0 : if (pIt != aItem.end())
1966 0 : xItem->replaceByName(PROPNAME_MEDIATYPE, pIt->second);
1967 0 : pIt = aItem.find(PROPNAME_CLIPBOARDFORMAT);
1968 0 : if (pIt != aItem.end())
1969 0 : xItem->replaceByName(PROPNAME_CLIPBOARDFORMAT, pIt->second);
1970 :
1971 0 : css::uno::Reference< css::container::XNameReplace > xUIName;
1972 0 : xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1973 0 : impl_savePatchUINames(xUIName, aItem);
1974 : }
1975 0 : break;
1976 :
1977 : //---------------------------------------
1978 : case E_FILTER :
1979 : {
1980 0 : pIt = aItem.find(PROPNAME_TYPE);
1981 0 : if (pIt != aItem.end())
1982 0 : xItem->replaceByName(PROPNAME_TYPE, pIt->second);
1983 0 : pIt = aItem.find(PROPNAME_FILEFORMATVERSION);
1984 0 : if (pIt != aItem.end())
1985 0 : xItem->replaceByName(PROPNAME_FILEFORMATVERSION, pIt->second);
1986 0 : pIt = aItem.find(PROPNAME_UICOMPONENT);
1987 0 : if (pIt != aItem.end())
1988 0 : xItem->replaceByName(PROPNAME_UICOMPONENT, pIt->second);
1989 0 : pIt = aItem.find(PROPNAME_FILTERSERVICE);
1990 0 : if (pIt != aItem.end())
1991 0 : xItem->replaceByName(PROPNAME_FILTERSERVICE, pIt->second);
1992 0 : pIt = aItem.find(PROPNAME_DOCUMENTSERVICE);
1993 0 : if (pIt != aItem.end())
1994 0 : xItem->replaceByName(PROPNAME_DOCUMENTSERVICE, pIt->second);
1995 0 : pIt = aItem.find(PROPNAME_USERDATA);
1996 0 : if (pIt != aItem.end())
1997 0 : xItem->replaceByName(PROPNAME_USERDATA, pIt->second);
1998 0 : pIt = aItem.find(PROPNAME_TEMPLATENAME);
1999 0 : if (pIt != aItem.end())
2000 0 : xItem->replaceByName(PROPNAME_TEMPLATENAME, pIt->second);
2001 :
2002 : // special handling for flags! Convert it from an integer flag field back
2003 : // to a list of names ...
2004 : // But note: because we work directly on a reference to the cache item,
2005 : // its not allowd to change the value here. We must work on a copy!
2006 0 : pIt = aItem.find(PROPNAME_FLAGS);
2007 0 : if (pIt != aItem.end())
2008 : {
2009 0 : sal_Int32 nFlags = 0;
2010 0 : pIt->second >>= nFlags;
2011 0 : css::uno::Any aFlagNameList;
2012 0 : aFlagNameList <<= FilterCache::impl_convertFlagField2FlagNames(nFlags);
2013 0 : xItem->replaceByName(PROPNAME_FLAGS, aFlagNameList);
2014 : }
2015 :
2016 : //TODO remove it if moving of filter uinames to type uinames
2017 : // will be finished realy
2018 : #ifdef AS_ENABLE_FILTER_UINAMES
2019 0 : css::uno::Reference< css::container::XNameReplace > xUIName;
2020 0 : xItem->getByName(PROPNAME_UINAME) >>= xUIName;
2021 0 : impl_savePatchUINames(xUIName, aItem);
2022 : #endif // AS_ENABLE_FILTER_UINAMES
2023 : }
2024 0 : break;
2025 :
2026 : //---------------------------------------
2027 : case E_FRAMELOADER :
2028 : case E_CONTENTHANDLER :
2029 : {
2030 0 : pIt = aItem.find(PROPNAME_TYPES);
2031 0 : if (pIt != aItem.end())
2032 0 : xItem->replaceByName(PROPNAME_TYPES, pIt->second);
2033 : }
2034 0 : break;
2035 0 : default: break;
2036 : }
2037 0 : }
2038 :
2039 : /*-----------------------------------------------
2040 : static! => no locks neccessary
2041 : -----------------------------------------------*/
2042 0 : css::uno::Sequence< ::rtl::OUString > FilterCache::impl_convertFlagField2FlagNames(sal_Int32 nFlags)
2043 : {
2044 0 : OUStringList lFlagNames;
2045 :
2046 0 : if ((nFlags & FLAGVAL_3RDPARTYFILTER ) == FLAGVAL_3RDPARTYFILTER ) lFlagNames.push_back(FLAGNAME_3RDPARTYFILTER );
2047 0 : if ((nFlags & FLAGVAL_ALIEN ) == FLAGVAL_ALIEN ) lFlagNames.push_back(FLAGNAME_ALIEN );
2048 0 : if ((nFlags & FLAGVAL_ASYNCHRON ) == FLAGVAL_ASYNCHRON ) lFlagNames.push_back(FLAGNAME_ASYNCHRON );
2049 0 : if ((nFlags & FLAGVAL_BROWSERPREFERRED ) == FLAGVAL_BROWSERPREFERRED ) lFlagNames.push_back(FLAGNAME_BROWSERPREFERRED );
2050 0 : if ((nFlags & FLAGVAL_CONSULTSERVICE ) == FLAGVAL_CONSULTSERVICE ) lFlagNames.push_back(FLAGNAME_CONSULTSERVICE );
2051 0 : if ((nFlags & FLAGVAL_DEFAULT ) == FLAGVAL_DEFAULT ) lFlagNames.push_back(FLAGNAME_DEFAULT );
2052 0 : if ((nFlags & FLAGVAL_ENCRYPTION ) == FLAGVAL_ENCRYPTION ) lFlagNames.push_back(FLAGNAME_ENCRYPTION );
2053 0 : if ((nFlags & FLAGVAL_EXPORT ) == FLAGVAL_EXPORT ) lFlagNames.push_back(FLAGNAME_EXPORT );
2054 0 : if ((nFlags & FLAGVAL_IMPORT ) == FLAGVAL_IMPORT ) lFlagNames.push_back(FLAGNAME_IMPORT );
2055 0 : if ((nFlags & FLAGVAL_INTERNAL ) == FLAGVAL_INTERNAL ) lFlagNames.push_back(FLAGNAME_INTERNAL );
2056 0 : if ((nFlags & FLAGVAL_NOTINCHOOSER ) == FLAGVAL_NOTINCHOOSER ) lFlagNames.push_back(FLAGNAME_NOTINCHOOSER );
2057 0 : if ((nFlags & FLAGVAL_NOTINFILEDIALOG ) == FLAGVAL_NOTINFILEDIALOG ) lFlagNames.push_back(FLAGNAME_NOTINFILEDIALOG );
2058 0 : if ((nFlags & FLAGVAL_NOTINSTALLED ) == FLAGVAL_NOTINSTALLED ) lFlagNames.push_back(FLAGNAME_NOTINSTALLED );
2059 0 : if ((nFlags & FLAGVAL_OWN ) == FLAGVAL_OWN ) lFlagNames.push_back(FLAGNAME_OWN );
2060 0 : if ((nFlags & FLAGVAL_PACKED ) == FLAGVAL_PACKED ) lFlagNames.push_back(FLAGNAME_PACKED );
2061 0 : if ((nFlags & FLAGVAL_PASSWORDTOMODIFY ) == FLAGVAL_PASSWORDTOMODIFY ) lFlagNames.push_back(FLAGNAME_PASSWORDTOMODIFY );
2062 0 : if ((nFlags & FLAGVAL_PREFERRED ) == FLAGVAL_PREFERRED ) lFlagNames.push_back(FLAGNAME_PREFERRED );
2063 0 : if ((nFlags & FLAGVAL_STARTPRESENTATION) == FLAGVAL_STARTPRESENTATION) lFlagNames.push_back(FLAGNAME_STARTPRESENTATION);
2064 0 : if ((nFlags & FLAGVAL_READONLY ) == FLAGVAL_READONLY ) lFlagNames.push_back(FLAGNAME_READONLY );
2065 0 : if ((nFlags & FLAGVAL_SUPPORTSSELECTION) == FLAGVAL_SUPPORTSSELECTION) lFlagNames.push_back(FLAGNAME_SUPPORTSSELECTION);
2066 0 : if ((nFlags & FLAGVAL_TEMPLATE ) == FLAGVAL_TEMPLATE ) lFlagNames.push_back(FLAGNAME_TEMPLATE );
2067 0 : if ((nFlags & FLAGVAL_TEMPLATEPATH ) == FLAGVAL_TEMPLATEPATH ) lFlagNames.push_back(FLAGNAME_TEMPLATEPATH );
2068 0 : if ((nFlags & FLAGVAL_USESOPTIONS ) == FLAGVAL_USESOPTIONS ) lFlagNames.push_back(FLAGNAME_USESOPTIONS );
2069 0 : if ((nFlags & FLAGVAL_COMBINED ) == FLAGVAL_COMBINED ) lFlagNames.push_back(FLAGNAME_COMBINED );
2070 :
2071 0 : return lFlagNames.getAsConstList();
2072 : }
2073 :
2074 : /*-----------------------------------------------
2075 : static! => no locks neccessary
2076 : -----------------------------------------------*/
2077 10071 : sal_Int32 FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence< ::rtl::OUString >& lNames)
2078 : {
2079 10071 : sal_Int32 nField = 0;
2080 :
2081 10071 : const ::rtl::OUString* pNames = lNames.getConstArray();
2082 10071 : sal_Int32 c = lNames.getLength();
2083 49795 : for (sal_Int32 i=0; i<c; ++i)
2084 : {
2085 39724 : if (pNames[i].equals(FLAGNAME_3RDPARTYFILTER))
2086 : {
2087 3152 : nField |= FLAGVAL_3RDPARTYFILTER;
2088 3152 : continue;
2089 : }
2090 36572 : if (pNames[i].equals(FLAGNAME_ALIEN))
2091 : {
2092 8820 : nField |= FLAGVAL_ALIEN;
2093 8820 : continue;
2094 : }
2095 27752 : if (pNames[i].equals(FLAGNAME_ASYNCHRON))
2096 : {
2097 216 : nField |= FLAGVAL_ASYNCHRON;
2098 216 : continue;
2099 : }
2100 27536 : if (pNames[i].equals(FLAGNAME_BROWSERPREFERRED))
2101 : {
2102 0 : nField |= FLAGVAL_BROWSERPREFERRED;
2103 0 : continue;
2104 : }
2105 27536 : if (pNames[i].equals(FLAGNAME_CONSULTSERVICE))
2106 : {
2107 0 : nField |= FLAGVAL_CONSULTSERVICE;
2108 0 : continue;
2109 : }
2110 27536 : if (pNames[i].equals(FLAGNAME_DEFAULT))
2111 : {
2112 441 : nField |= FLAGVAL_DEFAULT;
2113 441 : continue;
2114 : }
2115 27095 : if (pNames[i].equals(FLAGNAME_ENCRYPTION))
2116 : {
2117 1895 : nField |= FLAGVAL_ENCRYPTION;
2118 1895 : continue;
2119 : }
2120 25200 : if (pNames[i].equals(FLAGNAME_EXPORT))
2121 : {
2122 6871 : nField |= FLAGVAL_EXPORT;
2123 6871 : continue;
2124 : }
2125 18329 : if (pNames[i].equals(FLAGNAME_IMPORT))
2126 : {
2127 7047 : nField |= FLAGVAL_IMPORT;
2128 7047 : continue;
2129 : }
2130 11282 : if (pNames[i].equals(FLAGNAME_INTERNAL))
2131 : {
2132 54 : nField |= FLAGVAL_INTERNAL;
2133 54 : continue;
2134 : }
2135 11228 : if (pNames[i].equals(FLAGNAME_NOTINCHOOSER))
2136 : {
2137 282 : nField |= FLAGVAL_NOTINCHOOSER;
2138 282 : continue;
2139 : }
2140 10946 : if (pNames[i].equals(FLAGNAME_NOTINFILEDIALOG))
2141 : {
2142 228 : nField |= FLAGVAL_NOTINFILEDIALOG;
2143 228 : continue;
2144 : }
2145 10718 : if (pNames[i].equals(FLAGNAME_NOTINSTALLED))
2146 : {
2147 0 : nField |= FLAGVAL_NOTINSTALLED;
2148 0 : continue;
2149 : }
2150 10718 : if (pNames[i].equals(FLAGNAME_OWN))
2151 : {
2152 1683 : nField |= FLAGVAL_OWN;
2153 1683 : continue;
2154 : }
2155 9035 : if (pNames[i].equals(FLAGNAME_PACKED))
2156 : {
2157 0 : nField |= FLAGVAL_PACKED;
2158 0 : continue;
2159 : }
2160 9035 : if (pNames[i].equals(FLAGNAME_PASSWORDTOMODIFY))
2161 : {
2162 653 : nField |= FLAGVAL_PASSWORDTOMODIFY;
2163 653 : continue;
2164 : }
2165 8382 : if (pNames[i].equals(FLAGNAME_PREFERRED))
2166 : {
2167 2059 : nField |= FLAGVAL_PREFERRED;
2168 2059 : continue;
2169 : }
2170 6323 : if (pNames[i].equals(FLAGNAME_STARTPRESENTATION))
2171 : {
2172 162 : nField |= FLAGVAL_STARTPRESENTATION;
2173 162 : continue;
2174 : }
2175 6161 : if (pNames[i].equals(FLAGNAME_READONLY))
2176 : {
2177 54 : nField |= FLAGVAL_READONLY;
2178 54 : continue;
2179 : }
2180 6107 : if (pNames[i].equals(FLAGNAME_SUPPORTSSELECTION))
2181 : {
2182 1728 : nField |= FLAGVAL_SUPPORTSSELECTION;
2183 1728 : continue;
2184 : }
2185 4379 : if (pNames[i].equals(FLAGNAME_TEMPLATE))
2186 : {
2187 2273 : nField |= FLAGVAL_TEMPLATE;
2188 2273 : continue;
2189 : }
2190 2106 : if (pNames[i].equals(FLAGNAME_TEMPLATEPATH))
2191 : {
2192 1242 : nField |= FLAGVAL_TEMPLATEPATH;
2193 1242 : continue;
2194 : }
2195 864 : if (pNames[i].equals(FLAGNAME_USESOPTIONS))
2196 : {
2197 756 : nField |= FLAGVAL_USESOPTIONS;
2198 756 : continue;
2199 : }
2200 108 : if (pNames[i].equals(FLAGNAME_COMBINED))
2201 : {
2202 0 : nField |= FLAGVAL_COMBINED;
2203 0 : continue;
2204 : }
2205 : }
2206 :
2207 10071 : return nField;
2208 : }
2209 :
2210 :
2211 :
2212 0 : void FilterCache::impl_interpretDataVal4Type(const ::rtl::OUString& sValue,
2213 : sal_Int32 nProp ,
2214 : CacheItem& rItem )
2215 : {
2216 0 : switch(nProp)
2217 : {
2218 : // Preferred
2219 : case 0: {
2220 0 : if (sValue.toInt32() == 1)
2221 0 : rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_True);
2222 : else
2223 0 : rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_False);
2224 : }
2225 0 : break;
2226 : // MediaType
2227 0 : case 1: rItem[PROPNAME_MEDIATYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2228 0 : break;
2229 : // ClipboardFormat
2230 0 : case 2: rItem[PROPNAME_CLIPBOARDFORMAT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2231 0 : break;
2232 : // URLPattern
2233 0 : case 3: rItem[PROPNAME_URLPATTERN] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2234 0 : break;
2235 : // Extensions
2236 0 : case 4: rItem[PROPNAME_EXTENSIONS] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2237 0 : break;
2238 : }
2239 0 : }
2240 :
2241 :
2242 :
2243 0 : void FilterCache::impl_interpretDataVal4Filter(const ::rtl::OUString& sValue,
2244 : sal_Int32 nProp ,
2245 : CacheItem& rItem )
2246 : {
2247 0 : switch(nProp)
2248 : {
2249 : // Order
2250 : case 0: {
2251 0 : sal_Int32 nOrder = sValue.toInt32();
2252 : if (nOrder > 0)
2253 : {
2254 : OSL_FAIL("FilterCache::impl_interpretDataVal4Filter()\nCant move Order value from filter to type on demand!\n");
2255 : _FILTER_CONFIG_LOG_2_("impl_interpretDataVal4Filter(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(rItem).getStr())
2256 : }
2257 : }
2258 0 : break;
2259 : // Type
2260 0 : case 1: rItem[PROPNAME_TYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2261 0 : break;
2262 : // DocumentService
2263 0 : case 2: rItem[PROPNAME_DOCUMENTSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2264 0 : break;
2265 : // FilterService
2266 0 : case 3: rItem[PROPNAME_FILTERSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2267 0 : break;
2268 : // Flags
2269 0 : case 4: rItem[PROPNAME_FLAGS] <<= sValue.toInt32();
2270 0 : break;
2271 : // UserData
2272 0 : case 5: rItem[PROPNAME_USERDATA] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2273 0 : break;
2274 : // FileFormatVersion
2275 0 : case 6: rItem[PROPNAME_FILEFORMATVERSION] <<= sValue.toInt32();
2276 0 : break;
2277 : // TemplateName
2278 0 : case 7: rItem[PROPNAME_TEMPLATENAME] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2279 0 : break;
2280 : // [optional!] UIComponent
2281 0 : case 8: rItem[PROPNAME_UICOMPONENT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2282 0 : break;
2283 : }
2284 0 : }
2285 :
2286 : /*-----------------------------------------------
2287 : TODO work on a cache copy first, which can be flushed afterwards
2288 : That would be usefully to gurantee a consistent cache.
2289 : -----------------------------------------------*/
2290 54 : void FilterCache::impl_readOldFormat()
2291 : throw(css::uno::Exception)
2292 : {
2293 : // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
2294 : // Its optional and shouldnt disturb our normal work!
2295 : // E.g. we must check, if the package exists ...
2296 :
2297 54 : css::uno::Reference< css::container::XNameAccess > xCfg;
2298 : try
2299 : {
2300 54 : css::uno::Reference< css::uno::XInterface > xInt = impl_openConfig(E_PROVIDER_OLD);
2301 54 : xCfg = css::uno::Reference< css::container::XNameAccess >(xInt, css::uno::UNO_QUERY_THROW);
2302 : }
2303 : /* corrupt filter addon ? because it's external (optional) code .. we can ignore it. Addon wont work then ...
2304 : but that seams to be acceptable.
2305 : see #139088# for further informations
2306 : */
2307 0 : catch(const css::uno::Exception&)
2308 54 : { return; }
2309 :
2310 54 : ::rtl::OUString TYPES_SET("Types");
2311 :
2312 : // May be there is no type set ...
2313 54 : if (xCfg->hasByName(TYPES_SET))
2314 : {
2315 54 : css::uno::Reference< css::container::XNameAccess > xSet;
2316 54 : xCfg->getByName(TYPES_SET) >>= xSet;
2317 54 : const css::uno::Sequence< ::rtl::OUString > lItems = xSet->getElementNames();
2318 54 : const ::rtl::OUString* pItems = lItems.getConstArray();
2319 54 : for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2320 54 : m_lTypes[pItems[i]] = impl_readOldItem(xSet, E_TYPE, pItems[i]);
2321 : }
2322 :
2323 54 : ::rtl::OUString FILTER_SET("Filters");
2324 : // May be there is no filter set ...
2325 54 : if (xCfg->hasByName(FILTER_SET))
2326 : {
2327 54 : css::uno::Reference< css::container::XNameAccess > xSet;
2328 54 : xCfg->getByName(FILTER_SET) >>= xSet;
2329 54 : const css::uno::Sequence< ::rtl::OUString > lItems = xSet->getElementNames();
2330 54 : const ::rtl::OUString* pItems = lItems.getConstArray();
2331 54 : for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2332 54 : m_lFilters[pItems[i]] = impl_readOldItem(xSet, E_FILTER, pItems[i]);
2333 54 : }
2334 : }
2335 :
2336 :
2337 :
2338 0 : CacheItem FilterCache::impl_readOldItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
2339 : EItemType eType,
2340 : const ::rtl::OUString& sItem)
2341 : throw(css::uno::Exception)
2342 : {
2343 0 : css::uno::Reference< css::container::XNameAccess > xItem;
2344 0 : xSet->getByName(sItem) >>= xItem;
2345 0 : if (!xItem.is())
2346 : throw css::uno::Exception(
2347 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cant read old item." )),
2348 0 : css::uno::Reference< css::uno::XInterface >());
2349 :
2350 0 : CacheItem aItem;
2351 0 : aItem[PROPNAME_NAME] <<= sItem;
2352 :
2353 : // Installed flag ...
2354 : // Isnt used any longer!
2355 :
2356 : // UIName
2357 0 : impl_readPatchUINames(xItem, aItem);
2358 :
2359 : // Data
2360 0 : ::rtl::OUString sData;
2361 0 : OUStringList lData;
2362 0 : xItem->getByName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ))) >>= sData;
2363 0 : lData = impl_tokenizeString(sData, (sal_Unicode)',');
2364 0 : if (
2365 0 : (sData.isEmpty()) ||
2366 0 : (lData.size()<1 )
2367 : )
2368 : {
2369 : throw css::uno::Exception(
2370 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cant read old item property DATA." )),
2371 0 : css::uno::Reference< css::uno::XInterface >());
2372 : }
2373 :
2374 0 : sal_Int32 nProp = 0;
2375 0 : for (OUStringList::const_iterator pProp = lData.begin();
2376 0 : pProp != lData.end() ;
2377 : ++pProp )
2378 : {
2379 0 : const ::rtl::OUString& sProp = *pProp;
2380 0 : switch(eType)
2381 : {
2382 : case E_TYPE :
2383 0 : impl_interpretDataVal4Type(sProp, nProp, aItem);
2384 0 : break;
2385 :
2386 : case E_FILTER :
2387 0 : impl_interpretDataVal4Filter(sProp, nProp, aItem);
2388 0 : break;
2389 0 : default: break;
2390 : }
2391 0 : ++nProp;
2392 : }
2393 :
2394 0 : return aItem;
2395 : }
2396 :
2397 :
2398 :
2399 0 : OUStringList FilterCache::impl_tokenizeString(const ::rtl::OUString& sData ,
2400 : sal_Unicode cSeperator)
2401 : {
2402 0 : OUStringList lData ;
2403 0 : sal_Int32 nToken = 0;
2404 0 : do
2405 : {
2406 0 : ::rtl::OUString sToken = sData.getToken(0, cSeperator, nToken);
2407 0 : lData.push_back(sToken);
2408 : }
2409 : while(nToken >= 0);
2410 0 : return lData;
2411 : }
2412 :
2413 : #if OSL_DEBUG_LEVEL > 0
2414 :
2415 :
2416 : ::rtl::OUString FilterCache::impl_searchFrameLoaderForType(const ::rtl::OUString& sType) const
2417 : {
2418 : CacheItemList::const_iterator pIt;
2419 : for ( pIt = m_lFrameLoaders.begin();
2420 : pIt != m_lFrameLoaders.end() ;
2421 : ++pIt )
2422 : {
2423 : const ::rtl::OUString& sItem = pIt->first;
2424 : ::comphelper::SequenceAsHashMap lProps(pIt->second);
2425 : OUStringList lTypes(lProps[PROPNAME_TYPES]);
2426 :
2427 : if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2428 : return sItem;
2429 : }
2430 :
2431 : return ::rtl::OUString();
2432 : }
2433 :
2434 :
2435 :
2436 : ::rtl::OUString FilterCache::impl_searchContentHandlerForType(const ::rtl::OUString& sType) const
2437 : {
2438 : CacheItemList::const_iterator pIt;
2439 : for ( pIt = m_lContentHandlers.begin();
2440 : pIt != m_lContentHandlers.end() ;
2441 : ++pIt )
2442 : {
2443 : const ::rtl::OUString& sItem = pIt->first;
2444 : ::comphelper::SequenceAsHashMap lProps(pIt->second);
2445 : OUStringList lTypes(lProps[PROPNAME_TYPES]);
2446 :
2447 : if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2448 : return sItem;
2449 : }
2450 :
2451 : return ::rtl::OUString();
2452 : }
2453 : #endif
2454 :
2455 :
2456 :
2457 6033 : sal_Bool FilterCache::impl_isModuleInstalled(const ::rtl::OUString& sModule)
2458 : {
2459 6033 : css::uno::Reference< css::container::XNameAccess > xCfg;
2460 :
2461 : // SAFE ->
2462 6033 : ::osl::ResettableMutexGuard aLock(m_aLock);
2463 6033 : if (! m_xModuleCfg.is())
2464 : {
2465 : m_xModuleCfg = css::uno::Reference< css::container::XNameAccess >(
2466 : ::comphelper::ConfigurationHelper::openConfig(
2467 : comphelper::getComponentContext(m_xSMGR),
2468 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office/Factories" )),
2469 : ::comphelper::ConfigurationHelper::E_READONLY),
2470 54 : css::uno::UNO_QUERY_THROW);
2471 : }
2472 :
2473 6033 : xCfg = m_xModuleCfg;
2474 6033 : aLock.clear();
2475 : // <- SAFE
2476 :
2477 6033 : if (xCfg.is())
2478 6033 : return xCfg->hasByName(sModule);
2479 :
2480 0 : return sal_False;
2481 : }
2482 :
2483 : } // namespace config
2484 : } // namespace filter
2485 :
2486 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|