Update to m13
[ooovba.git] / filter / source / config / cache / filtercache.cxx
blobfc93ad20cd417eda3023fec85db0a973e62d2bda
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: filtercache.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_filter.hxx"
34 #include "filtercache.hxx"
35 #include "lateinitlistener.hxx"
36 #include "macros.hxx"
37 #include "constant.hxx"
38 #include "cacheupdatelistener.hxx"
40 /*TODO see using below ... */
41 #define AS_ENABLE_FILTER_UINAMES
42 #define WORKAROUND_EXCEPTION_PROBLEM
44 //_______________________________________________
45 // includes
46 #include <com/sun/star/util/XChangesBatch.hpp>
47 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
48 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/beans/XProperty.hpp>
51 #include <com/sun/star/beans/PropertyValue.hpp>
52 #include <com/sun/star/beans/Property.hpp>
53 #include <com/sun/star/beans/PropertyAttribute.hpp>
54 #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
55 #include <comphelper/sequenceasvector.hxx>
56 #include <comphelper/locale.hxx>
57 #include <unotools/processfactory.hxx>
59 #ifndef _UNOTOOLS_CONFIGPATHES_HXX_
60 #include <unotools/configpathes.hxx>
61 #endif
62 #include <rtl/ustrbuf.hxx>
63 #include <rtl/logfile.hxx>
64 #include <rtl/uri.hxx>
65 #include <tools/urlobj.hxx>
66 #include <tools/wldcrd.hxx>
68 #include <com/sun/star/deployment/thePackageManagerFactory.hpp>
70 #include <comphelper/configurationhelper.hxx>
71 #include <ucbhelper/commandenvironment.hxx>
72 #include <rtl/bootstrap.hxx>
74 #include <osl/file.hxx>
76 using namespace com::sun::star;
78 //_______________________________________________
79 // namespace
81 namespace filter{
82 namespace config{
84 namespace css = ::com::sun::star;
86 //_______________________________________________
87 // definitions
89 // Error message in case filter config seems to be corrupted.
90 // Note: Dont tell user something about "setup -repair"!
91 // Its no longer supported by using native installers ...
92 static ::rtl::OUString MESSAGE_CORRUPTED_FILTERCONFIG = ::rtl::OUString::createFromAscii("The filter configuration appears to be defective. Please install the office suite again.");
94 /*-----------------------------------------------
95 15.03.2004 08:59
96 -----------------------------------------------*/
97 FilterCache::FilterCache()
98 : BaseLock ( )
99 , m_xSMGR (::comphelper::getProcessServiceFactory())
100 , m_eFillState(E_CONTAINS_NOTHING )
102 RTL_LOGFILE_TRACE("{ (as96863) FilterCache lifetime");
105 /*-----------------------------------------------
106 15.03.2004 08:59
107 -----------------------------------------------*/
108 FilterCache::~FilterCache()
110 RTL_LOGFILE_TRACE("} (as96863) FilterCache lifetime");
113 /*-----------------------------------------------
114 03.03.2004 11:27
115 -----------------------------------------------*/
116 FilterCache* FilterCache::clone() const
118 // SAFE -> ----------------------------------
119 ::osl::ResettableMutexGuard aLock(m_aLock);
121 FilterCache* pClone = new FilterCache();
123 // Dont copy the configuration access points here.
124 // They will be created on demand inside the cloned instance,
125 // if they are needed.
127 pClone->m_xSMGR = m_xSMGR;
129 pClone->m_lTypes = m_lTypes;
130 pClone->m_lDetectServices = m_lDetectServices;
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;
137 pClone->m_sActLocale = m_sActLocale;
138 pClone->m_sFormatName = m_sFormatName;
139 pClone->m_sFormatVersion = m_sFormatVersion;
141 pClone->m_eFillState = m_eFillState;
143 pClone->m_lChangedTypes = m_lChangedTypes;
144 pClone->m_lChangedFilters = m_lChangedFilters;
145 pClone->m_lChangedDetectServices = m_lChangedDetectServices;
146 pClone->m_lChangedFrameLoaders = m_lChangedFrameLoaders;
147 pClone->m_lChangedContentHandlers = m_lChangedContentHandlers;
149 return pClone;
150 // <- SAFE ----------------------------------
153 /*-----------------------------------------------
154 03.03.2004 14:39
155 -----------------------------------------------*/
156 void FilterCache::takeOver(const FilterCache& rClone)
158 // SAFE -> ----------------------------------
159 ::osl::ResettableMutexGuard aLock(m_aLock);
161 // a)
162 // Dont copy the configuration access points here!
163 // We must use our own ones ...
165 // b)
166 // Further we can ignore the uno service manager.
167 // We should already have a valid instance.
169 // c)
170 // Take over only changed items!
171 // Otherwhise we risk the following scenario:
172 // c1) clone_1 contains changed filters
173 // c2) clone_2 container changed types
174 // c3) clone_1 take over changed filters and unchanged types
175 // c4) clone_2 take over unchanged filters(!) and changed types(!)
176 // c5) c4 overwrites c3!
178 if (rClone.m_lChangedTypes.size()>0)
179 m_lTypes = rClone.m_lTypes;
180 if (rClone.m_lChangedDetectServices.size()>0)
181 m_lDetectServices = rClone.m_lDetectServices;
182 if (rClone.m_lChangedFilters.size()>0)
183 m_lFilters = rClone.m_lFilters;
184 if (rClone.m_lChangedFrameLoaders.size()>0)
185 m_lFrameLoaders = rClone.m_lFrameLoaders;
186 if (rClone.m_lChangedContentHandlers.size()>0)
187 m_lContentHandlers = rClone.m_lContentHandlers;
189 m_lChangedTypes.clear();
190 m_lChangedDetectServices.clear();
191 m_lChangedFilters.clear();
192 m_lChangedFrameLoaders.clear();
193 m_lChangedContentHandlers.clear();
195 m_sActLocale = rClone.m_sActLocale;
196 m_sFormatName = rClone.m_sFormatName;
197 m_sFormatVersion = rClone.m_sFormatVersion;
199 m_eFillState = rClone.m_eFillState;
201 // renew all dependencies and optimizations
202 // Because we cant be shure, that changed filters on one clone
203 // and changed types of another clone work together.
204 // But here we can check against the lates changes ...
205 impl_validateAndOptimize();
206 // <- SAFE ----------------------------------
209 /*-----------------------------------------------
210 28.10.2003 09:01
211 -----------------------------------------------*/
212 void FilterCache::load(EFillState eRequired,
213 #if OSL_DEBUG_LEVEL > 1
214 sal_Bool bByThread
215 #else
216 sal_Bool
217 #endif
219 throw(css::uno::Exception)
221 // SAFE -> ----------------------------------
222 ::osl::ResettableMutexGuard aLock(m_aLock);
224 // check if required fill state is already reached ...
225 // There is nothing to do then.
226 if ((m_eFillState & eRequired) == eRequired)
227 return;
229 #if OSL_DEBUG_LEVEL > 1 && !defined(OS2)
230 if (
231 (!bByThread) &&
233 ((eRequired & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) ||
234 ((eRequired & E_CONTAINS_ALL ) == E_CONTAINS_ALL )
238 OSL_ENSURE(sal_False, "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!");
240 #endif
242 // Otherwhise load the missing items.
244 // ------------------------------------------
245 // a) load some const values from configration.
246 // These values are needed there for loading
247 // config items ...
248 // Further we load some std items from the
249 // configuration so we can try to load the first
250 // office document with a minimal set of values.
251 if (m_eFillState == E_CONTAINS_NOTHING)
253 impl_getDirectCFGValue(CFGDIRECTKEY_OFFICELOCALE) >>= m_sActLocale;
254 if (!m_sActLocale.getLength())
256 _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify office locale => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_OFFICELOCALE));
257 m_sActLocale = DEFAULT_OFFICELOCALE;
260 impl_getDirectCFGValue(CFGDIRECTKEY_FORMATNAME) >>= m_sFormatName;
261 if (!m_sFormatName.getLength())
262 impl_getDirectCFGValue(CFGDIRECTKEY_PRODUCTNAME) >>= m_sFormatName;
264 if (!m_sFormatName.getLength())
266 _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format name => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATNAME));
267 m_sFormatName = DEFAULT_FORMATNAME;
270 impl_getDirectCFGValue(CFGDIRECTKEY_FORMATVERSION) >>= m_sFormatVersion;
271 if (!m_sFormatVersion.getLength())
273 _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format version => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATVERSION));
274 m_sFormatVersion = DEFAULT_FORMATVERSION;
277 // Support the old configuration support. Read it only one times during office runtime!
278 impl_readOldFormat();
280 // enable "loadOnDemand" feature ...
281 // Create uno listener, which waits for finishing the office startup
282 // and starts a thread, which calls loadAll() at this filter cache.
283 // Note: Its not a leak to create this listener with new here.
284 // It kills itself after working!
285 /* LateInitListener* pLateInit = */ new LateInitListener(m_xSMGR);
288 // ------------------------------------------
289 // b) If the required fill state was not reached
290 // but std values was already loaded ...
291 // we must load some further missing items.
292 impl_load(eRequired);
293 // <- SAFE
296 /*-----------------------------------------------
297 28.10.2003 09:50
298 -----------------------------------------------*/
299 sal_Bool FilterCache::isFillState(FilterCache::EFillState eState) const
300 throw(css::uno::Exception)
302 // SAFE ->
303 ::osl::ResettableMutexGuard aLock(m_aLock);
304 return ((m_eFillState & eState) == eState);
305 // <- SAFE
308 /*-----------------------------------------------
309 14.07.2003 10:45
310 -----------------------------------------------*/
311 OUStringList FilterCache::getMatchingItemsByProps( EItemType eType ,
312 const CacheItem& lIProps,
313 const CacheItem& lEProps) const
314 throw(css::uno::Exception)
316 // SAFE ->
317 ::osl::ResettableMutexGuard aLock(m_aLock);
319 // search for right list
320 // An exception is thrown �f "eType" is unknown.
321 // => rList will be valid everytimes next line is reached.
322 CacheItemList& rList = impl_getItemList(eType);
324 OUStringList lKeys;
326 // search items, which provides all needed properties of set "lIProps"
327 // but not of set "lEProps"!
328 for (CacheItemList::const_iterator pIt = rList.begin();
329 pIt != rList.end() ;
330 ++pIt )
332 _FILTER_CONFIG_LOG_1_("getMatchingProps for \"%s\" ...\n",
333 _FILTER_CONFIG_TO_ASCII_(pIt->first))
334 if (
335 (pIt->second.haveProps(lIProps) ) &&
336 (pIt->second.dontHaveProps(lEProps))
339 lKeys.push_back(pIt->first);
343 return lKeys;
344 // <- SAFE
347 /*-----------------------------------------------
348 02.07.2003 09:32
349 -----------------------------------------------*/
350 sal_Bool FilterCache::hasItems(EItemType eType) const
351 throw(css::uno::Exception)
353 // SAFE ->
354 ::osl::ResettableMutexGuard aLock(m_aLock);
356 // search for right list
357 // An exception is thrown �f "eType" is unknown.
358 // => rList will be valid everytimes next line is reached.
359 CacheItemList& rList = impl_getItemList(eType);
361 return (rList.size()>0);
362 // <- SAFE
365 /*-----------------------------------------------
366 02.07.2003 11:48
367 -----------------------------------------------*/
368 OUStringList FilterCache::getItemNames(EItemType eType) const
369 throw(css::uno::Exception)
371 // SAFE ->
372 ::osl::ResettableMutexGuard aLock(m_aLock);
374 // search for right list
375 // An exception is thrown �f "eType" is unknown.
376 // => rList will be valid everytimes next line is reached.
377 CacheItemList& rList = impl_getItemList(eType);
379 OUStringList lKeys;
380 for (CacheItemList::const_iterator pIt = rList.begin();
381 pIt != rList.end() ;
382 ++pIt )
384 lKeys.push_back(pIt->first);
386 return lKeys;
387 // <- SAFE
390 /*-----------------------------------------------
391 27.10.2003 08:37
392 -----------------------------------------------*/
393 sal_Bool FilterCache::hasItem( EItemType eType,
394 const ::rtl::OUString& sItem)
395 throw(css::uno::Exception)
397 // SAFE ->
398 ::osl::ResettableMutexGuard aLock(m_aLock);
400 // search for right list
401 // An exception is thrown �f "eType" is unknown.
402 // => rList will be valid everytimes next line is reached.
403 CacheItemList& rList = impl_getItemList(eType);
405 // if item could not be found - check if it can be loaded
406 // from the underlying configuration layer. Might it was not already
407 // loaded into this FilterCache object before.
408 CacheItemList::const_iterator pIt = rList.find(sItem);
409 if (pIt != rList.end())
410 return sal_True;
414 impl_loadItemOnDemand(eType, sItem);
415 // no exception => item could be loaded!
416 return sal_True;
418 catch(const css::container::NoSuchElementException&)
421 return sal_False;
422 // <- SAFE
425 /*-----------------------------------------------
426 17.07.2006 09:15
427 -----------------------------------------------*/
428 CacheItem FilterCache::getItem( EItemType eType,
429 const ::rtl::OUString& sItem)
430 throw(css::uno::Exception)
432 // SAFE ->
433 ::osl::ResettableMutexGuard aLock(m_aLock);
435 // search for right list
436 // An exception is thrown if "eType" is unknown.
437 // => rList will be valid everytimes next line is reached.
438 CacheItemList& rList = impl_getItemList(eType);
440 // check if item exists ...
441 CacheItemList::iterator pIt = rList.find(sItem);
442 if (pIt == rList.end())
444 // ... or load it on demand from the
445 // underlying configuration layer.
446 // Note: NoSuchElementException is thrown automaticly here if
447 // item could not be loaded!
448 pIt = impl_loadItemOnDemand(eType, sItem);
451 /* Workaround for #137955#
452 Draw types and filters are installed ... but draw was disabled during setup.
453 We must supress accessing these filters. Otherwise the office can crash.
454 Solution for the next major release: do not install those filters !
456 if (eType == E_FILTER)
458 CacheItem& rFilter = pIt->second;
459 ::rtl::OUString sDocService;
460 rFilter[PROPNAME_DOCUMENTSERVICE] >>= sDocService;
462 // --> PB 2006-10-18 #142498#
463 // In Standalone-Impress the module WriterWeb is not installed
464 // but it is there to load help pages
465 sal_Bool bIsHelpFilter = sItem.equalsAscii( "writer_web_HTML_help" );
467 if ( !bIsHelpFilter && !impl_isModuleInstalled(sDocService) )
468 // <--
470 ::rtl::OUStringBuffer sMsg(256);
471 sMsg.appendAscii("The requested filter '" );
472 sMsg.append (sItem );
473 sMsg.appendAscii("' exists ... but it shouldnt; because the corresponding OOo module was not installed.");
474 throw css::container::NoSuchElementException(sMsg.makeStringAndClear(), css::uno::Reference< css::uno::XInterface >());
478 return pIt->second;
479 // <- SAFE
482 /*-----------------------------------------------
483 03.03.2004 11:28
484 -----------------------------------------------*/
485 void FilterCache::removeItem( EItemType eType,
486 const ::rtl::OUString& sItem)
487 throw(css::uno::Exception)
489 // SAFE ->
490 ::osl::ResettableMutexGuard aLock(m_aLock);
492 // search for right list
493 // An exception is thrown �f "eType" is unknown.
494 // => rList will be valid everytimes next line is reached.
495 CacheItemList& rList = impl_getItemList(eType);
497 CacheItemList::iterator pItem = rList.find(sItem);
498 if (pItem == rList.end())
499 pItem = impl_loadItemOnDemand(eType, sItem); // throws NoSuchELementException!
500 rList.erase(pItem);
502 impl_addItem2FlushList(eType, sItem);
505 /*-----------------------------------------------
506 26.11.2003 13:28
507 -----------------------------------------------*/
508 void FilterCache::setItem( EItemType eType ,
509 const ::rtl::OUString& sItem ,
510 const CacheItem& aValue)
511 throw(css::uno::Exception)
513 // SAFE ->
514 ::osl::ResettableMutexGuard aLock(m_aLock);
516 // search for right list
517 // An exception is thrown �f "eType" is unknown.
518 // => rList will be valid everytimes next line is reached.
519 CacheItemList& rList = impl_getItemList(eType);
521 // name must be part of the property set too ... otherwhise our
522 // container query cant work correctly
523 CacheItem aItem = aValue;
524 aItem[PROPNAME_NAME] <<= sItem;
525 aItem.validateUINames(m_sActLocale);
527 // remove implicit properties as e.g. FINALIZED or MANDATORY
528 // They cant be saved here and must be readed on demand later, if they are needed.
529 removeStatePropsFromItem(aItem);
531 rList[sItem] = aItem;
533 impl_addItem2FlushList(eType, sItem);
536 //-----------------------------------------------
537 void FilterCache::refreshItem( EItemType eType,
538 const ::rtl::OUString& sItem)
539 throw(css::uno::Exception)
541 // SAFE ->
542 ::osl::ResettableMutexGuard aLock(m_aLock);
543 impl_loadItemOnDemand(eType, sItem);
546 /*-----------------------------------------------
547 27.10.2003 08:14
548 -----------------------------------------------*/
549 void FilterCache::addStatePropsToItem( EItemType eType,
550 const ::rtl::OUString& sItem,
551 CacheItem& rItem)
552 throw(css::uno::Exception)
554 // SAFE ->
555 ::osl::ResettableMutexGuard aLock(m_aLock);
557 // Note: Opening of the configuration layer throws some exceptions
558 // if it failed. So we dont must check any reference here ...
559 css::uno::Reference< css::container::XNameAccess > xPackage;
560 css::uno::Reference< css::container::XNameAccess > xSet;
561 switch(eType)
563 case E_TYPE :
565 xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
566 xPackage->getByName(CFGSET_TYPES) >>= xSet;
568 break;
570 case E_FILTER :
572 xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY);
573 xPackage->getByName(CFGSET_FILTERS) >>= xSet;
575 break;
577 case E_FRAMELOADER :
579 /* TODO
580 Hack -->
581 The default frame loader cant be located inside te normal set of frame loaders.
582 Its an atomic property inside the misc cfg package. So we cant retrieve the information
583 about FINALIZED and MANDATORY very easy ... :-(
584 => set it to readonly/required everytimes :-)
586 css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
587 ::rtl::OUString sDefaultFrameLoader;
588 if (
589 (aDirectValue >>= sDefaultFrameLoader) &&
590 (sDefaultFrameLoader.getLength() ) &&
591 (sItem.equals(sDefaultFrameLoader) )
594 rItem[PROPNAME_FINALIZED] <<= sal_True;
595 rItem[PROPNAME_MANDATORY] <<= sal_True;
596 return;
598 /* <-- HACK */
600 xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
601 xPackage->getByName(CFGSET_FRAMELOADERS) >>= xSet;
603 break;
605 case E_CONTENTHANDLER :
607 xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
608 xPackage->getByName(CFGSET_CONTENTHANDLERS) >>= xSet;
610 break;
611 default: break;
616 css::uno::Reference< css::beans::XProperty > xItem;
617 xSet->getByName(sItem) >>= xItem;
618 css::beans::Property aDescription = xItem->getAsProperty();
620 sal_Bool bFinalized = ((aDescription.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
621 sal_Bool bMandatory = ((aDescription.Attributes & css::beans::PropertyAttribute::REMOVEABLE) != css::beans::PropertyAttribute::REMOVEABLE);
623 rItem[PROPNAME_FINALIZED] <<= bFinalized;
624 rItem[PROPNAME_MANDATORY] <<= bMandatory;
626 catch(const css::container::NoSuchElementException&)
628 /* Ignore exceptions for missing elements inside configuration.
629 May by the following reason exists:
630 - The item does not exists inside the new configuration package org.openoffice.TypeDetection - but
631 we got it from the old package org.openoffice.Office/TypeDetection. We dont migrate such items
632 automaticly to the new format. Because it will disturb e.g. the deinstallation of an external filter
633 package. Because such external filter can remove the old file - but not the automaticly created new one ...
635 => mark item as FINALIZED / MANDATORY, we dont support writing to the old format
637 rItem[PROPNAME_FINALIZED] <<= sal_True;
638 rItem[PROPNAME_MANDATORY] <<= sal_True;
641 // <- SAFE
644 /*-----------------------------------------------
645 05.03.2004 10:36
646 -----------------------------------------------*/
647 void FilterCache::removeStatePropsFromItem(CacheItem& rItem)
648 throw(css::uno::Exception)
650 CacheItem::iterator pIt;
651 pIt = rItem.find(PROPNAME_FINALIZED);
652 if (pIt != rItem.end())
653 rItem.erase(pIt);
654 pIt = rItem.find(PROPNAME_MANDATORY);
655 if (pIt != rItem.end())
656 rItem.erase(pIt);
659 /*-----------------------------------------------
660 02.07.2003 09:17
661 -----------------------------------------------*/
662 void FilterCache::flush()
663 throw(css::uno::Exception)
665 // SAFE ->
666 ::osl::ResettableMutexGuard aLock(m_aLock);
668 // renew all dependencies and optimizations
669 impl_validateAndOptimize();
671 if (m_lChangedTypes.size() > 0)
673 css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
674 css::uno::Reference< css::container::XNameAccess > xSet ;
676 xConfig->getByName(CFGSET_TYPES) >>= xSet;
677 impl_flushByList(xSet, E_TYPE, m_lTypes, m_lChangedTypes);
679 css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
680 xFlush->commitChanges();
683 if (m_lChangedFilters.size() > 0)
685 css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY);
686 css::uno::Reference< css::container::XNameAccess > xSet ;
688 xConfig->getByName(CFGSET_FILTERS) >>= xSet;
689 impl_flushByList(xSet, E_FILTER, m_lFilters, m_lChangedFilters);
691 css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
692 xFlush->commitChanges();
695 /*TODO FrameLoader/ContentHandler must be flushed here too ... */
698 /*-----------------------------------------------
699 20.10.2003 09:22
700 -----------------------------------------------*/
701 void FilterCache::impl_flushByList(const css::uno::Reference< css::container::XNameAccess >& xSet ,
702 EItemType eType ,
703 const CacheItemList& rCache,
704 const OUStringList& lItems)
705 throw(css::uno::Exception)
707 css::uno::Reference< css::container::XNameContainer > xAddRemoveSet = css::uno::Reference< css::container::XNameContainer > (xSet, css::uno::UNO_QUERY);
708 css::uno::Reference< css::container::XNameReplace > xReplaceeSet = css::uno::Reference< css::container::XNameReplace > (xSet, css::uno::UNO_QUERY);
709 css::uno::Reference< css::lang::XSingleServiceFactory > xFactory = css::uno::Reference< css::lang::XSingleServiceFactory >(xSet, css::uno::UNO_QUERY);
711 for (OUStringList::const_iterator pIt = lItems.begin();
712 pIt != lItems.end() ;
713 ++pIt )
715 const ::rtl::OUString& sItem = *pIt;
716 EItemFlushState eState = impl_specifyFlushOperation(xSet, rCache, sItem);
717 switch(eState)
719 case E_ITEM_REMOVED :
721 xAddRemoveSet->removeByName(sItem);
723 break;
725 case E_ITEM_ADDED :
727 css::uno::Reference< css::container::XNameReplace > xItem (xFactory->createInstance(), css::uno::UNO_QUERY);
729 // special case. no exception - but not a valid item => set must be finalized or mandatory!
730 // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
731 if (!xItem.is())
732 throw css::uno::Exception(::rtl::OUString::createFromAscii("Cant add item. Set is finalized or mandatory!"),
733 css::uno::Reference< css::uno::XInterface >() );
735 CacheItemList::const_iterator pItem = rCache.find(sItem);
736 impl_saveItem(xItem, eType, pItem->second);
737 xAddRemoveSet->insertByName(sItem, css::uno::makeAny(xItem));
739 break;
741 case E_ITEM_CHANGED :
743 css::uno::Reference< css::container::XNameReplace > xItem;
744 xSet->getByName(sItem) >>= xItem;
746 // special case. no exception - but not a valid item => it must be finalized or mandatory!
747 // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
748 if (!xItem.is())
749 throw css::uno::Exception(::rtl::OUString::createFromAscii("Cant change item. Its finalized or mandatory!"),
750 css::uno::Reference< css::uno::XInterface >() );
752 CacheItemList::const_iterator pItem = rCache.find(sItem);
753 impl_saveItem(xItem, eType, pItem->second);
755 break;
756 default: break;
761 /*-----------------------------------------------
762 03.11.2003 08:38
763 -----------------------------------------------*/
764 void FilterCache::detectFlatForURL(const css::util::URL& aURL ,
765 FlatDetection& rFlatTypes) const
766 throw(css::uno::Exception)
768 // extract extension from URL, so it can be used directly as key into our hash map!
769 // Note further: It must be converted to lower case, because the optimize hash
770 // (which maps extensions to types) work with lower case key strings!
771 INetURLObject aParser (aURL.Main);
772 ::rtl::OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
773 sal_True ,
774 INetURLObject::DECODE_WITH_CHARSET);
775 sExtension = sExtension.toAsciiLowerCase();
777 // SAFE -> ----------------------------------
778 ::osl::ResettableMutexGuard aLock(m_aLock);
780 //*******************************************
781 // i) Step over all well known URL pattern
782 // and add registered types to the return list too
783 // Do it as first one - because: if a type match by a
784 // pattern a following deep detection can be supressed!
785 // Further we can stop after first match ...
786 for (CacheItemRegistration::const_iterator pPattReg = m_lURLPattern2Types.begin();
787 pPattReg != m_lURLPattern2Types.end() ;
788 ++pPattReg )
790 WildCard aPatternCheck(pPattReg->first);
791 if (aPatternCheck.Matches(aURL.Main))
793 const OUStringList& rTypesForPattern = pPattReg->second;
795 FlatDetectionInfo aInfo;
796 aInfo.sType = *(rTypesForPattern.begin());
797 aInfo.bMatchByPattern = sal_True;
799 rFlatTypes.push_back(aInfo);
800 // return;
804 //*******************************************
805 // ii) search types matching to the given extension.
806 // Copy every macthing type without changing its order!
807 // Because preferred types was added as first one during
808 // loading configuration.
809 CacheItemRegistration::const_iterator pExtReg = m_lExtensions2Types.find(sExtension);
810 if (pExtReg != m_lExtensions2Types.end())
812 const OUStringList& rTypesForExtension = pExtReg->second;
813 for (OUStringList::const_iterator pIt = rTypesForExtension.begin();
814 pIt != rTypesForExtension.end() ;
815 ++pIt )
817 FlatDetectionInfo aInfo;
818 aInfo.sType = *pIt;
819 aInfo.bMatchByExtension = sal_True;
821 rFlatTypes.push_back(aInfo);
825 aLock.clear();
826 // <- SAFE ----------------------------------
829 /*-----------------------------------------------
830 03.11.2003 08:38
831 -----------------------------------------------*/
832 CacheItemList& FilterCache::impl_getItemList(EItemType eType) const
833 throw(css::uno::Exception)
835 // SAFE -> ----------------------------------
836 ::osl::ResettableMutexGuard aLock(m_aLock);
838 switch(eType)
840 case E_TYPE : return m_lTypes ;
841 case E_FILTER : return m_lFilters ;
842 case E_FRAMELOADER : return m_lFrameLoaders ;
843 case E_CONTENTHANDLER : return m_lContentHandlers;
844 case E_DETECTSERVICE : return m_lDetectServices ;
848 // throw has been moved from the default section of the switch to
849 // avoid warning: control reaches end of non-void function
850 throw css::uno::Exception(::rtl::OUString::createFromAscii("unknown sub container requested."),
851 css::uno::Reference< css::uno::XInterface >() );
852 // <- SAFE ----------------------------------
855 /*-----------------------------------------------
856 21.10.2003 13:20
857 -----------------------------------------------*/
858 css::uno::Reference< css::uno::XInterface > FilterCache::impl_openConfig(EConfigProvider eProvider)
859 throw(css::uno::Exception)
861 // SAFE ->
862 ::osl::ResettableMutexGuard aLock(m_aLock);
864 ::rtl::OUString sPath ;
865 css::uno::Reference< css::uno::XInterface >* pConfig = 0;
866 css::uno::Reference< css::uno::XInterface > xOld ;
867 ::rtl::OString sRtlLog ;
868 FilterCache::EItemType eItemType( FilterCache::E_TYPE ) ;
869 sal_Bool bStartListening = sal_False;
871 switch(eProvider)
873 case E_PROVIDER_TYPES :
875 if (m_xConfigTypes.is())
876 return m_xConfigTypes;
877 sPath = CFGPACKAGE_TD_TYPES;
878 pConfig = &m_xConfigTypes;
879 eItemType = FilterCache::E_TYPE;
880 bStartListening = sal_True;
881 sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_TYPES)");
883 break;
885 case E_PROVIDER_FILTERS :
887 if (m_xConfigFilters.is())
888 return m_xConfigFilters;
889 sPath = CFGPACKAGE_TD_FILTERS;
890 pConfig = &m_xConfigFilters;
891 eItemType = FilterCache::E_FILTER;
892 bStartListening = sal_True;
893 sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_FILTERS)");
895 break;
897 case E_PROVIDER_OTHERS :
899 if (m_xConfigOthers.is())
900 return m_xConfigOthers;
901 sPath = CFGPACKAGE_TD_OTHERS;
902 pConfig = &m_xConfigOthers;
903 eItemType = FilterCache::E_TYPE;
904 sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OTHERS)");
906 break;
908 case E_PROVIDER_OLD :
910 // This special provider is used to work with
911 // the old configuration format only. Its not cached!
912 sPath = CFGPACKAGE_TD_OLD;
913 pConfig = &xOld;
914 sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OLD)");
916 break;
918 default : throw css::uno::Exception(::rtl::OUString::createFromAscii("These configuration node isnt supported here for open!"), 0);
922 RTL_LOGFILE_CONTEXT(aLog, sRtlLog.getStr());
923 *pConfig = impl_createConfigAccess(sPath ,
924 sal_False, // bReadOnly
925 sal_True ); // bLocalesMode
928 // Start listening for changes on that configuration access.
929 // We must not control the lifetime of this listener. Itself
930 // checks, when ist time to die :-)
931 if (bStartListening)
933 CacheUpdateListener* pListener = new CacheUpdateListener(m_xSMGR, *pConfig, eItemType);
934 pListener->startListening();
937 return *pConfig;
938 // <- SAFE
941 /*-----------------------------------------------
942 17.07.2003 10:10
943 -----------------------------------------------*/
944 css::uno::Any FilterCache::impl_getDirectCFGValue(const ::rtl::OUString& sDirectKey)
946 ::rtl::OUString sRoot;
947 ::rtl::OUString sKey ;
949 if (
950 (!::utl::splitLastFromConfigurationPath(sDirectKey, sRoot, sKey)) ||
951 (!sRoot.getLength() ) ||
952 (!sKey.getLength() )
954 return css::uno::Any();
956 css::uno::Reference< css::uno::XInterface > xCfg = impl_createConfigAccess(sRoot ,
957 sal_True , // bReadOnly
958 sal_False); // bLocalesMode
959 if (!xCfg.is())
960 return css::uno::Any();
962 css::uno::Reference< css::container::XNameAccess > xAccess(xCfg, css::uno::UNO_QUERY);
963 if (!xAccess.is())
964 return css::uno::Any();
966 css::uno::Any aValue;
969 aValue = xAccess->getByName(sKey);
971 catch(const css::uno::RuntimeException& exRun)
972 { throw exRun; }
973 #if OSL_DEBUG_LEVEL>0
974 catch(const css::uno::Exception& ex)
975 #else
976 catch(const css::uno::Exception&)
977 #endif
979 #if OSL_DEBUG_LEVEL > 0
980 OSL_ENSURE(sal_False, ::rtl::OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
981 #endif
982 aValue.clear();
985 return aValue;
988 /*-----------------------------------------------
989 17.07.2003 09:49
990 -----------------------------------------------*/
991 css::uno::Reference< css::uno::XInterface > FilterCache::impl_createConfigAccess(const ::rtl::OUString& sRoot ,
992 sal_Bool bReadOnly ,
993 sal_Bool bLocalesMode)
995 // SAFE ->
996 ::osl::ResettableMutexGuard aLock(m_aLock);
998 css::uno::Reference< css::uno::XInterface > xCfg;
1002 css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
1003 m_xSMGR->createInstance(SERVICE_CONFIGURATIONPROVIDER), css::uno::UNO_QUERY);
1005 if (!xConfigProvider.is())
1006 return css::uno::Reference< css::uno::XInterface >();
1008 ::comphelper::SequenceAsVector< css::uno::Any > lParams;
1009 css::beans::PropertyValue aParam ;
1011 // set root path
1012 aParam.Name = _FILTER_CONFIG_FROM_ASCII_("nodepath");
1013 aParam.Value <<= sRoot;
1014 lParams.push_back(css::uno::makeAny(aParam));
1016 // enable "all locales mode" ... if required
1017 if (bLocalesMode)
1019 aParam.Name = _FILTER_CONFIG_FROM_ASCII_("locale");
1020 aParam.Value <<= _FILTER_CONFIG_FROM_ASCII_("*" );
1021 lParams.push_back(css::uno::makeAny(aParam));
1024 // open it
1025 if (bReadOnly)
1026 xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS, lParams.getAsConstList());
1027 else
1028 xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS, lParams.getAsConstList());
1030 // If configuration could not be opened ... but factory method does not throwed an exception
1031 // trigger throwing of our own CorruptedFilterConfigurationException.
1032 // Let message empty. The normal exception text show enough informations to the user.
1033 if (! xCfg.is())
1034 throw css::uno::Exception(
1035 _FILTER_CONFIG_FROM_ASCII_("Got NULL reference on opening configuration file ... but no exception."),
1036 css::uno::Reference< css::uno::XInterface >());
1038 catch(const css::uno::Exception& ex)
1040 throw css::document::CorruptedFilterConfigurationException(
1041 MESSAGE_CORRUPTED_FILTERCONFIG,
1042 css::uno::Reference< css::uno::XInterface >(),
1043 ex.Message);
1046 return xCfg;
1047 // <- SAFE
1050 /*-----------------------------------------------
1051 24.10.2003 10:03
1052 -----------------------------------------------*/
1053 void FilterCache::impl_validateAndOptimize()
1054 throw(css::uno::Exception)
1056 // SAFE ->
1057 ::osl::ResettableMutexGuard aLock(m_aLock);
1059 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::impl_validateAndOptimize");
1061 // First check if any filter or type could be readed
1062 // from the underlying configuration!
1063 sal_Bool bSomeTypesShouldExist = ((m_eFillState & E_CONTAINS_STANDARD ) == E_CONTAINS_STANDARD );
1064 sal_Bool bAllFiltersShouldExist = ((m_eFillState & E_CONTAINS_FILTERS ) == E_CONTAINS_FILTERS );
1066 #if OSL_DEBUG_LEVEL > 0
1068 sal_Int32 nWarnings = 0;
1070 // sal_Bool bAllTypesShouldExist = ((m_eFillState & E_CONTAINS_TYPES ) == E_CONTAINS_TYPES );
1071 sal_Bool bAllLoadersShouldExist = ((m_eFillState & E_CONTAINS_FRAMELOADERS ) == E_CONTAINS_FRAMELOADERS );
1072 sal_Bool bAllHandlersShouldExist = ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS);
1073 #endif
1075 if (
1077 (bSomeTypesShouldExist) &&
1078 (m_lTypes.size() < 1 )
1079 ) ||
1081 (bAllFiltersShouldExist) &&
1082 (m_lFilters.size() < 1 )
1086 throw css::document::CorruptedFilterConfigurationException(
1087 MESSAGE_CORRUPTED_FILTERCONFIG,
1088 css::uno::Reference< css::uno::XInterface >(),
1089 ::rtl::OUString::createFromAscii("The list of types or filters is empty."));
1092 // Create a log for all detected problems, which
1093 // occure in the next feew lines.
1094 // If there are some real errors throw a RuntimException!
1095 // If there are some warnings only, show an assertion.
1096 sal_Int32 nErrors = 0;
1097 ::rtl::OUStringBuffer sLog(256);
1099 CacheItemList::iterator pIt;
1101 for (pIt = m_lTypes.begin(); pIt != m_lTypes.end(); ++pIt)
1103 ::rtl::OUString sType = pIt->first;
1104 CacheItem aType = pIt->second;
1106 // create list of all known detect services / frame loader / content handler on demand
1107 // Because these informations are available as type properties!
1108 ::rtl::OUString sDetectService;
1109 aType[PROPNAME_DETECTSERVICE ] >>= sDetectService;
1110 if (sDetectService.getLength())
1111 impl_resolveItem4TypeRegistration(&m_lDetectServices, sDetectService, sType);
1113 // get its registration for file Extensions AND(!) URLPattern ...
1114 // It doesnt matter if these items exists or if our
1115 // used index access create some default ones ...
1116 // only in case there is no filled set of Extensions AND
1117 // no filled set of URLPattern -> we must try to remove this invalid item
1118 // from this cache!
1119 css::uno::Sequence< ::rtl::OUString > lExtensions;
1120 css::uno::Sequence< ::rtl::OUString > lURLPattern;
1121 aType[PROPNAME_EXTENSIONS] >>= lExtensions;
1122 aType[PROPNAME_URLPATTERN] >>= lURLPattern;
1123 sal_Int32 ce = lExtensions.getLength();
1124 sal_Int32 cu = lURLPattern.getLength();
1126 #if OSL_DEBUG_LEVEL > 0
1128 ::rtl::OUString sInternalTypeNameCheck;
1129 aType[PROPNAME_NAME] >>= sInternalTypeNameCheck;
1130 if (!sInternalTypeNameCheck.equals(sType))
1132 sLog.appendAscii("Warning\t:\t");
1133 sLog.appendAscii("The type \"" );
1134 sLog.append (sType );
1135 sLog.appendAscii("\" does support the property \"Name\" correctly.\n");
1136 ++nWarnings;
1139 if (!ce && !cu)
1141 sLog.appendAscii("Warning\t:\t");
1142 sLog.appendAscii("The type \"" );
1143 sLog.append (sType );
1144 sLog.appendAscii("\" does not contain any URL pattern nor any extensions.\n");
1145 ++nWarnings;
1147 #endif
1149 // create an optimized registration for this type to
1150 // its set list of extensions/url pattern. If its a "normal" type
1151 // set it at the end of this optimized list. But if its
1152 // a "Preferred" one - set it to the front of this list.
1153 // Of course multiple "Preferred" registrations can occure
1154 // (they shouldnt - but they can!) ... Ignore it. The last
1155 // preferred type is useable in the same manner then every
1156 // other type!
1157 sal_Bool bPreferred = sal_False;
1158 aType[PROPNAME_PREFERRED] >>= bPreferred;
1160 const ::rtl::OUString* pExtensions = lExtensions.getConstArray();
1161 for (sal_Int32 e=0; e<ce; ++e)
1163 // Note: We must be shure that adress the right hash entry
1164 // does not depend from any upper/lower case problems ...
1165 ::rtl::OUString sNormalizedExtension = pExtensions[e].toAsciiLowerCase();
1167 OUStringList& lTypesForExtension = m_lExtensions2Types[sNormalizedExtension];
1168 if (::std::find(lTypesForExtension.begin(), lTypesForExtension.end(), sType) != lTypesForExtension.end())
1169 continue;
1171 if (bPreferred)
1172 lTypesForExtension.insert(lTypesForExtension.begin(), sType);
1173 else
1174 lTypesForExtension.push_back(sType);
1177 const ::rtl::OUString* pURLPattern = lURLPattern.getConstArray();
1178 for (sal_Int32 u=0; u<cu; ++u)
1180 OUStringList& lTypesForURLPattern = m_lURLPattern2Types[pURLPattern[u]];
1181 if (::std::find(lTypesForURLPattern.begin(), lTypesForURLPattern.end(), sType) != lTypesForURLPattern.end())
1182 continue;
1184 if (bPreferred)
1185 lTypesForURLPattern.insert(lTypesForURLPattern.begin(), sType);
1186 else
1187 lTypesForURLPattern.push_back(sType);
1190 #if OSL_DEBUG_LEVEL > 0
1192 // Dont check cross references between types and filters, if
1193 // not all filters read from disk!
1194 // OK - this cache can read single filters on demand too ...
1195 // but then the fill state of this cache shouldnt be set to E_CONTAINS_FILTERS!
1196 if (!bAllFiltersShouldExist)
1197 continue;
1199 ::rtl::OUString sPrefFilter;
1200 aType[PROPNAME_PREFERREDFILTER] >>= sPrefFilter;
1201 if (!sPrefFilter.getLength())
1203 // OK - there is no filter for this type. But thats not an error.
1204 // May be it can be handled by a ContentHandler ...
1205 // But at this time its not guaranteed that there is any ContentHandler
1206 // or FrameLoader inside this cache ... but on disk ...
1207 sal_Bool bReferencedByLoader = sal_True;
1208 sal_Bool bReferencedByHandler = sal_True;
1209 if (bAllLoadersShouldExist)
1210 bReferencedByLoader = (impl_searchFrameLoaderForType(sType).getLength()!=0);
1212 if (bAllHandlersShouldExist)
1213 bReferencedByHandler = (impl_searchContentHandlerForType(sType).getLength()!=0);
1215 if (
1216 (!bReferencedByLoader ) &&
1217 (!bReferencedByHandler)
1220 sLog.appendAscii("Warning\t:\t" );
1221 sLog.appendAscii("The type \"" );
1222 sLog.append (sType );
1223 sLog.appendAscii("\" isnt used by any filter, loader or content handler.\n");
1224 ++nWarnings;
1228 if (sPrefFilter.getLength())
1230 CacheItemList::const_iterator pIt2 = m_lFilters.find(sPrefFilter);
1231 if (pIt2 == m_lFilters.end())
1233 if (bAllFiltersShouldExist)
1235 ++nWarnings; // preferred filters can point to a non-installed office module ! no error ... it's a warning only .-(
1236 sLog.appendAscii("error\t:\t");
1238 else
1240 ++nWarnings;
1241 sLog.appendAscii("warning\t:\t");
1244 sLog.appendAscii("The type \"" );
1245 sLog.append (sType );
1246 sLog.appendAscii("\" points to an invalid filter \"");
1247 sLog.append (sPrefFilter );
1248 sLog.appendAscii("\".\n" );
1250 continue;
1253 CacheItem aPrefFilter = pIt2->second;
1254 ::rtl::OUString sFilterTypeReg;
1255 aPrefFilter[PROPNAME_TYPE] >>= sFilterTypeReg;
1256 if (sFilterTypeReg != sType)
1258 sLog.appendAscii("error\t:\t" );
1259 sLog.appendAscii("The preferred filter \"" );
1260 sLog.append (sPrefFilter );
1261 sLog.appendAscii("\" of type \"" );
1262 sLog.append (sType );
1263 sLog.appendAscii("is registered for another type \"");
1264 sLog.append (sFilterTypeReg );
1265 sLog.appendAscii("\".\n" );
1266 ++nErrors;
1269 sal_Int32 nFlags = 0;
1270 aPrefFilter[PROPNAME_FLAGS] >>= nFlags;
1271 if ((nFlags & FLAGVAL_IMPORT) != FLAGVAL_IMPORT)
1273 sLog.appendAscii("error\t:\t" );
1274 sLog.appendAscii("The preferred filter \"" );
1275 sLog.append (sPrefFilter );
1276 sLog.appendAscii("\" of type \"" );
1277 sLog.append (sType );
1278 sLog.appendAscii("\" is not an IMPORT filter!\n");
1279 ++nErrors;
1282 ::rtl::OUString sInternalFilterNameCheck;
1283 aPrefFilter[PROPNAME_NAME] >>= sInternalFilterNameCheck;
1284 if (!sInternalFilterNameCheck.equals(sPrefFilter))
1286 sLog.appendAscii("Warning\t:\t" );
1287 sLog.appendAscii("The filter \"" );
1288 sLog.append (sPrefFilter );
1289 sLog.appendAscii("\" does support the property \"Name\" correctly.\n");
1290 ++nWarnings;
1293 #endif
1296 // create dependencies between the global default frame loader
1297 // and all types (and of course if registered filters), which
1298 // does not registered for any other loader.
1299 css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
1300 ::rtl::OUString sDefaultFrameLoader;
1302 if (
1303 (!(aDirectValue >>= sDefaultFrameLoader)) ||
1304 (!sDefaultFrameLoader.getLength() )
1307 sLog.appendAscii("error\t:\t" );
1308 sLog.appendAscii("There is no valid default frame loader!?\n");
1309 ++nErrors;
1312 // a) get list of all well known types
1313 // b) step over all well known frame loader services
1314 // and remove all types from list a), which already
1315 // referenced by a loader b)
1316 OUStringList lTypes = getItemNames(E_TYPE);
1317 for ( pIt = m_lFrameLoaders.begin();
1318 pIt != m_lFrameLoaders.end() ;
1319 ++pIt )
1321 // Note: of course the default loader must be ignored here.
1322 // Because we replace its registration later completly with all
1323 // types, which are not referenced by any other loader.
1324 // So we can avaoid our code against the complexity of a diff!
1325 ::rtl::OUString sLoader = pIt->first;
1326 if (sLoader.equals(sDefaultFrameLoader))
1327 continue;
1329 CacheItem& rLoader = pIt->second;
1330 css::uno::Any& rTypesReg = rLoader[PROPNAME_TYPES];
1331 OUStringList lTypesReg (rTypesReg);
1333 for (OUStringList::const_iterator pTypesReg = lTypesReg.begin();
1334 pTypesReg != lTypesReg.end() ;
1335 ++pTypesReg )
1337 OUStringList::iterator pTypeCheck = ::std::find(lTypes.begin(), lTypes.end(), *pTypesReg);
1338 if (pTypeCheck != lTypes.end())
1339 lTypes.erase(pTypeCheck);
1343 CacheItem& rDefaultLoader = m_lFrameLoaders[sDefaultFrameLoader];
1344 rDefaultLoader[PROPNAME_NAME ] <<= sDefaultFrameLoader;
1345 rDefaultLoader[PROPNAME_TYPES] <<= lTypes.getAsConstList();
1347 ::rtl::OUString sLogOut = sLog.makeStringAndClear();
1348 OSL_ENSURE(!nErrors, ::rtl::OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1349 if (nErrors>0)
1350 throw css::document::CorruptedFilterConfigurationException(
1351 MESSAGE_CORRUPTED_FILTERCONFIG,
1352 css::uno::Reference< css::uno::XInterface >(),
1353 sLogOut);
1354 OSL_ENSURE(!nWarnings, ::rtl::OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1356 // <- SAFE
1359 /*-----------------------------------------------
1360 20.10.2003 08:15
1361 -----------------------------------------------*/
1362 void FilterCache::impl_addItem2FlushList( EItemType eType,
1363 const ::rtl::OUString& sItem)
1364 throw(css::uno::Exception)
1366 OUStringList* pList = 0;
1367 switch(eType)
1369 case E_TYPE :
1370 pList = &m_lChangedTypes;
1371 break;
1373 case E_FILTER :
1374 pList = &m_lChangedFilters;
1375 break;
1377 case E_FRAMELOADER :
1378 pList = &m_lChangedFrameLoaders;
1379 break;
1381 case E_CONTENTHANDLER :
1382 pList = &m_lChangedContentHandlers;
1383 break;
1385 case E_DETECTSERVICE :
1386 pList = &m_lChangedDetectServices;
1387 break;
1389 default : throw css::uno::Exception(::rtl::OUString::createFromAscii("unsupported item type"), 0);
1392 OUStringList::const_iterator pItem = ::std::find(pList->begin(), pList->end(), sItem);
1393 if (pItem == pList->end())
1394 pList->push_back(sItem);
1397 /*-----------------------------------------------
1398 20.10.2003 08:49
1399 -----------------------------------------------*/
1400 FilterCache::EItemFlushState FilterCache::impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1401 const CacheItemList& rList,
1402 const ::rtl::OUString& sItem)
1403 throw(css::uno::Exception)
1405 sal_Bool bExistsInConfigLayer = xSet->hasByName(sItem);
1406 sal_Bool bExistsInMemory = (rList.find(sItem) != rList.end());
1408 EItemFlushState eState( E_ITEM_UNCHANGED );
1410 // !? ... such situation can occure, if an item was added and(!) removed before it was flushed :-)
1411 if (!bExistsInConfigLayer && !bExistsInMemory)
1412 eState = E_ITEM_UNCHANGED;
1413 else
1414 if (!bExistsInConfigLayer && bExistsInMemory)
1415 eState = E_ITEM_ADDED;
1416 else
1417 if (bExistsInConfigLayer && bExistsInMemory)
1418 eState = E_ITEM_CHANGED;
1419 else
1420 if (bExistsInConfigLayer && !bExistsInMemory)
1421 eState = E_ITEM_REMOVED;
1423 return eState;
1426 /*-----------------------------------------------
1427 14.10.2003 09:26
1428 -----------------------------------------------*/
1429 void FilterCache::impl_resolveItem4TypeRegistration( CacheItemList* pList,
1430 const ::rtl::OUString& sItem,
1431 const ::rtl::OUString& sType)
1432 throw(css::uno::Exception)
1434 CacheItem& rItem = (*pList)[sItem];
1435 // In case its a new created entry (automaticly done by the hash_map index operator!)
1436 // we must be shure, that this entry has its own name as property available.
1437 // Its needed later at our container interface!
1438 rItem[PROPNAME_NAME] <<= sItem;
1440 OUStringList lTypeRegs(rItem[PROPNAME_TYPES]);
1441 if (::std::find(lTypeRegs.begin(), lTypeRegs.end(), sType) == lTypeRegs.end())
1443 lTypeRegs.push_back(sType);
1444 rItem[PROPNAME_TYPES] <<= lTypeRegs.getAsConstList();
1448 /*-----------------------------------------------
1449 28.10.2003 09:18
1450 -----------------------------------------------*/
1451 void FilterCache::impl_load(EFillState eRequiredState)
1452 throw(css::uno::Exception)
1454 // SAFE ->
1455 ::osl::ResettableMutexGuard aLock(m_aLock);
1457 // Attention: Detect services are part of the standard set!
1458 // So there is no need to handle it seperatly.
1460 // ------------------------------------------
1461 // a) The standard set of config value is needed.
1462 if (
1463 ((eRequiredState & E_CONTAINS_STANDARD) == E_CONTAINS_STANDARD) &&
1464 ((m_eFillState & E_CONTAINS_STANDARD) != E_CONTAINS_STANDARD)
1467 // Attention! If config couldnt be opened successfully
1468 // and exception os thrown automaticly and must be forwarded
1469 // to our calli ...
1470 css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
1472 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load std");
1473 impl_loadSet(xTypes, E_TYPE, E_READ_STANDARD, &m_lTypes);
1477 // ------------------------------------------
1478 // b) We need all type informations ...
1479 if (
1480 ((eRequiredState & E_CONTAINS_TYPES) == E_CONTAINS_TYPES) &&
1481 ((m_eFillState & E_CONTAINS_TYPES) != E_CONTAINS_TYPES)
1484 // Attention! If config couldnt be opened successfully
1485 // and exception os thrown automaticly and must be forwarded
1486 // to our calli ...
1487 css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
1489 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all types");
1490 impl_loadSet(xTypes, E_TYPE, E_READ_UPDATE, &m_lTypes);
1494 // ------------------------------------------
1495 // c) We need all filter informations ...
1496 if (
1497 ((eRequiredState & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) &&
1498 ((m_eFillState & E_CONTAINS_FILTERS) != E_CONTAINS_FILTERS)
1501 // Attention! If config couldnt be opened successfully
1502 // and exception os thrown automaticly and must be forwarded
1503 // to our calli ...
1504 css::uno::Reference< css::container::XNameAccess > xFilters(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY);
1506 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all filters");
1507 impl_loadSet(xFilters, E_FILTER, E_READ_ALL, &m_lFilters);
1511 // ------------------------------------------
1512 // c) We need all frame loader informations ...
1513 if (
1514 ((eRequiredState & E_CONTAINS_FRAMELOADERS) == E_CONTAINS_FRAMELOADERS) &&
1515 ((m_eFillState & E_CONTAINS_FRAMELOADERS) != E_CONTAINS_FRAMELOADERS)
1518 // Attention! If config couldnt be opened successfully
1519 // and exception os thrown automaticly and must be forwarded
1520 // to our calli ...
1521 css::uno::Reference< css::container::XNameAccess > xLoaders(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
1523 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all frame loader");
1524 impl_loadSet(xLoaders, E_FRAMELOADER, E_READ_ALL, &m_lFrameLoaders);
1528 // ------------------------------------------
1529 // d) We need all content handler informations ...
1530 if (
1531 ((eRequiredState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS) &&
1532 ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) != E_CONTAINS_CONTENTHANDLERS)
1535 // Attention! If config couldnt be opened successfully
1536 // and exception os thrown automaticly and must be forwarded
1537 // to our calli ...
1538 css::uno::Reference< css::container::XNameAccess > xHandlers(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
1540 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all content handler");
1541 impl_loadSet(xHandlers, E_CONTENTHANDLER, E_READ_ALL, &m_lContentHandlers);
1545 // update fill state. Note: its a bit field, which combines different parts.
1546 m_eFillState = (EFillState) ((sal_Int32)m_eFillState | (sal_Int32)eRequiredState);
1548 // any data readed?
1549 // yes! => validate it and update optimized structures.
1550 impl_validateAndOptimize();
1552 // <- SAFE
1555 static bool isOdfConverterInstalled()
1557 static bool bTested = false;
1558 static bool bInstalled = false;
1560 if ( bTested )
1561 return bInstalled;
1563 bTested = true;
1565 // the easy path - check for the OdfConverter binary
1566 rtl::OUString aPath;
1568 rtl::Bootstrap::get( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ), aPath );
1569 aPath += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/OdfConverter" ) );
1571 osl::DirectoryItem aDirItem;
1572 if ( osl::DirectoryItem::get( aPath, aDirItem ) == osl::FileBase::E_None )
1574 bInstalled = true;
1575 return bInstalled;
1578 // check the installed extensions
1579 uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> xMS(::comphelper::getProcessServiceFactory(), uno::UNO_QUERY);
1580 uno::Reference< beans::XPropertySet > xProps(xMS, uno::UNO_QUERY);
1581 uno::Reference< uno::XComponentContext > xContext(xProps->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")), uno::UNO_QUERY);
1583 uno::Reference< deployment::XPackageManager > xUserContext(
1584 deployment::thePackageManagerFactory::get (xContext)->getPackageManager( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("user") ) ) );
1585 uno::Reference< ::com::sun::star::deployment::XPackageManager > xSharedContext(
1586 deployment::thePackageManagerFactory::get (xContext)->getPackageManager( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("shared") ) ) );
1588 uno::Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = uno::Reference< task::XInteractionHandler > (
1589 xMS->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), uno::UNO_QUERY );
1590 ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, uno::Reference< ucb::XProgressHandler >() );
1592 uno::Reference< ucb::XCommandEnvironment > xCmdEnv( static_cast< ::com::sun::star::ucb::XCommandEnvironment* >( pCommandEnv ), uno::UNO_QUERY );
1594 const uno::Sequence< uno::Reference< deployment::XPackage > > userPackages(
1595 xUserContext->getDeployedPackages( NULL, xCmdEnv ) );
1596 const uno::Sequence< uno::Reference< deployment::XPackage > > sharedPackages(
1597 xSharedContext->getDeployedPackages( NULL, xCmdEnv ) );
1599 const uno::Sequence< uno::Reference< deployment::XPackage > > pkgsArray[2] = {
1600 userPackages,
1601 sharedPackages
1604 for ( int i = 0; i < 2; i++ ) {
1605 const uno::Sequence< uno::Reference< deployment::XPackage > > pkgs = pkgsArray[i];
1607 for ( int j = 0; j < pkgs.getLength(); j++ ) {
1608 rtl::OUString fname = pkgs[j]->getName();
1609 if ( fname.matchIgnoreAsciiCase( rtl::OUString::createFromAscii( "odf-converter-" ) ) ) {
1610 printf( "Found match for odf-converter!\n");
1611 fflush( stdout );
1612 bInstalled = true;
1613 return bInstalled;
1618 return false;
1621 static bool terribleHackToPreferOdfConverter( const rtl::OUString& rName )
1623 if ( !isOdfConverterInstalled() )
1624 return false;
1626 if ( rName.equalsAscii( "Calc MS Excel 2007 XML" ) ||
1627 rName.equalsAscii( "MS Excel 2007 XML" ) ||
1628 rName.equalsAscii( "MS PowerPoint 2007 XML" ) ||
1629 rName.equalsAscii( "Impress MS PowerPoint 2007 XML" ) ||
1630 rName.equalsAscii( "writer_MS_Word_2007" ) ||
1631 rName.equalsAscii( "MS Word 2007 XML" ) )
1633 return true;
1636 return false;
1639 /*-----------------------------------------------
1640 22.09.2003 14:27
1641 -----------------------------------------------*/
1642 void FilterCache::impl_loadSet(const css::uno::Reference< css::container::XNameAccess >& xConfig,
1643 EItemType eType ,
1644 EReadOption eOption,
1645 CacheItemList* pCache )
1646 throw(css::uno::Exception)
1648 // get access to the right configuration set
1649 ::rtl::OUString sSetName;
1650 switch(eType)
1652 case E_TYPE :
1653 sSetName = CFGSET_TYPES;
1654 break;
1656 case E_FILTER :
1657 sSetName = CFGSET_FILTERS;
1658 break;
1660 case E_FRAMELOADER :
1661 sSetName = CFGSET_FRAMELOADERS;
1662 break;
1664 case E_CONTENTHANDLER :
1665 sSetName = CFGSET_CONTENTHANDLERS;
1666 break;
1667 default: break;
1670 css::uno::Reference< css::container::XNameAccess > xSet;
1671 css::uno::Sequence< ::rtl::OUString > lItems;
1675 css::uno::Any aVal = xConfig->getByName(sSetName);
1676 if (!(aVal >>= xSet) || !xSet.is())
1678 ::rtl::OUStringBuffer sMsg(256);
1679 sMsg.appendAscii("Could not open configuration set \"");
1680 sMsg.append (sSetName );
1681 sMsg.appendAscii("\"." );
1682 throw css::uno::Exception(
1683 sMsg.makeStringAndClear(),
1684 css::uno::Reference< css::uno::XInterface >());
1686 lItems = xSet->getElementNames();
1688 catch(const css::uno::Exception& ex)
1690 throw css::document::CorruptedFilterConfigurationException(
1691 MESSAGE_CORRUPTED_FILTERCONFIG,
1692 css::uno::Reference< css::uno::XInterface >(),
1693 ex.Message);
1696 // get names of all existing sub items of this set
1697 // step over it and fill internal cache structures.
1699 // But dont update optimized structures like e.g. hash
1700 // for mapping extensions to its types!
1702 const ::rtl::OUString* pItems = lItems.getConstArray();
1703 sal_Int32 c = lItems.getLength();
1704 for (sal_Int32 i=0; i<c; ++i)
1706 if ( terribleHackToPreferOdfConverter( pItems[i] ) )
1707 continue;
1709 CacheItemList::iterator pItem = pCache->find(pItems[i]);
1710 switch(eOption)
1712 // a) read a standard set of properties only or read all
1713 case E_READ_STANDARD :
1714 case E_READ_ALL :
1718 (*pCache)[pItems[i]] = impl_loadItem(xSet, eType, pItems[i], eOption);
1720 catch(const css::uno::Exception& ex)
1722 throw css::document::CorruptedFilterConfigurationException(
1723 MESSAGE_CORRUPTED_FILTERCONFIG,
1724 css::uno::Reference< css::uno::XInterface >(),
1725 ex.Message);
1728 break;
1730 // b) read optional properties only!
1731 // All items must already exist inside our cache.
1732 // But they must be updated.
1733 case E_READ_UPDATE :
1735 if (pItem == pCache->end())
1737 ::rtl::OUStringBuffer sMsg(256);
1738 sMsg.appendAscii("item \"" );
1739 sMsg.append (pItems[i] );
1740 sMsg.appendAscii("\" not found for update!");
1741 throw css::uno::Exception(sMsg.makeStringAndClear() ,
1742 css::uno::Reference< css::uno::XInterface >());
1746 CacheItem aItem = impl_loadItem(xSet, eType, pItems[i], eOption);
1747 pItem->second.update(aItem);
1749 catch(const css::uno::Exception& ex)
1751 throw css::document::CorruptedFilterConfigurationException(
1752 MESSAGE_CORRUPTED_FILTERCONFIG,
1753 css::uno::Reference< css::uno::XInterface >(),
1754 ex.Message);
1757 break;
1758 default: break;
1763 /*-----------------------------------------------
1764 26.11.2003 12:49
1765 -----------------------------------------------*/
1766 void FilterCache::impl_readPatchUINames(const css::uno::Reference< css::container::XNameAccess >& xNode,
1767 CacheItem& rItem)
1768 throw(css::uno::Exception)
1770 static ::rtl::OUString FORMATNAME_VAR = ::rtl::OUString::createFromAscii("%productname%" );
1771 static ::rtl::OUString FORMATVERSION_VAR = ::rtl::OUString::createFromAscii("%formatversion%");
1773 // SAFE -> ----------------------------------
1774 ::osl::ResettableMutexGuard aLock(m_aLock);
1775 ::rtl::OUString sFormatName = m_sFormatName ;
1776 ::rtl::OUString sFormatVersion = m_sFormatVersion;
1777 ::rtl::OUString sActLocale = m_sActLocale ;
1778 aLock.clear();
1779 // <- SAFE ----------------------------------
1781 css::uno::Any aVal = xNode->getByName(PROPNAME_UINAME);
1782 css::uno::Reference< css::container::XNameAccess > xUIName;
1783 if (!(aVal >>= xUIName) && !xUIName.is())
1784 return;
1786 const ::comphelper::SequenceAsVector< ::rtl::OUString > lLocales(xUIName->getElementNames());
1787 ::comphelper::SequenceAsVector< ::rtl::OUString >::const_iterator pLocale ;
1788 ::comphelper::SequenceAsHashMap lUINames;
1790 // patch %PRODUCTNAME and %FORMATNAME
1791 for ( pLocale = lLocales.begin();
1792 pLocale != lLocales.end() ;
1793 ++pLocale )
1795 const ::rtl::OUString& sLocale = *pLocale;
1797 ::rtl::OUString sValue;
1798 xUIName->getByName(sLocale) >>= sValue;
1800 // replace %productname%
1801 sal_Int32 nIndex = sValue.indexOf(FORMATNAME_VAR);
1802 while(nIndex != -1)
1804 sValue = sValue.replaceAt(nIndex, FORMATNAME_VAR.getLength(), sFormatName);
1805 nIndex = sValue.indexOf(FORMATNAME_VAR, nIndex);
1807 // replace %formatversion%
1808 nIndex = sValue.indexOf(FORMATVERSION_VAR);
1809 while(nIndex != -1)
1811 sValue = sValue.replaceAt(nIndex, FORMATVERSION_VAR.getLength(), sFormatVersion);
1812 nIndex = sValue.indexOf(FORMATVERSION_VAR, nIndex);
1815 lUINames[sLocale] <<= sValue;
1818 aVal <<= lUINames.getAsConstPropertyValueList();
1819 rItem[PROPNAME_UINAMES] = aVal;
1821 // find right UIName for current office locale
1822 // Use fallbacks too!
1823 pLocale = ::comphelper::Locale::getFallback(lLocales, sActLocale);
1824 if (pLocale == lLocales.end())
1826 #if OSL_DEBUG_LEVEL > 0
1827 ::rtl::OUString sName = rItem.getUnpackedValueOrDefault(PROPNAME_NAME, ::rtl::OUString());
1829 ::rtl::OUStringBuffer sMsg(256);
1830 sMsg.appendAscii("Fallback scenario for filter or type '" );
1831 sMsg.append (sName );
1832 sMsg.appendAscii("' and locale '" );
1833 sMsg.append (sActLocale );
1834 sMsg.appendAscii("' failed. Please check your filter configuration.");
1836 OSL_ENSURE(sal_False, _FILTER_CONFIG_TO_ASCII_(sMsg.makeStringAndClear()));
1837 #endif
1838 return;
1841 const ::rtl::OUString& sLocale = *pLocale;
1842 ::comphelper::SequenceAsHashMap::const_iterator pUIName = lUINames.find(sLocale);
1843 if (pUIName != lUINames.end())
1844 rItem[PROPNAME_UINAME] = pUIName->second;
1847 /*-----------------------------------------------
1848 26.11.2003 12:56
1849 -----------------------------------------------*/
1850 void FilterCache::impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
1851 const CacheItem& rItem)
1852 throw(css::uno::Exception)
1854 css::uno::Reference< css::container::XNameContainer > xAdd (xNode, css::uno::UNO_QUERY);
1855 css::uno::Reference< css::container::XNameAccess > xCheck(xNode, css::uno::UNO_QUERY);
1857 css::uno::Sequence< css::beans::PropertyValue > lUINames = rItem.getUnpackedValueOrDefault(PROPNAME_UINAMES, css::uno::Sequence< css::beans::PropertyValue >());
1858 sal_Int32 c = lUINames.getLength();
1859 const css::beans::PropertyValue* pUINames = lUINames.getConstArray();
1861 for (sal_Int32 i=0; i<c; ++i)
1863 if (xCheck->hasByName(pUINames[i].Name))
1864 xNode->replaceByName(pUINames[i].Name, pUINames[i].Value);
1865 else
1866 xAdd->insertByName(pUINames[i].Name, pUINames[i].Value);
1870 /*-----------------------------------------------
1871 29.10.2003 13:17
1872 TODO
1873 clarify, how the real problem behind the
1874 wrong constructed CacheItem instance (which
1875 will force a crash during destruction)
1876 can be solved ...
1877 -----------------------------------------------*/
1878 CacheItem FilterCache::impl_loadItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1879 EItemType eType ,
1880 const ::rtl::OUString& sItem ,
1881 EReadOption eOption)
1882 throw(css::uno::Exception)
1884 // try to get an API object, which points directly to the
1885 // requested item. If it fail an exception should occure and
1886 // break this operation. Of course returned API object must be
1887 // checked too.
1888 css::uno::Reference< css::container::XNameAccess > xItem;
1889 #ifdef WORKAROUND_EXCEPTION_PROBLEM
1892 #endif
1893 css::uno::Any aVal = xSet->getByName(sItem);
1894 if (!(aVal >>= xItem) || !xItem.is())
1896 ::rtl::OUStringBuffer sMsg(256);
1897 sMsg.appendAscii("found corrupted item \"");
1898 sMsg.append (sItem );
1899 sMsg.appendAscii("\"." );
1900 throw css::uno::Exception(sMsg.makeStringAndClear() ,
1901 css::uno::Reference< css::uno::XInterface >());
1903 #ifdef WORKAROUND_EXCEPTION_PROBLEM
1905 catch(const css::container::NoSuchElementException&)
1907 throw;
1909 #endif
1911 // The internal name of an item must(!) be part of the property
1912 // set too. Of course its already used as key into the e.g. outside
1913 // used hash map ... but some of our API methods provide
1914 // this property set as result only. But the user of this CacheItem
1915 // should know, which value the key names has :-) ITS IMPORTANT!
1916 CacheItem aItem;
1917 aItem[PROPNAME_NAME] = css::uno::makeAny(sItem);
1918 switch(eType)
1920 //---------------------------------------
1921 case E_TYPE :
1923 // read standard properties of a type
1924 if (
1925 (eOption == E_READ_STANDARD) ||
1926 (eOption == E_READ_ALL )
1929 aItem[PROPNAME_PREFERREDFILTER] = xItem->getByName(PROPNAME_PREFERREDFILTER);
1930 aItem[PROPNAME_DETECTSERVICE ] = xItem->getByName(PROPNAME_DETECTSERVICE );
1931 aItem[PROPNAME_URLPATTERN ] = xItem->getByName(PROPNAME_URLPATTERN );
1932 aItem[PROPNAME_EXTENSIONS ] = xItem->getByName(PROPNAME_EXTENSIONS );
1933 aItem[PROPNAME_PREFERRED ] = xItem->getByName(PROPNAME_PREFERRED );
1934 aItem[PROPNAME_CLIPBOARDFORMAT] = xItem->getByName(PROPNAME_CLIPBOARDFORMAT);
1936 // read optional properties of a type
1937 // no else here! Is an additional switch ...
1938 if (
1939 (eOption == E_READ_UPDATE) ||
1940 (eOption == E_READ_ALL )
1943 aItem[PROPNAME_MEDIATYPE ] = xItem->getByName(PROPNAME_MEDIATYPE );
1944 impl_readPatchUINames(xItem, aItem);
1947 break;
1949 //---------------------------------------
1950 case E_FILTER :
1952 // read standard properties of a filter
1953 if (
1954 (eOption == E_READ_STANDARD) ||
1955 (eOption == E_READ_ALL )
1958 aItem[PROPNAME_TYPE ] = xItem->getByName(PROPNAME_TYPE );
1959 aItem[PROPNAME_FILEFORMATVERSION] = xItem->getByName(PROPNAME_FILEFORMATVERSION);
1960 aItem[PROPNAME_UICOMPONENT ] = xItem->getByName(PROPNAME_UICOMPONENT );
1961 aItem[PROPNAME_FILTERSERVICE ] = xItem->getByName(PROPNAME_FILTERSERVICE );
1962 aItem[PROPNAME_DOCUMENTSERVICE ] = xItem->getByName(PROPNAME_DOCUMENTSERVICE );
1964 // special handling for flags! Convert it from a list of names to its
1965 // int representation ...
1966 css::uno::Sequence< ::rtl::OUString > lFlagNames;
1967 if (xItem->getByName(PROPNAME_FLAGS) >>= lFlagNames)
1968 aItem[PROPNAME_FLAGS] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
1970 // read optional properties of a filter
1971 // no else here! Is an additional switch ...
1972 if (
1973 (eOption == E_READ_UPDATE) ||
1974 (eOption == E_READ_ALL )
1977 aItem[PROPNAME_USERDATA ] = xItem->getByName(PROPNAME_USERDATA );
1978 aItem[PROPNAME_TEMPLATENAME] = xItem->getByName(PROPNAME_TEMPLATENAME);
1979 //TODO remove it if moving of filter uinames to type uinames
1980 // will be finished realy
1981 #ifdef AS_ENABLE_FILTER_UINAMES
1982 impl_readPatchUINames(xItem, aItem);
1983 #endif // AS_ENABLE_FILTER_UINAMES
1986 break;
1988 //---------------------------------------
1989 case E_FRAMELOADER :
1990 case E_CONTENTHANDLER :
1992 aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
1994 break;
1995 default: break;
1998 return aItem;
2001 /*-----------------------------------------------
2002 27.10.2003 08:47
2003 -----------------------------------------------*/
2004 CacheItemList::iterator FilterCache::impl_loadItemOnDemand( EItemType eType,
2005 const ::rtl::OUString& sItem)
2006 throw(css::uno::Exception)
2008 CacheItemList* pList = 0;
2009 css::uno::Reference< css::uno::XInterface > xConfig ;
2010 ::rtl::OUString sSet ;
2012 switch(eType)
2014 case E_TYPE :
2016 pList = &m_lTypes;
2017 xConfig = impl_openConfig(E_PROVIDER_TYPES);
2018 sSet = CFGSET_TYPES;
2020 break;
2022 case E_FILTER :
2024 pList = &m_lFilters;
2025 xConfig = impl_openConfig(E_PROVIDER_FILTERS);
2026 sSet = CFGSET_FILTERS;
2028 break;
2030 case E_FRAMELOADER :
2032 pList = &m_lFrameLoaders;
2033 xConfig = impl_openConfig(E_PROVIDER_OTHERS);
2034 sSet = CFGSET_FRAMELOADERS;
2036 break;
2038 case E_CONTENTHANDLER :
2040 pList = &m_lContentHandlers;
2041 xConfig = impl_openConfig(E_PROVIDER_OTHERS);
2042 sSet = CFGSET_CONTENTHANDLERS;
2044 break;
2046 case E_DETECTSERVICE :
2048 OSL_ENSURE(sal_False, "Cant load detect services on demand. Who use this unsupported feature?");
2050 break;
2053 css::uno::Reference< css::container::XNameAccess > xRoot(xConfig, css::uno::UNO_QUERY_THROW);
2054 css::uno::Reference< css::container::XNameAccess > xSet ;
2055 xRoot->getByName(sSet) >>= xSet;
2057 CacheItemList::iterator pItemInCache = pList->find(sItem);
2058 sal_Bool bItemInConfig = xSet->hasByName(sItem);
2060 if (bItemInConfig)
2062 CacheItem aItem;
2063 CacheItem::iterator pDbgTest = aItem.find(PROPNAME_NAME);
2064 aItem = impl_loadItem(xSet, eType, sItem, E_READ_ALL);
2065 (*pList)[sItem] = aItem;
2066 _FILTER_CONFIG_LOG_2_("impl_loadItemOnDemand(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(sItem).getStr())
2068 else
2070 if (pItemInCache != pList->end())
2071 pList->erase(pItemInCache);
2072 // OK - this item does not exists inside configuration.
2073 // And we already updated our internal cache.
2074 // But the outside code needs this NoSuchElementException
2075 // to know, that this item does notexists.
2076 // Nobody checks the iterator!
2077 throw css::container::NoSuchElementException();
2080 return pList->find(sItem);
2083 /*-----------------------------------------------
2084 20.10.2003 09:38
2085 -----------------------------------------------*/
2086 void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem,
2087 EItemType eType,
2088 const CacheItem& aItem)
2089 throw(css::uno::Exception)
2091 CacheItem::const_iterator pIt;
2092 switch(eType)
2094 //---------------------------------------
2095 case E_TYPE :
2097 pIt = aItem.find(PROPNAME_PREFERREDFILTER);
2098 if (pIt != aItem.end())
2099 xItem->replaceByName(PROPNAME_PREFERREDFILTER, pIt->second);
2100 pIt = aItem.find(PROPNAME_DETECTSERVICE);
2101 if (pIt != aItem.end())
2102 xItem->replaceByName(PROPNAME_DETECTSERVICE, pIt->second);
2103 pIt = aItem.find(PROPNAME_URLPATTERN);
2104 if (pIt != aItem.end())
2105 xItem->replaceByName(PROPNAME_URLPATTERN, pIt->second);
2106 pIt = aItem.find(PROPNAME_EXTENSIONS);
2107 if (pIt != aItem.end())
2108 xItem->replaceByName(PROPNAME_EXTENSIONS, pIt->second);
2109 pIt = aItem.find(PROPNAME_PREFERRED);
2110 if (pIt != aItem.end())
2111 xItem->replaceByName(PROPNAME_PREFERRED, pIt->second);
2112 pIt = aItem.find(PROPNAME_MEDIATYPE);
2113 if (pIt != aItem.end())
2114 xItem->replaceByName(PROPNAME_MEDIATYPE, pIt->second);
2115 pIt = aItem.find(PROPNAME_CLIPBOARDFORMAT);
2116 if (pIt != aItem.end())
2117 xItem->replaceByName(PROPNAME_CLIPBOARDFORMAT, pIt->second);
2119 css::uno::Reference< css::container::XNameReplace > xUIName;
2120 xItem->getByName(PROPNAME_UINAME) >>= xUIName;
2121 impl_savePatchUINames(xUIName, aItem);
2123 break;
2125 //---------------------------------------
2126 case E_FILTER :
2128 pIt = aItem.find(PROPNAME_TYPE);
2129 if (pIt != aItem.end())
2130 xItem->replaceByName(PROPNAME_TYPE, pIt->second);
2131 pIt = aItem.find(PROPNAME_FILEFORMATVERSION);
2132 if (pIt != aItem.end())
2133 xItem->replaceByName(PROPNAME_FILEFORMATVERSION, pIt->second);
2134 pIt = aItem.find(PROPNAME_UICOMPONENT);
2135 if (pIt != aItem.end())
2136 xItem->replaceByName(PROPNAME_UICOMPONENT, pIt->second);
2137 pIt = aItem.find(PROPNAME_FILTERSERVICE);
2138 if (pIt != aItem.end())
2139 xItem->replaceByName(PROPNAME_FILTERSERVICE, pIt->second);
2140 pIt = aItem.find(PROPNAME_DOCUMENTSERVICE);
2141 if (pIt != aItem.end())
2142 xItem->replaceByName(PROPNAME_DOCUMENTSERVICE, pIt->second);
2143 pIt = aItem.find(PROPNAME_USERDATA);
2144 if (pIt != aItem.end())
2145 xItem->replaceByName(PROPNAME_USERDATA, pIt->second);
2146 pIt = aItem.find(PROPNAME_TEMPLATENAME);
2147 if (pIt != aItem.end())
2148 xItem->replaceByName(PROPNAME_TEMPLATENAME, pIt->second);
2150 // special handling for flags! Convert it from an integer flag field back
2151 // to a list of names ...
2152 // But note: because we work directly on a reference to the cache item,
2153 // its not allowd to change the value here. We must work on a copy!
2154 sal_Int32 nFlags = 0;
2155 pIt = aItem.find(PROPNAME_FLAGS);
2156 if (pIt != aItem.end())
2158 pIt->second >>= nFlags;
2159 css::uno::Any aFlagNameList;
2160 aFlagNameList <<= FilterCache::impl_convertFlagField2FlagNames(nFlags);
2161 xItem->replaceByName(PROPNAME_FLAGS, aFlagNameList);
2164 //TODO remove it if moving of filter uinames to type uinames
2165 // will be finished realy
2166 #ifdef AS_ENABLE_FILTER_UINAMES
2167 css::uno::Reference< css::container::XNameReplace > xUIName;
2168 xItem->getByName(PROPNAME_UINAME) >>= xUIName;
2169 impl_savePatchUINames(xUIName, aItem);
2170 #endif // AS_ENABLE_FILTER_UINAMES
2172 break;
2174 //---------------------------------------
2175 case E_FRAMELOADER :
2176 case E_CONTENTHANDLER :
2178 pIt = aItem.find(PROPNAME_TYPES);
2179 if (pIt != aItem.end())
2180 xItem->replaceByName(PROPNAME_TYPES, pIt->second);
2182 break;
2183 default: break;
2187 /*-----------------------------------------------
2188 20.10.2003 09:45
2189 static! => no locks neccessary
2190 -----------------------------------------------*/
2191 css::uno::Sequence< ::rtl::OUString > FilterCache::impl_convertFlagField2FlagNames(sal_Int32 nFlags)
2193 OUStringList lFlagNames;
2195 if ((nFlags & FLAGVAL_3RDPARTYFILTER ) == FLAGVAL_3RDPARTYFILTER ) lFlagNames.push_back(FLAGNAME_3RDPARTYFILTER );
2196 if ((nFlags & FLAGVAL_ALIEN ) == FLAGVAL_ALIEN ) lFlagNames.push_back(FLAGNAME_ALIEN );
2197 if ((nFlags & FLAGVAL_ASYNCHRON ) == FLAGVAL_ASYNCHRON ) lFlagNames.push_back(FLAGNAME_ASYNCHRON );
2198 if ((nFlags & FLAGVAL_BROWSERPREFERRED ) == FLAGVAL_BROWSERPREFERRED ) lFlagNames.push_back(FLAGNAME_BROWSERPREFERRED );
2199 if ((nFlags & FLAGVAL_CONSULTSERVICE ) == FLAGVAL_CONSULTSERVICE ) lFlagNames.push_back(FLAGNAME_CONSULTSERVICE );
2200 if ((nFlags & FLAGVAL_DEFAULT ) == FLAGVAL_DEFAULT ) lFlagNames.push_back(FLAGNAME_DEFAULT );
2201 if ((nFlags & FLAGVAL_EXPORT ) == FLAGVAL_EXPORT ) lFlagNames.push_back(FLAGNAME_EXPORT );
2202 if ((nFlags & FLAGVAL_IMPORT ) == FLAGVAL_IMPORT ) lFlagNames.push_back(FLAGNAME_IMPORT );
2203 if ((nFlags & FLAGVAL_INTERNAL ) == FLAGVAL_INTERNAL ) lFlagNames.push_back(FLAGNAME_INTERNAL );
2204 if ((nFlags & FLAGVAL_NOTINCHOOSER ) == FLAGVAL_NOTINCHOOSER ) lFlagNames.push_back(FLAGNAME_NOTINCHOOSER );
2205 if ((nFlags & FLAGVAL_NOTINFILEDIALOG ) == FLAGVAL_NOTINFILEDIALOG ) lFlagNames.push_back(FLAGNAME_NOTINFILEDIALOG );
2206 if ((nFlags & FLAGVAL_NOTINSTALLED ) == FLAGVAL_NOTINSTALLED ) lFlagNames.push_back(FLAGNAME_NOTINSTALLED );
2207 if ((nFlags & FLAGVAL_OWN ) == FLAGVAL_OWN ) lFlagNames.push_back(FLAGNAME_OWN );
2208 if ((nFlags & FLAGVAL_PACKED ) == FLAGVAL_PACKED ) lFlagNames.push_back(FLAGNAME_PACKED );
2209 if ((nFlags & FLAGVAL_PREFERRED ) == FLAGVAL_PREFERRED ) lFlagNames.push_back(FLAGNAME_PREFERRED );
2210 if ((nFlags & FLAGVAL_STARTPRESENTATION) == FLAGVAL_STARTPRESENTATION) lFlagNames.push_back(FLAGNAME_STARTPRESENTATION);
2211 if ((nFlags & FLAGVAL_READONLY ) == FLAGVAL_READONLY ) lFlagNames.push_back(FLAGNAME_READONLY );
2212 if ((nFlags & FLAGVAL_SILENTEXPORT ) == FLAGVAL_SILENTEXPORT ) lFlagNames.push_back(FLAGNAME_SILENTEXPORT );
2213 if ((nFlags & FLAGVAL_SUPPORTSSELECTION) == FLAGVAL_SUPPORTSSELECTION) lFlagNames.push_back(FLAGNAME_SUPPORTSSELECTION);
2214 if ((nFlags & FLAGVAL_TEMPLATE ) == FLAGVAL_TEMPLATE ) lFlagNames.push_back(FLAGNAME_TEMPLATE );
2215 if ((nFlags & FLAGVAL_TEMPLATEPATH ) == FLAGVAL_TEMPLATEPATH ) lFlagNames.push_back(FLAGNAME_TEMPLATEPATH );
2216 if ((nFlags & FLAGVAL_USESOPTIONS ) == FLAGVAL_USESOPTIONS ) lFlagNames.push_back(FLAGNAME_USESOPTIONS );
2217 if ((nFlags & FLAGVAL_COMBINED ) == FLAGVAL_COMBINED ) lFlagNames.push_back(FLAGNAME_COMBINED );
2219 return lFlagNames.getAsConstList();
2222 /*-----------------------------------------------
2223 27.06.2003 09:26
2224 static! => no locks neccessary
2225 -----------------------------------------------*/
2226 sal_Int32 FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence< ::rtl::OUString >& lNames)
2228 sal_Int32 nField = 0;
2230 const ::rtl::OUString* pNames = lNames.getConstArray();
2231 sal_Int32 c = lNames.getLength();
2232 for (sal_Int32 i=0; i<c; ++i)
2234 if (pNames[i].equals(FLAGNAME_3RDPARTYFILTER))
2236 nField |= FLAGVAL_3RDPARTYFILTER;
2237 continue;
2239 if (pNames[i].equals(FLAGNAME_ALIEN))
2241 nField |= FLAGVAL_ALIEN;
2242 continue;
2244 if (pNames[i].equals(FLAGNAME_ASYNCHRON))
2246 nField |= FLAGVAL_ASYNCHRON;
2247 continue;
2249 if (pNames[i].equals(FLAGNAME_BROWSERPREFERRED))
2251 nField |= FLAGVAL_BROWSERPREFERRED;
2252 continue;
2254 if (pNames[i].equals(FLAGNAME_CONSULTSERVICE))
2256 nField |= FLAGVAL_CONSULTSERVICE;
2257 continue;
2259 if (pNames[i].equals(FLAGNAME_DEFAULT))
2261 nField |= FLAGVAL_DEFAULT;
2262 continue;
2264 if (pNames[i].equals(FLAGNAME_EXPORT))
2266 nField |= FLAGVAL_EXPORT;
2267 continue;
2269 if (pNames[i].equals(FLAGNAME_IMPORT))
2271 nField |= FLAGVAL_IMPORT;
2272 continue;
2274 if (pNames[i].equals(FLAGNAME_INTERNAL))
2276 nField |= FLAGVAL_INTERNAL;
2277 continue;
2279 if (pNames[i].equals(FLAGNAME_NOTINCHOOSER))
2281 nField |= FLAGVAL_NOTINCHOOSER;
2282 continue;
2284 if (pNames[i].equals(FLAGNAME_NOTINFILEDIALOG))
2286 nField |= FLAGVAL_NOTINFILEDIALOG;
2287 continue;
2289 if (pNames[i].equals(FLAGNAME_NOTINSTALLED))
2291 nField |= FLAGVAL_NOTINSTALLED;
2292 continue;
2294 if (pNames[i].equals(FLAGNAME_OWN))
2296 nField |= FLAGVAL_OWN;
2297 continue;
2299 if (pNames[i].equals(FLAGNAME_PACKED))
2301 nField |= FLAGVAL_PACKED;
2302 continue;
2304 if (pNames[i].equals(FLAGNAME_PREFERRED))
2306 nField |= FLAGVAL_PREFERRED;
2307 continue;
2309 if (pNames[i].equals(FLAGNAME_STARTPRESENTATION))
2311 nField |= FLAGVAL_STARTPRESENTATION;
2312 continue;
2314 if (pNames[i].equals(FLAGNAME_READONLY))
2316 nField |= FLAGVAL_READONLY;
2317 continue;
2319 if (pNames[i].equals(FLAGNAME_SILENTEXPORT))
2321 nField |= FLAGVAL_SILENTEXPORT;
2322 continue;
2324 if (pNames[i].equals(FLAGNAME_SUPPORTSSELECTION))
2326 nField |= FLAGVAL_SUPPORTSSELECTION;
2327 continue;
2329 if (pNames[i].equals(FLAGNAME_TEMPLATE))
2331 nField |= FLAGVAL_TEMPLATE;
2332 continue;
2334 if (pNames[i].equals(FLAGNAME_TEMPLATEPATH))
2336 nField |= FLAGVAL_TEMPLATEPATH;
2337 continue;
2339 if (pNames[i].equals(FLAGNAME_USESOPTIONS))
2341 nField |= FLAGVAL_USESOPTIONS;
2342 continue;
2344 if (pNames[i].equals(FLAGNAME_COMBINED))
2346 nField |= FLAGVAL_COMBINED;
2347 continue;
2351 return nField;
2354 /*-----------------------------------------------
2355 12.02.2004 08:40
2356 -----------------------------------------------*/
2357 void FilterCache::impl_interpretDataVal4Type(const ::rtl::OUString& sValue,
2358 sal_Int32 nProp ,
2359 CacheItem& rItem )
2361 switch(nProp)
2363 // Preferred
2364 case 0: {
2365 if (sValue.toInt32() == 1)
2366 rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_True);
2367 else
2368 rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_False);
2370 break;
2371 // MediaType
2372 case 1: rItem[PROPNAME_MEDIATYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2373 break;
2374 // ClipboardFormat
2375 case 2: rItem[PROPNAME_CLIPBOARDFORMAT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2376 break;
2377 // URLPattern
2378 case 3: rItem[PROPNAME_URLPATTERN] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2379 break;
2380 // Extensions
2381 case 4: rItem[PROPNAME_EXTENSIONS] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2382 break;
2386 /*-----------------------------------------------
2387 12.02.2004 08:50
2388 -----------------------------------------------*/
2389 void FilterCache::impl_interpretDataVal4Filter(const ::rtl::OUString& sValue,
2390 sal_Int32 nProp ,
2391 CacheItem& rItem )
2393 switch(nProp)
2395 // Order
2396 case 0: {
2397 sal_Int32 nOrder = sValue.toInt32();
2398 if (nOrder > 0)
2400 OSL_ENSURE(sal_False, "FilterCache::impl_interpretDataVal4Filter()\nCant move Order value from filter to type on demand!\n");
2401 _FILTER_CONFIG_LOG_2_("impl_interpretDataVal4Filter(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(rItem).getStr())
2404 break;
2405 // Type
2406 case 1: rItem[PROPNAME_TYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2407 break;
2408 // DocumentService
2409 case 2: rItem[PROPNAME_DOCUMENTSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2410 break;
2411 // FilterService
2412 case 3: rItem[PROPNAME_FILTERSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2413 break;
2414 // Flags
2415 case 4: rItem[PROPNAME_FLAGS] <<= sValue.toInt32();
2416 break;
2417 // UserData
2418 case 5: rItem[PROPNAME_USERDATA] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2419 break;
2420 // FileFormatVersion
2421 case 6: rItem[PROPNAME_FILEFORMATVERSION] <<= sValue.toInt32();
2422 break;
2423 // TemplateName
2424 case 7: rItem[PROPNAME_TEMPLATENAME] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2425 break;
2426 // [optional!] UIComponent
2427 case 8: rItem[PROPNAME_UICOMPONENT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2428 break;
2432 /*-----------------------------------------------
2433 12.02.2004 08:30
2434 TODO work on a cache copy first, which can be flushed afterwards
2435 That would be usefully to gurantee a consistent cache.
2436 -----------------------------------------------*/
2437 void FilterCache::impl_readOldFormat()
2438 throw(css::uno::Exception)
2440 static ::rtl::OUString TYPES_SET = ::rtl::OUString::createFromAscii("Types" );
2441 static ::rtl::OUString FILTER_SET = ::rtl::OUString::createFromAscii("Filters");
2443 // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
2444 // Its optional and shouldnt disturb our normal work!
2445 // E.g. we must check, if the package exists ...
2447 css::uno::Reference< css::container::XNameAccess > xCfg;
2450 css::uno::Reference< css::uno::XInterface > xInt = impl_openConfig(E_PROVIDER_OLD);
2451 xCfg = css::uno::Reference< css::container::XNameAccess >(xInt, css::uno::UNO_QUERY_THROW);
2453 /* corrupt filter addon ? because it's external (optional) code .. we can ignore it. Addon wont work then ...
2454 but that seams to be acceptable.
2455 see #139088# for further informations
2457 catch(const css::uno::Exception&)
2458 { return; }
2460 // May be there is no type set ...
2461 if (xCfg->hasByName(TYPES_SET))
2463 css::uno::Reference< css::container::XNameAccess > xSet;
2464 xCfg->getByName(TYPES_SET) >>= xSet;
2465 const css::uno::Sequence< ::rtl::OUString > lItems = xSet->getElementNames();
2466 const ::rtl::OUString* pItems = lItems.getConstArray();
2467 for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2468 m_lTypes[pItems[i]] = impl_readOldItem(xSet, E_TYPE, pItems[i]);
2471 // May be there is no filter set ...
2472 if (xCfg->hasByName(FILTER_SET))
2474 css::uno::Reference< css::container::XNameAccess > xSet;
2475 xCfg->getByName(FILTER_SET) >>= xSet;
2476 const css::uno::Sequence< ::rtl::OUString > lItems = xSet->getElementNames();
2477 const ::rtl::OUString* pItems = lItems.getConstArray();
2478 for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2479 m_lFilters[pItems[i]] = impl_readOldItem(xSet, E_FILTER, pItems[i]);
2483 /*-----------------------------------------------
2484 12.02.2004 08:30
2485 -----------------------------------------------*/
2486 CacheItem FilterCache::impl_readOldItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
2487 EItemType eType,
2488 const ::rtl::OUString& sItem)
2489 throw(css::uno::Exception)
2491 css::uno::Reference< css::container::XNameAccess > xItem;
2492 xSet->getByName(sItem) >>= xItem;
2493 if (!xItem.is())
2494 throw css::uno::Exception(
2495 ::rtl::OUString::createFromAscii("Cant read old item."),
2496 css::uno::Reference< css::uno::XInterface >());
2498 CacheItem aItem;
2499 aItem[PROPNAME_NAME] <<= sItem;
2501 // Installed flag ...
2502 // Isnt used any longer!
2504 // UIName
2505 impl_readPatchUINames(xItem, aItem);
2507 // Data
2508 ::rtl::OUString sData;
2509 OUStringList lData;
2510 xItem->getByName(::rtl::OUString::createFromAscii("Data")) >>= sData;
2511 lData = impl_tokenizeString(sData, (sal_Unicode)',');
2512 if (
2513 (!sData.getLength()) ||
2514 (lData.size()<1 )
2517 throw css::uno::Exception(
2518 ::rtl::OUString::createFromAscii("Cant read old item property DATA."),
2519 css::uno::Reference< css::uno::XInterface >());
2522 sal_Int32 nProp = 0;
2523 for (OUStringList::const_iterator pProp = lData.begin();
2524 pProp != lData.end() ;
2525 ++pProp )
2527 const ::rtl::OUString& sProp = *pProp;
2528 switch(eType)
2530 case E_TYPE :
2531 impl_interpretDataVal4Type(sProp, nProp, aItem);
2532 break;
2534 case E_FILTER :
2535 impl_interpretDataVal4Filter(sProp, nProp, aItem);
2536 break;
2537 default: break;
2539 ++nProp;
2542 return aItem;
2545 /*-----------------------------------------------
2546 12.02.2004 08:15
2547 -----------------------------------------------*/
2548 OUStringList FilterCache::impl_tokenizeString(const ::rtl::OUString& sData ,
2549 sal_Unicode cSeperator)
2551 OUStringList lData ;
2552 sal_Int32 nToken = 0;
2555 ::rtl::OUString sToken = sData.getToken(0, cSeperator, nToken);
2556 lData.push_back(sToken);
2558 while(nToken >= 0);
2559 return lData;
2562 /*-----------------------------------------------*/
2563 ::rtl::OUString FilterCache::impl_searchFrameLoaderForType(const ::rtl::OUString& sType) const
2565 CacheItemList::const_iterator pIt;
2566 for ( pIt = m_lFrameLoaders.begin();
2567 pIt != m_lFrameLoaders.end() ;
2568 ++pIt )
2570 const ::rtl::OUString& sItem = pIt->first;
2571 ::comphelper::SequenceAsHashMap lProps(pIt->second);
2572 OUStringList lTypes(lProps[PROPNAME_TYPES]);
2574 if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2575 return sItem;
2578 return ::rtl::OUString();
2581 /*-----------------------------------------------*/
2582 ::rtl::OUString FilterCache::impl_searchContentHandlerForType(const ::rtl::OUString& sType) const
2584 CacheItemList::const_iterator pIt;
2585 for ( pIt = m_lContentHandlers.begin();
2586 pIt != m_lContentHandlers.end() ;
2587 ++pIt )
2589 const ::rtl::OUString& sItem = pIt->first;
2590 ::comphelper::SequenceAsHashMap lProps(pIt->second);
2591 OUStringList lTypes(lProps[PROPNAME_TYPES]);
2593 if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2594 return sItem;
2597 return ::rtl::OUString();
2600 /*-----------------------------------------------*/
2601 sal_Bool FilterCache::impl_isModuleInstalled(const ::rtl::OUString& sModule)
2603 css::uno::Reference< css::container::XNameAccess > xCfg;
2605 // SAFE ->
2606 ::osl::ResettableMutexGuard aLock(m_aLock);
2607 if (! m_xModuleCfg.is())
2609 m_xModuleCfg = css::uno::Reference< css::container::XNameAccess >(
2610 ::comphelper::ConfigurationHelper::openConfig(
2611 m_xSMGR,
2612 ::rtl::OUString::createFromAscii("org.openoffice.Setup/Office/Factories"),
2613 ::comphelper::ConfigurationHelper::E_READONLY),
2614 css::uno::UNO_QUERY_THROW);
2617 xCfg = m_xModuleCfg;
2618 aLock.clear();
2619 // <- SAFE
2621 if (xCfg.is())
2622 return xCfg->hasByName(sModule);
2624 return sal_False;
2627 } // namespace config
2628 } // namespace filter