android: Update app-specific/MIME type icons
[LibreOffice.git] / filter / source / config / cache / basecontainer.cxx
blob86b6677ffa1d73f37c2ae59c0736a01498d2b72b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "basecontainer.hxx"
23 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
24 #include <com/sun/star/uno/Type.h>
25 #include <comphelper/enumhelper.hxx>
26 #include <comphelper/sequence.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <osl/diagnose.h>
30 namespace filter::config{
32 BaseContainer::BaseContainer()
33 : m_eType()
35 GetTheFilterCache().load(FilterCache::E_CONTAINS_STANDARD);
39 BaseContainer::~BaseContainer()
44 void BaseContainer::init(const OUString& sImplementationName,
45 const css::uno::Sequence< OUString >& lServiceNames ,
46 FilterCache::EItemType eType )
48 // SAFE ->
49 std::unique_lock aLock(m_aMutex);
51 m_sImplementationName = sImplementationName;
52 m_lServiceNames = lServiceNames ;
53 m_eType = eType ;
54 // <- SAFE
58 void BaseContainer::impl_loadOnDemand(std::unique_lock<std::mutex>& /*rGuard*/)
60 // A generic container needs all items of a set of our cache!
61 // Of course it can block for a while, till the cache is really filled.
62 // Note: don't load all sets supported by the cache here!
64 FilterCache::EFillState eRequiredState = FilterCache::E_CONTAINS_NOTHING;
65 switch(m_eType)
67 case FilterCache::E_TYPE :
68 eRequiredState = FilterCache::E_CONTAINS_TYPES;
69 break;
71 case FilterCache::E_FILTER :
72 eRequiredState = FilterCache::E_CONTAINS_FILTERS;
73 break;
75 case FilterCache::E_FRAMELOADER :
76 eRequiredState = FilterCache::E_CONTAINS_FRAMELOADERS;
77 break;
79 case FilterCache::E_CONTENTHANDLER :
80 eRequiredState = FilterCache::E_CONTAINS_CONTENTHANDLERS;
81 break;
84 GetTheFilterCache().load(eRequiredState);
88 void BaseContainer::impl_initFlushMode(std::unique_lock<std::mutex>& /*rGuard*/)
90 if (!m_pFlushCache)
91 m_pFlushCache = GetTheFilterCache().clone();
92 if (!m_pFlushCache)
93 throw css::uno::RuntimeException( "Can not create write copy of internal used cache on demand.",
94 getXWeak());
98 FilterCache* BaseContainer::impl_getWorkingCache(std::unique_lock<std::mutex>& /*rGuard*/) const
100 if (m_pFlushCache)
101 return m_pFlushCache.get();
102 else
103 return &GetTheFilterCache();
107 OUString SAL_CALL BaseContainer::getImplementationName()
109 return m_sImplementationName;
113 sal_Bool SAL_CALL BaseContainer::supportsService(const OUString& sServiceName)
115 return cppu::supportsService(this, sServiceName);
118 css::uno::Sequence< OUString > SAL_CALL BaseContainer::getSupportedServiceNames()
120 return m_lServiceNames;
124 void SAL_CALL BaseContainer::insertByName(const OUString& sItem ,
125 const css::uno::Any& aValue)
127 if (sItem.isEmpty())
128 throw css::lang::IllegalArgumentException("empty value not allowed as item name.",
129 static_cast< css::container::XNameContainer* >(this),
132 CacheItem aItem;
135 aItem << aValue;
137 catch(const css::uno::Exception& ex)
139 throw css::lang::IllegalArgumentException(ex.Message, static_cast< css::container::XNameContainer* >(this), 2);
142 // SAFE -> ----------------------------------
143 std::unique_lock aLock(m_aMutex);
145 impl_loadOnDemand(aLock);
147 // create write copy of used cache on demand ...
148 impl_initFlushMode(aLock);
150 FilterCache* pCache = impl_getWorkingCache(aLock);
151 if (pCache->hasItem(m_eType, sItem))
152 throw css::container::ElementExistException(OUString(), static_cast< css::container::XNameContainer* >(this));
153 pCache->setItem(m_eType, sItem, aItem);
154 // <- SAFE ----------------------------------
158 void SAL_CALL BaseContainer::removeByName(const OUString& sItem)
160 // SAFE -> ----------------------------------
161 std::unique_lock aLock(m_aMutex);
163 impl_loadOnDemand(aLock);
165 // create write copy of used cache on demand ...
166 impl_initFlushMode(aLock);
168 FilterCache* pCache = impl_getWorkingCache(aLock);
169 pCache->removeItem(m_eType, sItem); // throw exceptions automatically
170 // <- SAFE ----------------------------------
174 void SAL_CALL BaseContainer::replaceByName(const OUString& sItem ,
175 const css::uno::Any& aValue)
177 if (sItem.isEmpty())
178 throw css::lang::IllegalArgumentException("empty value not allowed as item name.",
179 static_cast< css::container::XNameContainer* >(this),
182 CacheItem aItem;
185 aItem << aValue;
187 catch(const css::uno::Exception& ex)
189 throw css::lang::IllegalArgumentException(ex.Message, static_cast< css::container::XNameContainer* >(this), 2);
192 // SAFE -> ----------------------------------
193 std::unique_lock aLock(m_aMutex);
195 impl_loadOnDemand(aLock);
197 // create write copy of used cache on demand ...
198 impl_initFlushMode(aLock);
200 FilterCache* pCache = impl_getWorkingCache(aLock);
201 if (!pCache->hasItem(m_eType, sItem))
202 throw css::container::NoSuchElementException(OUString(), static_cast< css::container::XNameContainer* >(this));
203 pCache->setItem(m_eType, sItem, aItem);
204 // <- SAFE ----------------------------------
208 css::uno::Any SAL_CALL BaseContainer::getByName(const OUString& sItem)
210 if (sItem.isEmpty())
211 throw css::container::NoSuchElementException( "An empty item can't be part of this cache!",
212 static_cast< css::container::XNameAccess* >(this));
214 css::uno::Any aValue;
216 // SAFE ->
217 std::unique_lock aLock(m_aMutex);
219 impl_loadOnDemand(aLock);
223 FilterCache* pCache = impl_getWorkingCache(aLock);
224 aValue = pCache->getItemWithStateProps(m_eType, sItem);
226 catch(const css::container::NoSuchElementException&)
228 throw;
230 catch(const css::uno::Exception&)
232 // TODO invalid cache!? How should it be handled right?
235 // <- SAFE
237 return aValue;
241 css::uno::Sequence< OUString > SAL_CALL BaseContainer::getElementNames()
243 css::uno::Sequence< OUString > lNames;
245 // SAFE ->
246 std::unique_lock aLock(m_aMutex);
248 impl_loadOnDemand(aLock);
252 FilterCache* pCache = impl_getWorkingCache(aLock);
253 std::vector<OUString> lKeys = pCache->getItemNames(m_eType);
254 lNames = comphelper::containerToSequence(lKeys);
256 catch(const css::uno::Exception&)
258 // invalid cache!?
259 lNames.realloc(0);
262 // <- SAFE
264 return lNames;
268 sal_Bool SAL_CALL BaseContainer::hasByName(const OUString& sItem)
270 bool bHasOne = false;
272 // SAFE ->
273 std::unique_lock aLock(m_aMutex);
275 impl_loadOnDemand(aLock);
279 FilterCache* pCache = impl_getWorkingCache(aLock);
280 bHasOne = pCache->hasItem(m_eType, sItem);
282 catch(const css::uno::Exception&)
284 // invalid cache!?
285 bHasOne = false;
288 // <- SAFE
290 return bHasOne;
294 css::uno::Type SAL_CALL BaseContainer::getElementType()
296 // no lock necessary - because the type of our items
297 // is fix! no internal call or member needed ...
298 return cppu::UnoType<css::uno::Sequence< css::beans::PropertyValue >>::get();
302 sal_Bool SAL_CALL BaseContainer::hasElements()
304 bool bHasSome = false;
306 // SAFE ->
307 std::unique_lock aLock(m_aMutex);
309 impl_loadOnDemand(aLock);
313 FilterCache* pCache = impl_getWorkingCache(aLock);
314 bHasSome = pCache->hasItems(m_eType);
316 catch(const css::uno::Exception&)
318 // invalid cache?!
319 bHasSome = false;
322 // <- SAFE
324 return bHasSome;
328 css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::createSubSetEnumerationByQuery(const OUString& /* sQuery */ )
330 OSL_FAIL("not pure virtual ... but not really implemented .-)");
332 return new ::comphelper::OEnumerationByName(this, {});
336 css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
338 std::vector<OUString> lKeys;
340 // SAFE ->
341 std::unique_lock aLock(m_aMutex);
343 impl_loadOnDemand(aLock);
347 // search the key names of all items, where its properties match
348 // the given ones in its minimum
349 FilterCache* pCache = impl_getWorkingCache(aLock);
350 lKeys = pCache->getMatchingItemsByProps(m_eType, o3tl::span<const css::beans::NamedValue>( lProperties.getConstArray(), lProperties.getLength() ));
352 catch(const css::uno::Exception&)
354 // invalid cache, internal failure, wrong conversion ...!?
355 // doesn't matter
356 lKeys.clear();
359 // <- SAFE
361 // create a specialized enumeration helper, which
362 // provides the collected information outside.
363 // It hold a reference to us ... and call our container interface directly.
364 // be aware of some direct callbacks if it will be created :-)
366 /* Note: It's not allowed to return NULL. Because an empty enumeration
367 transport the same information but make no trouble outside.
368 Further its easier to work directly with the return value
369 instead of checking of NULL returns! */
371 return new ::comphelper::OEnumerationByName(this, std::move(lKeys));
375 void SAL_CALL BaseContainer::flush()
377 // SAFE ->
378 std::unique_lock aLock(m_aMutex);
380 if (!m_pFlushCache)
381 throw css::lang::WrappedTargetRuntimeException(
382 "Can not guarantee cache consistency. Special flush container does not exists!",
383 getXWeak(),
384 css::uno::Any());
388 m_pFlushCache->flush();
389 // Take over all changes into the global cache and
390 // forget the clone.
391 /* TODO
392 -think about me
393 If the global cache gets this information via listener,
394 we should remove this method!
396 GetTheFilterCache().takeOver(*m_pFlushCache);
398 catch(const css::uno::Exception& ex)
400 // Don't remove the clone. May be the outside
401 // user wish to repair it now and calls flush()
402 // later again ...
404 throw css::lang::WrappedTargetRuntimeException( "Flush rejected by internal container.",
405 getXWeak(),
406 css::uno::Any(ex));
409 m_pFlushCache.reset();
411 css::lang::EventObject aSource (static_cast< css::util::XFlushable* >(this));
412 m_lListener.notifyEach( aLock, &css::util::XFlushListener::flushed, aSource);
414 // <- SAFE
418 void SAL_CALL BaseContainer::addFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
420 std::unique_lock g(m_aMutex);
421 m_lListener.addInterface(g, xListener);
425 void SAL_CALL BaseContainer::removeFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
427 std::unique_lock g(m_aMutex);
428 m_lListener.removeInterface(g, xListener);
431 } // namespace filter::config
433 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */