LibreOffice Module comphelper (master)  1
configuration.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 
10 #include <sal/config.h>
11 
12 #include <cassert>
13 #include <memory>
14 
15 #include <com/sun/star/beans/PropertyAttribute.hpp>
16 #include <com/sun/star/configuration/ReadOnlyAccess.hpp>
17 #include <com/sun/star/configuration/ReadWriteAccess.hpp>
18 #include <com/sun/star/configuration/XReadWriteAccess.hpp>
19 #include <com/sun/star/configuration/theDefaultProvider.hpp>
20 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
21 #include <com/sun/star/container/XHierarchicalNameReplace.hpp>
22 #include <com/sun/star/container/XNameAccess.hpp>
23 #include <com/sun/star/container/XNameContainer.hpp>
24 #include <com/sun/star/lang/XLocalizable.hpp>
25 #include <com/sun/star/uno/Any.hxx>
26 #include <com/sun/star/uno/Reference.hxx>
30 #include <rtl/instance.hxx>
31 #include <rtl/ustrbuf.hxx>
32 #include <rtl/ustring.hxx>
33 #include <sal/log.hxx>
35 
36 namespace com::sun::star::uno { class XComponentContext; }
37 
38 namespace {
39 
40 struct TheConfigurationWrapper:
41  public rtl::StaticWithArg<
42  comphelper::detail::ConfigurationWrapper,
43  css::uno::Reference< css::uno::XComponentContext >,
44  TheConfigurationWrapper >
45 {};
46 
47 OUString getDefaultLocale(
48  css::uno::Reference< css::uno::XComponentContext > const & context)
49 {
50  return LanguageTag(
51  css::uno::Reference< css::lang::XLocalizable >(
52  css::configuration::theDefaultProvider::get(context),
53  css::uno::UNO_QUERY_THROW)->
54  getLocale()).getBcp47(false);
55 }
56 
57 OUString extendLocalizedPath(OUString const & path, OUString const & locale) {
59  locale.match("*"), "comphelper",
60  "Locale \"" << locale << "\" starts with \"*\"");
61  assert(locale.indexOf('&') == -1);
62  assert(locale.indexOf('"') == -1);
63  assert(locale.indexOf('\'') == -1);
64  return path + "/['*" + locale + "']";
65 }
66 
67 }
68 
69 std::shared_ptr< comphelper::ConfigurationChanges >
71  css::uno::Reference< css::uno::XComponentContext > const & context)
72 {
73  return TheConfigurationWrapper::get(context).createChanges();
74 }
75 
77 
79  access_->commitChanges();
80 }
81 
83  css::uno::Reference< css::uno::XComponentContext > const & context):
84  access_(
85  css::configuration::ReadWriteAccess::create(
86  context, getDefaultLocale(context)))
87 {}
88 
90  OUString const & path, css::uno::Any const & value) const
91 {
92  access_->replaceByHierarchicalName(path, value);
93 }
94 
95 css::uno::Reference< css::container::XHierarchicalNameReplace >
96 comphelper::ConfigurationChanges::getGroup(OUString const & path) const
97 {
98  return css::uno::Reference< css::container::XHierarchicalNameReplace >(
99  access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
100 }
101 
102 css::uno::Reference< css::container::XNameContainer >
103 comphelper::ConfigurationChanges::getSet(OUString const & path) const
104 {
105  return css::uno::Reference< css::container::XNameContainer >(
106  access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
107 }
108 
111  css::uno::Reference< css::uno::XComponentContext > const & context)
112 {
113  return TheConfigurationWrapper::get(context);
114 }
115 
117  css::uno::Reference< css::uno::XComponentContext > const & context):
118  context_(context),
119  access_(css::configuration::ReadWriteAccess::create(context, "*"))
120 {}
121 
123 
125  const
126 {
127  return
128  (access_->getPropertyByHierarchicalName(path).Attributes
129  & css::beans::PropertyAttribute::READONLY)
130  != 0;
131 }
132 
134  OUString const & path) const
135 {
136  return access_->getByHierarchicalName(path);
137 }
138 
140  std::shared_ptr< ConfigurationChanges > const & batch,
141  OUString const & path, css::uno::Any const & value)
142 {
143  assert(batch.get() != nullptr);
144  batch->setPropertyValue(path, value);
145 }
146 
147 css::uno::Any
149  OUString const & path) const
150 {
151  return access_->getByHierarchicalName(
152  extendLocalizedPath(path, getDefaultLocale(context_)));
153 }
154 
156  std::shared_ptr< ConfigurationChanges > const & batch,
157  OUString const & path, css::uno::Any const & value)
158 {
159  assert(batch.get() != nullptr);
160  batch->setPropertyValue(path, value);
161 }
162 
163 css::uno::Reference< css::container::XHierarchicalNameAccess >
165  OUString const & path) const
166 {
167  return css::uno::Reference< css::container::XHierarchicalNameAccess >(
168  (css::configuration::ReadOnlyAccess::create(
169  context_, getDefaultLocale(context_))->
170  getByHierarchicalName(path)),
171  css::uno::UNO_QUERY_THROW);
172 }
173 
174 css::uno::Reference< css::container::XHierarchicalNameReplace >
176  std::shared_ptr< ConfigurationChanges > const & batch,
177  OUString const & path)
178 {
179  assert(batch.get() != nullptr);
180  return batch->getGroup(path);
181 }
182 
183 css::uno::Reference< css::container::XNameAccess >
185  OUString const & path) const
186 {
187  return css::uno::Reference< css::container::XNameAccess >(
188  (css::configuration::ReadOnlyAccess::create(
189  context_, getDefaultLocale(context_))->
190  getByHierarchicalName(path)),
191  css::uno::UNO_QUERY_THROW);
192 }
193 
194 css::uno::Reference< css::container::XNameContainer >
196  std::shared_ptr< ConfigurationChanges > const & batch,
197  OUString const & path)
198 {
199  assert(batch.get() != nullptr);
200  return batch->getSet(path);
201 }
202 
203 std::shared_ptr< comphelper::ConfigurationChanges >
205  return std::shared_ptr< ConfigurationChanges >(
207 }
208 
210 {
211  maListeners.push_back( pListener );
212  mxConfig->addPropertyChangeListener( pListener->maName, this );
213  pListener->setProperty( mxConfig->getPropertyValue( pListener->maName ) );
214 }
215 
217 {
218  auto it = std::find( maListeners.begin(), maListeners.end(), pListener );
219  if ( it != maListeners.end() )
220  {
221  maListeners.erase( it );
222  mxConfig->removePropertyChangeListener( pListener->maName, this );
223  }
224 }
225 
227 {
228  for (auto const& listener : maListeners)
229  {
230  mxConfig->removePropertyChangeListener( listener->maName, this );
231  listener->dispose();
232  }
233  maListeners.clear();
234 }
235 
236 void SAL_CALL comphelper::ConfigurationListener::disposing(css::lang::EventObject const &)
237 {
238  dispose();
239 }
240 
242  css::beans::PropertyChangeEvent const &rEvt )
243 {
244  // Code is commonly used inside the SolarMutexGuard
245  // so to avoid concurrent writes to the property,
246  // and allow fast, lock-less access, guard here.
249 
250  assert( rEvt.Source == mxConfig );
251  for (auto const& listener : maListeners)
252  {
253  if ( listener->maName == rEvt.PropertyName )
254  {
255  // ignore rEvt.NewValue - in theory it could be stale => not set.
256  css::uno::Any aValue = mxConfig->getPropertyValue( listener->maName );
257  listener->setProperty( aValue );
258  }
259  }
260 }
261 
262 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void setPropertyValue(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path, css::uno::Any const &value)
SAL_DLLPRIVATE css::uno::Reference< css::container::XHierarchicalNameReplace > getGroup(OUString const &path) const
static css::uno::Reference< css::container::XHierarchicalNameReplace > getGroupReadWrite(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path)
css::uno::Any getLocalizedPropertyValue(OUString const &path) const
const OUString & getBcp47(bool bResolveSystem=true) const
void dispose()
Release various circular references.
css::uno::Any getPropertyValue(OUString const &path) const
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
Reference< deployment::XPackageRegistry > create(Reference< deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, Reference< XComponentContext > const &xComponentContext)
css::uno::Reference< css::container::XNameAccess > getSetReadOnly(OUString const &path) const
void addListener(ConfigurationListenerPropertyBase *pListener)
Listen for the specific property denoted by the listener.
SAL_DLLPRIVATE ConfigurationWrapper(css::uno::Reference< css::uno::XComponentContext > const &context)
virtual void SAL_CALL disposing(css::lang::EventObject const &) override
static void setLocalizedPropertyValue(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path, css::uno::Any const &value)
void removeListener(ConfigurationListenerPropertyBase *pListener)
Stop listening.
#define SAL_WARN_IF(condition, area, stream)
A batch of configuration changes that is committed as a whole.
virtual void SAL_CALL propertyChange(css::beans::PropertyChangeEvent const &rEvt) override
Notify of the property change.
static SolarMutex * get()
Help components to get the SolarMutex easily.
Definition: solarmutex.cxx:34
bool isReadOnly(OUString const &path) const
css::uno::Reference< css::uno::XInterface > access_
static css::uno::Reference< css::container::XNameContainer > getSetReadWrite(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path)
css::uno::Reference< css::container::XHierarchicalNameAccess > getGroupReadOnly(OUString const &path) const
SAL_DLLPRIVATE css::uno::Reference< css::container::XNameContainer > getSet(OUString const &path) const
void dispose()
virtual void setProperty(const css::uno::Any &aProperty)=0
SAL_DLLPRIVATE void setPropertyValue(OUString const &path, css::uno::Any const &value) const
std::shared_ptr< ConfigurationChanges > createChanges() const
ConfigurationChanges(const ConfigurationChanges &)=delete
static ConfigurationWrapper const & get(css::uno::Reference< css::uno::XComponentContext > const &context)