24#include <com/sun/star/beans/NamedValue.hpp>
25#include <com/sun/star/beans/PropertyValue.hpp>
26#include <com/sun/star/configuration/theDefaultProvider.hpp>
27#include <com/sun/star/lang/EventObject.hpp>
28#include <com/sun/star/lang/Locale.hpp>
29#include <com/sun/star/lang/XLocalizable.hpp>
30#include <com/sun/star/lang/XMultiServiceFactory.hpp>
31#include <com/sun/star/lang/XServiceInfo.hpp>
32#include <com/sun/star/uno/Any.hxx>
33#include <com/sun/star/uno/Exception.hpp>
34#include <com/sun/star/uno/Reference.hxx>
35#include <com/sun/star/uno/Sequence.hxx>
36#include <com/sun/star/uno/XInterface.hpp>
37#include <com/sun/star/util/XFlushListener.hpp>
38#include <com/sun/star/util/XFlushable.hpp>
39#include <com/sun/star/util/XRefreshListener.hpp>
40#include <com/sun/star/util/XRefreshable.hpp>
45#include <osl/mutex.hxx>
48#include <rtl/ustring.hxx>
63constexpr OUStringLiteral accessServiceName =
64 u"com.sun.star.configuration.ConfigurationAccess";
65constexpr OUStringLiteral updateAccessServiceName =
66 u"com.sun.star.configuration.ConfigurationUpdateAccess";
69 throw css::uno::Exception(
70 (
"com.sun.star.configuration.ConfigurationProvider expects a single,"
71 " non-empty, string nodepath argument"),
77 css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
78 css::util::XRefreshable, css::util::XFlushable,
79 css::lang::XLocalizable >
82class Service :
public ServiceBase
86 const css::uno::Reference< css::uno::XComponentContext >& context):
94 const css::uno::Reference< css::uno::XComponentContext >& context,
100 assert(context.is());
107 virtual ~Service()
override {}
109 virtual void disposing(std::unique_lock<std::mutex>& rGuard)
override;
115 :
"com.sun.star.comp.configuration.ConfigurationProvider";
121 virtual css::uno::Sequence< OUString > SAL_CALL
126 : css::uno::Sequence<OUString> {
"com.sun.star.configuration.ConfigurationProvider" };
129 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
createInstance(
130 OUString
const & aServiceSpecifier)
override;
132 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
133 createInstanceWithArguments(
134 OUString
const & ServiceSpecifier,
135 css::uno::Sequence< css::uno::Any >
const & Arguments)
override;
137 virtual css::uno::Sequence< OUString > SAL_CALL
138 getAvailableServiceNames()
override;
140 virtual void SAL_CALL refresh()
override;
142 virtual void SAL_CALL addRefreshListener(
143 css::uno::Reference< css::util::XRefreshListener >
const & l)
override;
145 virtual void SAL_CALL removeRefreshListener(
146 css::uno::Reference< css::util::XRefreshListener >
const & l)
override;
148 virtual void SAL_CALL flush()
override;
150 virtual void SAL_CALL addFlushListener(
151 css::uno::Reference< css::util::XFlushListener >
const & l)
override;
153 virtual void SAL_CALL removeFlushListener(
154 css::uno::Reference< css::util::XFlushListener >
const & l)
override;
156 virtual void SAL_CALL
setLocale(css::lang::Locale
const & eLocale)
override;
158 virtual css::lang::Locale SAL_CALL
getLocale()
override;
160 void flushModifications()
const;
162 css::uno::Reference< css::uno::XComponentContext >
context_;
170css::uno::Reference< css::uno::XInterface > Service::createInstance(
171 OUString
const & aServiceSpecifier)
173 return createInstanceWithArguments(
174 aServiceSpecifier, css::uno::Sequence< css::uno::Any >());
177css::uno::Reference< css::uno::XInterface >
178Service::createInstanceWithArguments(
179 OUString
const & ServiceSpecifier,
180 css::uno::Sequence< css::uno::Any >
const & Arguments)
184 for (sal_Int32 i = 0;
i < Arguments.getLength(); ++
i) {
185 css::beans::NamedValue v1;
186 css::beans::PropertyValue v2;
189 if (Arguments[i] >>= v1) {
192 }
else if (Arguments[i] >>= v2) {
195 }
else if (Arguments.getLength() == 1 && (Arguments[i] >>= nodepath)) {
198 if (nodepath.isEmpty()) {
203 throw css::uno::Exception(
204 (
"com.sun.star.configuration.ConfigurationProvider expects"
205 " NamedValue or PropertyValue arguments"),
210 if (
name.equalsIgnoreAsciiCase(
"nodepath")) {
211 if (!nodepath.isEmpty() || !(value >>= nodepath) ||
216 }
else if (
name.equalsIgnoreAsciiCase(
"locale")) {
217 if (!locale.isEmpty() || !(value >>= locale) ||
220 throw css::uno::Exception(
221 (
"com.sun.star.configuration.ConfigurationProvider expects"
222 " at most one, non-empty, string Locale argument"),
227 if (nodepath.isEmpty()) {
232 if (nodepath[0] !=
'/') {
233 nodepath =
"/" + nodepath;
235 if (locale.isEmpty()) {
238 if (locale.isEmpty()) {
243 if (ServiceSpecifier == accessServiceName) {
245 }
else if (ServiceSpecifier == updateAccessServiceName) {
248 throw css::uno::Exception(
249 (
"com.sun.star.configuration.ConfigurationProvider does not support"
250 " service " + ServiceSpecifier),
253 osl::MutexGuard guard(*
lock_);
256 new RootAccess(components, nodepath, locale, update));
257 if (root->isValue()) {
258 throw css::uno::Exception(
259 (
"com.sun.star.configuration.ConfigurationProvider: there is a leaf"
260 " value at nodepath " + nodepath),
263 components.addRootAccess(root);
264 return root->getXWeak();
267css::uno::Sequence< OUString > Service::getAvailableServiceNames()
269 return { accessServiceName, updateAccessServiceName };
272void Service::refresh() {
274 std::unique_lock g(m_aMutex);
276 css::lang::EventObject ev(getXWeak());
281void Service::addRefreshListener(
282 css::uno::Reference< css::util::XRefreshListener >
const & l)
284 std::unique_lock g(m_aMutex);
288void Service::removeRefreshListener(
289 css::uno::Reference< css::util::XRefreshListener >
const & l)
291 std::unique_lock g(m_aMutex);
295void Service::flush() {
296 flushModifications();
297 std::unique_lock g(m_aMutex);
299 css::lang::EventObject ev(getXWeak());
304void Service::addFlushListener(
305 css::uno::Reference< css::util::XFlushListener >
const & l)
307 std::unique_lock g(m_aMutex);
311void Service::removeFlushListener(
312 css::uno::Reference< css::util::XFlushListener >
const & l)
314 std::unique_lock g(m_aMutex);
318void Service::setLocale(css::lang::Locale
const & eLocale)
320 osl::MutexGuard guard(*
lock_);
324css::lang::Locale Service::getLocale() {
325 osl::MutexGuard guard(*
lock_);
326 css::lang::Locale loc;
333void Service::disposing(std::unique_lock<std::mutex>& rGuard) {
335 flushModifications();
339void Service::flushModifications()
const {
342 osl::MutexGuard guard(*
lock_);
345 components->flushModifications();
348extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
349com_sun_star_comp_configuration_ConfigurationProvider_get_implementation(
350 css::uno::XComponentContext* Context, css::uno::Sequence<css::uno::Any>
const& Arguments)
352 if (!Arguments.hasElements()) {
353 auto p = css::configuration::theDefaultProvider::get(Context);
358 for (sal_Int32 i = 0;
i < Arguments.getLength(); ++
i) {
359 css::beans::NamedValue v1;
360 css::beans::PropertyValue v2;
363 if (Arguments[i] >>= v1) {
366 }
else if (Arguments[i] >>= v2) {
370 throw css::uno::Exception(
371 (
"com.sun.star.configuration.ConfigurationProvider factory"
372 " expects NamedValue or PropertyValue arguments"),
377 if (
name.equalsIgnoreAsciiCase(
"locale")) {
378 if (!locale.isEmpty() || !(value >>= locale) ||
381 throw css::uno::Exception(
382 (
"com.sun.star.configuration.ConfigurationProvider"
383 " factory expects at most one, non-empty, string"
387 }
else if (!
name.equalsIgnoreAsciiCase(
"enableasync")) {
388 throw css::uno::Exception(
389 (
"com.sun.star.configuration.ConfigurationProvider factory:"
390 " unknown argument " +
name),
394 return cppu::acquire(
new Service(Context, locale));
401 css::uno::Reference< css::uno::XComponentContext >
const & context)
403 return getXWeak(
new Service(context));
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
static OUString convertToBcp47(LanguageType nLangID)
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(std::unique_lock< std::mutex > &rGuard, void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event) const
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
static Components & getSingleton(css::uno::Reference< css::uno::XComponentContext > const &context)
css::uno::Reference< css::uno::XComponentContext > context_
comphelper::OInterfaceContainerHelper4< css::util::XRefreshListener > maRefreshListeners
comphelper::OInterfaceContainerHelper4< css::util::XFlushListener > maFlushListeners
std::shared_ptr< osl::Mutex > lock_
const LanguageTag & getLocale()
void setLocale(const LanguageTag &languageTag)
css::uno::Reference< css::uno::XInterface > createDefault(css::uno::Reference< css::uno::XComponentContext > const &context)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
std::shared_ptr< osl::Mutex > const & lock()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::vector< uno::Reference< sheet::XSpreadsheetDocument > > Components