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