LibreOffice Module configmgr (master) 1
configurationregistry.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <cassert>
23
24#include <com/sun/star/beans/NamedValue.hpp>
25#include <com/sun/star/container/NoSuchElementException.hpp>
26#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
27#include <com/sun/star/container/XNamed.hpp>
28#include <com/sun/star/lang/XMultiServiceFactory.hpp>
29#include <com/sun/star/lang/XServiceInfo.hpp>
30#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
31#include <com/sun/star/registry/InvalidRegistryException.hpp>
32#include <com/sun/star/registry/InvalidValueException.hpp>
33#include <com/sun/star/registry/RegistryKeyType.hpp>
34#include <com/sun/star/registry/RegistryValueType.hpp>
35#include <com/sun/star/registry/XRegistryKey.hpp>
36#include <com/sun/star/registry/XSimpleRegistry.hpp>
37#include <com/sun/star/uno/Any.hxx>
38#include <com/sun/star/uno/DeploymentException.hpp>
39#include <com/sun/star/uno/Exception.hpp>
40#include <com/sun/star/uno/Reference.hxx>
41#include <com/sun/star/uno/RuntimeException.hpp>
42#include <com/sun/star/uno/Sequence.hxx>
43#include <com/sun/star/uno/Type.hxx>
44#include <com/sun/star/uno/TypeClass.hpp>
45#include <com/sun/star/uno/XComponentContext.hpp>
46#include <com/sun/star/uno/XInterface.hpp>
47#include <com/sun/star/util/XFlushable.hpp>
48#include <cppu/unotype.hxx>
52#include <cppuhelper/weak.hxx>
53#include <mutex>
54#include <rtl/ustring.hxx>
55#include <utility>
56#include <sal/types.h>
57
58namespace com::sun::star::util {
59 class XFlushListener;
60}
61
63
64namespace {
65
66class Service:
67 public cppu::WeakImplHelper<
68 css::lang::XServiceInfo, css::registry::XSimpleRegistry,
69 css::util::XFlushable >
70{
71public:
72 explicit Service(css::uno::Reference< css::uno::XComponentContext > const & context);
73
74private:
75 Service(const Service&) = delete;
76 Service& operator=(const Service&) = delete;
77
78 virtual ~Service() override {}
79
80 virtual OUString SAL_CALL getImplementationName() override
81 { return "com.sun.star.comp.configuration.ConfigurationRegistry"; }
82
83 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
84 { return cppu::supportsService(this, ServiceName); }
85
86 virtual css::uno::Sequence< OUString > SAL_CALL
88 { return { "com.sun.star.configuration.ConfigurationRegistry" }; }
89
90 virtual OUString SAL_CALL getURL() override;
91
92 virtual void SAL_CALL open(
93 OUString const & rURL, sal_Bool bReadOnly, sal_Bool) override;
94
95 virtual sal_Bool SAL_CALL isValid() override;
96
97 virtual void SAL_CALL close() override;
98
99 virtual void SAL_CALL destroy() override;
100
101 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
102 getRootKey() override;
103
104 virtual sal_Bool SAL_CALL isReadOnly() override;
105
106 virtual void SAL_CALL mergeKey(OUString const &, OUString const &) override;
107
108 virtual void SAL_CALL flush() override;
109
110 virtual void SAL_CALL addFlushListener(
111 css::uno::Reference< css::util::XFlushListener > const &) override;
112
113 virtual void SAL_CALL removeFlushListener(
114 css::uno::Reference< css::util::XFlushListener > const &) override;
115
116 void checkValid();
117
118 void checkValid_RuntimeException();
119
120 void doClose();
121
122 css::uno::Reference< css::lang::XMultiServiceFactory > provider_;
123 std::mutex mutex_;
124 css::uno::Reference< css::uno::XInterface > access_;
125 OUString url_;
127
128 friend class RegistryKey;
129};
130
131class RegistryKey:
132 public cppu::WeakImplHelper< css::registry::XRegistryKey >
133{
134public:
135 RegistryKey(Service & service, css::uno::Any value):
136 service_(service), value_(std::move(value)) {}
137
138private:
139 RegistryKey(const RegistryKey&) = delete;
140 RegistryKey& operator=(const RegistryKey&) = delete;
141
142 virtual ~RegistryKey() override {}
143
144 virtual OUString SAL_CALL getKeyName() override;
145
146 virtual sal_Bool SAL_CALL isReadOnly() override;
147
148 virtual sal_Bool SAL_CALL isValid() override;
149
150 virtual css::registry::RegistryKeyType SAL_CALL getKeyType(
151 OUString const &) override;
152
153 virtual css::registry::RegistryValueType SAL_CALL getValueType() override;
154
155 virtual sal_Int32 SAL_CALL getLongValue() override;
156
157 virtual void SAL_CALL setLongValue(sal_Int32) override;
158
159 virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() override;
160
161 virtual void SAL_CALL setLongListValue(
162 css::uno::Sequence< sal_Int32 > const &) override;
163
164 virtual OUString SAL_CALL getAsciiValue() override;
165
166 virtual void SAL_CALL setAsciiValue(OUString const &) override;
167
168 virtual css::uno::Sequence< OUString > SAL_CALL getAsciiListValue() override;
169
170 virtual void SAL_CALL setAsciiListValue(
171 css::uno::Sequence< OUString > const &) override;
172
173 virtual OUString SAL_CALL getStringValue() override;
174
175 virtual void SAL_CALL setStringValue(OUString const &) override;
176
177 virtual css::uno::Sequence< OUString > SAL_CALL getStringListValue() override;
178
179 virtual void SAL_CALL setStringListValue(
180 css::uno::Sequence< OUString > const &) override;
181
182 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() override;
183
184 virtual void SAL_CALL setBinaryValue(css::uno::Sequence< sal_Int8 > const &) override;
185
186 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey(
187 OUString const & aKeyName) override;
188
189 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
190 createKey(OUString const &) override;
191
192 virtual void SAL_CALL closeKey() override;
193
194 virtual void SAL_CALL deleteKey(OUString const &) override;
195
196 virtual
197 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
198 SAL_CALL openKeys() override;
199
200 virtual css::uno::Sequence< OUString > SAL_CALL getKeyNames() override;
201
202 virtual sal_Bool SAL_CALL createLink(
203 OUString const &, OUString const &) override;
204
205 virtual void SAL_CALL deleteLink(OUString const &) override;
206
207 virtual OUString SAL_CALL getLinkTarget(OUString const &) override;
208
209 virtual OUString SAL_CALL getResolvedName(
210 OUString const & aKeyName) override;
211
213 css::uno::Any value_;
214};
215
216Service::Service(
217 css::uno::Reference< css::uno::XComponentContext > const & context)
218 : readOnly_(false)
219{
220 assert(context.is());
221 try {
222 provider_.set(
223 context->getServiceManager()->createInstanceWithContext(
224 "com.sun.star.configuration.DefaultProvider", context),
225 css::uno::UNO_QUERY_THROW);
226 } catch (css::uno::RuntimeException &) {
227 throw;
228 } catch (css::uno::Exception & e) {
229 throw css::uno::DeploymentException(
230 ("component context fails to supply service"
231 " com.sun.star.configuration.DefaultProvider of type"
232 " com.sun.star.lang.XMultiServiceFactory: " + e.Message),
233 context);
234 }
235}
236
237OUString Service::getURL() {
238 std::unique_lock g(mutex_);
239 checkValid_RuntimeException();
240 return url_;
241}
242
243void Service::open(OUString const & rURL, sal_Bool bReadOnly, sal_Bool)
244{
245 //TODO: bCreate
246 std::unique_lock g(mutex_);
247 if (access_.is()) {
248 doClose();
249 }
250 css::uno::Sequence< css::uno::Any > args{ css::uno::Any(
251 css::beans::NamedValue("nodepath", css::uno::Any(rURL))) };
252 try {
253 access_ = provider_->createInstanceWithArguments(
254 (bReadOnly
255 ? OUString("com.sun.star.configuration.ConfigurationAccess")
256 : OUString(
257 "com.sun.star.configuration.ConfigurationUpdateAccess")),
258 args);
259 } catch (css::uno::RuntimeException &) {
260 throw;
261 } catch (css::uno::Exception & e) {
262 css::uno::Any anyEx = cppu::getCaughtException();
263 throw css::lang::WrappedTargetRuntimeException(
264 "com.sun.star.configuration.ConfigurationRegistry: open failed: " +
265 e.Message,
266 getXWeak(), anyEx );
267 }
268 url_ = rURL;
270}
271
272sal_Bool Service::isValid() {
273 std::unique_lock g(mutex_);
274 return access_.is();
275}
276
277void Service::close()
278{
279 std::unique_lock g(mutex_);
280 checkValid();
281 doClose();
282}
283
284void Service::destroy()
285{
286 throw css::uno::RuntimeException(
287 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
288 getXWeak());
289}
290
291css::uno::Reference< css::registry::XRegistryKey > Service::getRootKey()
292{
293 std::unique_lock g(mutex_);
294 checkValid();
295 return new RegistryKey(*this, css::uno::Any(access_));
296}
297
298sal_Bool Service::isReadOnly() {
299 std::unique_lock g(mutex_);
300 checkValid_RuntimeException();
301 return readOnly_;
302}
303
304void Service::mergeKey(OUString const &, OUString const &)
305{
306 throw css::uno::RuntimeException(
307 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
308 getXWeak());
309}
310
311void Service::flush()
312{
313 throw css::uno::RuntimeException(
314 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
315 getXWeak());
316}
317
318void Service::addFlushListener(
319 css::uno::Reference< css::util::XFlushListener > const &)
320{
321 throw css::uno::RuntimeException(
322 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
323 getXWeak());
324}
325
326void Service::removeFlushListener(
327 css::uno::Reference< css::util::XFlushListener > const &)
328{
329 throw css::uno::RuntimeException(
330 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
331 getXWeak());
332}
333
334void Service::checkValid() {
335 if (!access_.is()) {
336 throw css::registry::InvalidRegistryException(
337 "com.sun.star.configuration.ConfigurationRegistry: not valid",
338 getXWeak());
339 }
340}
341
342void Service::checkValid_RuntimeException() {
343 if (!access_.is()) {
344 throw css::uno::RuntimeException(
345 "com.sun.star.configuration.ConfigurationRegistry: not valid",
346 getXWeak());
347 }
348}
349
350void Service::doClose() {
351 access_.clear();
352}
353
354OUString RegistryKey::getKeyName() {
355 std::unique_lock g(service_.mutex_);
356 service_.checkValid_RuntimeException();
357 css::uno::Reference< css::container::XNamed > named;
358 if (value_ >>= named) {
359 return named->getName();
360 }
361 throw css::uno::RuntimeException(
362 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
363 getXWeak());
364}
365
367{
368 std::unique_lock g(service_.mutex_);
369 service_.checkValid_RuntimeException();
370 return service_.readOnly_; //TODO: read-only sub-nodes in update access?
371}
372
374 return service_.isValid();
375}
376
377css::registry::RegistryKeyType RegistryKey::getKeyType(OUString const &)
378{
379 std::unique_lock g(service_.mutex_);
380 service_.checkValid();
381 return css::registry::RegistryKeyType_KEY;
382}
383
384css::registry::RegistryValueType RegistryKey::getValueType()
385{
386 std::unique_lock g(service_.mutex_);
387 service_.checkValid();
388 css::uno::Type t(value_.getValueType());
389 switch (t.getTypeClass()) {
390 case css::uno::TypeClass_LONG:
391 return css::registry::RegistryValueType_LONG;
392 case css::uno::TypeClass_STRING:
393 return css::registry::RegistryValueType_STRING;
394 case css::uno::TypeClass_SEQUENCE:
395 if (t == cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get()) {
396 return css::registry::RegistryValueType_BINARY;
397 } else if (t == cppu::UnoType< css::uno::Sequence< sal_Int32 > >::get())
398 {
399 return css::registry::RegistryValueType_LONGLIST;
400 } else if (t ==
401 cppu::UnoType< css::uno::Sequence< OUString > >::get())
402 {
403 return css::registry::RegistryValueType_STRINGLIST;
404 }
405 [[fallthrough]];
406 default:
407 return css::registry::RegistryValueType_NOT_DEFINED;
408 }
409}
410
411sal_Int32 RegistryKey::getLongValue()
412{
413 std::unique_lock g(service_.mutex_);
414 service_.checkValid();
415 sal_Int32 v = 0;
416 if (value_ >>= v) {
417 return v;
418 }
419 throw css::registry::InvalidValueException(
420 "com.sun.star.configuration.ConfigurationRegistry",
421 getXWeak());
422}
423
424void RegistryKey::setLongValue(sal_Int32)
425{
426 throw css::uno::RuntimeException(
427 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
428 getXWeak());
429}
430
431css::uno::Sequence< sal_Int32 > RegistryKey::getLongListValue()
432{
433 std::unique_lock g(service_.mutex_);
434 service_.checkValid();
435 css::uno::Sequence< sal_Int32 > v;
436 if (value_ >>= v) {
437 return v;
438 }
439 throw css::registry::InvalidValueException(
440 "com.sun.star.configuration.ConfigurationRegistry",
441 getXWeak());
442}
443
444void RegistryKey::setLongListValue(css::uno::Sequence< sal_Int32 > const &)
445{
446 throw css::uno::RuntimeException(
447 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
448 getXWeak());
449}
450
451OUString RegistryKey::getAsciiValue()
452{
453 std::unique_lock g(service_.mutex_);
454 service_.checkValid();
455 OUString v;
456 if (value_ >>= v) {
457 return v;
458 }
459 throw css::registry::InvalidValueException(
460 "com.sun.star.configuration.ConfigurationRegistry",
461 getXWeak());
462}
463
464void RegistryKey::setAsciiValue(OUString const &)
465{
466 throw css::uno::RuntimeException(
467 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
468 getXWeak());
469}
470
471css::uno::Sequence< OUString > RegistryKey::getAsciiListValue()
472{
473 std::unique_lock g(service_.mutex_);
474 service_.checkValid();
475 css::uno::Sequence< OUString > v;
476 if (value_ >>= v) {
477 return v;
478 }
479 throw css::registry::InvalidValueException(
480 "com.sun.star.configuration.ConfigurationRegistry",
481 getXWeak());
482}
483
484void RegistryKey::setAsciiListValue(css::uno::Sequence< OUString > const &)
485{
486 throw css::uno::RuntimeException(
487 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
488 getXWeak());
489}
490
491OUString RegistryKey::getStringValue()
492{
493 std::unique_lock g(service_.mutex_);
494 service_.checkValid();
495 OUString v;
496 if (value_ >>= v) {
497 return v;
498 }
499 throw css::registry::InvalidValueException(
500 "com.sun.star.configuration.ConfigurationRegistry",
501 getXWeak());
502}
503
504void RegistryKey::setStringValue(OUString const &)
505{
506 throw css::uno::RuntimeException(
507 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
508 getXWeak());
509}
510
511css::uno::Sequence< OUString > RegistryKey::getStringListValue()
512{
513 std::unique_lock g(service_.mutex_);
514 service_.checkValid();
515 css::uno::Sequence< OUString > v;
516 if (value_ >>= v) {
517 return v;
518 }
519 throw css::registry::InvalidValueException(
520 "com.sun.star.configuration.ConfigurationRegistry",
521 getXWeak());
522}
523
525 css::uno::Sequence< OUString > const &)
526{
527 throw css::uno::RuntimeException(
528 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
529 getXWeak());
530}
531
532css::uno::Sequence< sal_Int8 > RegistryKey::getBinaryValue()
533{
534 std::unique_lock g(service_.mutex_);
535 service_.checkValid();
536 css::uno::Sequence< sal_Int8 > v;
537 if (value_ >>= v) {
538 return v;
539 }
540 throw css::registry::InvalidValueException(
541 "com.sun.star.configuration.ConfigurationRegistry",
542 getXWeak());
543}
544
545void RegistryKey::setBinaryValue(css::uno::Sequence< sal_Int8 > const &)
546{
547 throw css::uno::RuntimeException(
548 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
549 getXWeak());
550}
551
552css::uno::Reference< css::registry::XRegistryKey > RegistryKey::openKey(
553 OUString const & aKeyName)
554{
555 std::unique_lock g(service_.mutex_);
556 service_.checkValid_RuntimeException();
557 css::uno::Reference< css::container::XHierarchicalNameAccess > access;
558 if (value_ >>= access) {
559 try {
560 return new RegistryKey(
561 service_, access->getByHierarchicalName(aKeyName));
562 } catch (css::container::NoSuchElementException &) {}
563 }
564 return css::uno::Reference< css::registry::XRegistryKey >();
565}
566
567css::uno::Reference< css::registry::XRegistryKey > RegistryKey::createKey(
568 OUString const &)
569{
570 throw css::uno::RuntimeException(
571 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
572 getXWeak());
573}
574
576{
577 std::unique_lock g(service_.mutex_);
578 service_.checkValid_RuntimeException();
579}
580
581void RegistryKey::deleteKey(OUString const &)
582{
583 throw css::uno::RuntimeException(
584 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
585 getXWeak());
586}
587
588css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
589RegistryKey::openKeys()
590{
591 throw css::uno::RuntimeException(
592 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
593 getXWeak());
594}
595
596css::uno::Sequence< OUString > RegistryKey::getKeyNames()
597{
598 throw css::uno::RuntimeException(
599 "com.sun.star.configuration.ConfigurationRegistry: not implemented",
600 getXWeak());
601}
602
603sal_Bool RegistryKey::createLink(OUString const &, OUString const &)
604{
605 std::unique_lock g(service_.mutex_);
606 service_.checkValid_RuntimeException();
607 return false;
608}
609
610void RegistryKey::deleteLink(OUString const &)
611{
612 std::unique_lock g(service_.mutex_);
613 service_.checkValid_RuntimeException();
614}
615
616OUString RegistryKey::getLinkTarget(OUString const &)
617{
618 std::unique_lock g(service_.mutex_);
619 service_.checkValid_RuntimeException();
620 return OUString();
621}
622
623OUString RegistryKey::getResolvedName(OUString const & aKeyName)
624{
625 std::unique_lock g(service_.mutex_);
626 service_.checkValid_RuntimeException();
627 return aKeyName;
628}
629
630}
631
632extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
634 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
635{
636 return cppu::acquire(new Service(context));
637}
638
639}
640
641/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
RegError getKeyNames(const OUString &keyName, RegistryKeyNames &rSubKeyNames)
RegError openKey(const OUString &keyName, RegistryKey &rOpenKey)
RegError deleteKey(const OUString &keyName)
RegError closeKey()
RegError getLongListValue(const OUString &keyName, RegistryValueList< sal_Int32 > &rValueList)
bool isValid() const
RegError setStringListValue(const OUString &keyName, char **pValueList, sal_uInt32 len)
bool isReadOnly() const
RegError setLongListValue(const OUString &keyName, sal_Int32 const *pValueList, sal_uInt32 len)
RegError createKey(const OUString &keyName, RegistryKey &rNewKey)
RegError getStringListValue(const OUString &keyName, RegistryValueList< char * > &rValueList)
Any value
css::uno::Any value_
bool readOnly_
std::mutex mutex_
OUString url_
Service & service_
css::uno::Reference< css::lang::XMultiServiceFactory > provider_
css::uno::Reference< css::uno::XInterface > access_
bool close
float v
bool bReadOnly
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_configuration_ConfigurationRegistry_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
css::uno::Sequence< OUString > getSupportedServiceNames()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
args
RegError REGISTRY_CALLTYPE setLongListValue(RegKeyHandle hKey, rtl_uString *keyName, sal_Int32 const *pValueList, sal_uInt32 len)
RegError REGISTRY_CALLTYPE createKey(RegKeyHandle hKey, rtl_uString *keyName, RegKeyHandle *phNewKey)
RegError REGISTRY_CALLTYPE setStringListValue(RegKeyHandle hKey, rtl_uString *keyName, char **pValueList, sal_uInt32 len)
RegError REGISTRY_CALLTYPE getStringListValue(RegKeyHandle hKey, rtl_uString *keyName, char ***pValueList, sal_uInt32 *pLen)
RegError REGISTRY_CALLTYPE getKeyNames(RegKeyHandle hKey, rtl_uString *keyName, rtl_uString ***pSubKeyNames, sal_uInt32 *pnSubKeys)
RegError REGISTRY_CALLTYPE getLongListValue(RegKeyHandle hKey, rtl_uString *keyName, sal_Int32 **pValueList, sal_uInt32 *pLen)
RegError REGISTRY_CALLTYPE getKeyName(RegKeyHandle hKey, rtl_uString **pKeyName)
RegError REGISTRY_CALLTYPE deleteKey(RegKeyHandle hKey, rtl_uString *keyName)
RegError REGISTRY_CALLTYPE openKey(RegKeyHandle hKey, rtl_uString *keyName, RegKeyHandle *phOpenKey)
RegError REGISTRY_CALLTYPE closeKey(RegKeyHandle hKey)
unsigned char sal_Bool