LibreOffice Module configmgr (master)  1
childaccess.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 #include <vector>
24 
25 #include <com/sun/star/container/XChild.hpp>
26 #include <com/sun/star/lang/NoSupportException.hpp>
27 #include <com/sun/star/lang/XUnoTunnel.hpp>
28 #include <com/sun/star/uno/Any.hxx>
29 #include <com/sun/star/uno/Reference.hxx>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/uno/Type.hxx>
32 #include <com/sun/star/uno/XInterface.hpp>
33 #include <cppu/unotype.hxx>
35 #include <cppuhelper/weak.hxx>
37 #include <osl/mutex.hxx>
38 #include <rtl/ref.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <rtl/ustring.hxx>
41 #include <sal/types.h>
42 
43 #include "access.hxx"
44 #include "childaccess.hxx"
45 #include "components.hxx"
46 #include "data.hxx"
48 #include "localizedvaluenode.hxx"
49 #include "lock.hxx"
50 #include "modifications.hxx"
51 #include "node.hxx"
52 #include "propertynode.hxx"
53 #include "rootaccess.hxx"
54 #include "type.hxx"
55 
56 namespace configmgr {
57 
58 css::uno::Sequence< sal_Int8 > const & ChildAccess::getUnoTunnelId()
59 {
60  static const comphelper::UnoIdInit theChildAccessUnoTunnelId;
61  return theChildAccessUnoTunnelId.getSeq();
62 }
63 
65  Components & components, rtl::Reference< RootAccess > const & root,
66  rtl::Reference< Access > const & parent, OUString const & name,
67  rtl::Reference< Node > const & node):
68  Access(components), root_(root), parent_(parent), name_(name), node_(node),
69  inTransaction_(false),
70  lock_( lock() )
71 {
72  assert(root.is() && parent.is() && node.is());
73 }
74 
76  Components & components, rtl::Reference< RootAccess > const & root,
77  rtl::Reference< Node > const & node):
78  Access(components), root_(root), node_(node), inTransaction_(false),
79  lock_( lock() )
80 {
81  assert(root.is() && node.is());
82 }
83 
84 std::vector<OUString> ChildAccess::getAbsolutePath() {
86  assert(parent.is());
87  std::vector<OUString> path(parent->getAbsolutePath());
88  path.push_back(name_);
89  return path;
90 }
91 
92 std::vector<OUString> ChildAccess::getRelativePath() {
93  std::vector<OUString> path;
95  if (parent.is()) {
96  path = parent->getRelativePath();
97  }
98  path.push_back(name_);
99  return path;
100 }
101 
103  OUStringBuffer path(128);
105  if (parent.is()) {
106  path.append(parent->getRelativePathRepresentation());
107  if (!path.isEmpty()) {
108  path.append('/');
109  }
110  }
111  path.append(Data::createSegment(node_->getTemplateName(), name_));
112  return path.makeStringAndClear();
113 }
114 
116  return node_;
117 }
118 
120  return node_->getFinalized() != Data::NO_LAYER ||
121  (parent_.is() && parent_->isFinalized());
122 }
123 
125  return name_;
126 }
127 
129  return root_;
130 }
131 
133  return parent_;
134 }
135 
136 void ChildAccess::acquire() noexcept {
137  Access::acquire();
138 }
139 
140 void ChildAccess::release() noexcept {
141  Access::release();
142 }
143 
144 css::uno::Reference< css::uno::XInterface > ChildAccess::getParent()
145 {
146  assert(thisIs(IS_ANY));
147  osl::MutexGuard g(*lock_);
149  return static_cast< cppu::OWeakObject * >(parent_.get());
150 }
151 
152 void ChildAccess::setParent(css::uno::Reference< css::uno::XInterface > const &)
153 {
154  assert(thisIs(IS_ANY));
155  osl::MutexGuard g(*lock_);
157  throw css::lang::NoSupportException(
158  "setParent", static_cast< cppu::OWeakObject * >(this));
159 }
160 
162  css::uno::Sequence< sal_Int8 > const & aIdentifier)
163 {
164  assert(thisIs(IS_ANY));
165  osl::MutexGuard g(*lock_);
167  return comphelper::getSomethingImpl(aIdentifier, this);
168 }
169 
171  rtl::Reference< RootAccess > const & root,
172  rtl::Reference< Access > const & parent, OUString const & name)
173  noexcept
174 {
175  assert(!parent_.is() && root.is() && parent.is() && !name.isEmpty());
176  root_ = root;
177  parent_ = parent;
178  name_ = name;
179 }
180 
181 void ChildAccess::unbind() noexcept {
182  assert(parent_.is());
183  parent_->releaseChild(name_);
184  parent_.clear();
185  inTransaction_ = true;
186 }
187 
189  inTransaction_ = false;
190 }
191 
193  node_ = node;
194 }
195 
197  css::uno::Any const & value, Modifications * localModifications)
198 {
199  assert(localModifications != nullptr);
200  Type type = TYPE_ERROR;
201  bool isNillable = false;
202  switch (node_->kind()) {
203  case Node::KIND_PROPERTY:
204  {
205  PropertyNode * prop = static_cast< PropertyNode * >(node_.get());
206  type = prop->getStaticType();
207  isNillable = prop->isNillable();
208  }
209  break;
211  {
212  OUString locale(getRootAccess()->getLocale());
213  if (!Components::allLocales(locale)) {
215  if (child.is()) {
216  child->setProperty(value, localModifications);
217  } else {
219  locale, value, localModifications);
220  }
221  return;
222  }
223  }
224  break;
226  {
227  LocalizedPropertyNode * locprop =
228  static_cast< LocalizedPropertyNode * >(getParentNode().get());
229  type = locprop->getStaticType();
230  isNillable = locprop->isNillable();
231  }
232  break;
233  default:
234  break;
235  }
236  checkValue(value, type, isNillable);
237  getParentAccess()->markChildAsModified(this);
238  changedValue_.emplace(value);
239  localModifications->add(getRelativePath());
240 }
241 
242 
243 css::uno::Any ChildAccess::asValue()
244 {
245  if (changedValue_)
246  {
247  return *changedValue_;
248  }
249  css::uno::Any value;
250  if (!asSimpleValue(node_, value, getComponents()))
251  {
252  if (node_->kind() == Node::KIND_LOCALIZED_PROPERTY)
253  {
254  OUString locale(getRootAccess()->getLocale());
255  if (!Components::allLocales(locale)) {
256  rtl::Reference< ChildAccess > child(getChild("*" + locale));
257  // As a last resort, return a nil value even though it may be
258  // illegal for the given property:
259  return child.is() ? child->asValue() : css::uno::Any();
260  }
261  }
262  value <<= css::uno::Reference< css::uno::XInterface >(
263  static_cast< cppu::OWeakObject * >(this));
264  }
265  return value;
266 }
267 
270  css::uno::Any &value,
271  Components &components)
272 {
273  switch (rNode->kind()) {
274  case Node::KIND_PROPERTY:
275  value = static_cast< PropertyNode * >(rNode.get())->getValue(components);
276  return true;
278  value = static_cast< LocalizedValueNode * >(rNode.get())->getValue();
279  return true;
280  default:
281  return false;
282  }
283 }
284 
285 void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
286 {
287  assert(globalModifications != nullptr);
288  commitChildChanges(valid, globalModifications);
289  if (valid && changedValue_)
290  {
291  std::vector<OUString> path(getAbsolutePath());
293  globalModifications->add(path);
294  switch (node_->kind()) {
295  case Node::KIND_PROPERTY:
296  static_cast< PropertyNode * >(node_.get())->setValue(
298  break;
300  static_cast< LocalizedValueNode * >(node_.get())->setValue(
302  break;
303  default:
304  assert(false); // this cannot happen
305  break;
306  }
307  }
308  changedValue_.reset();
309 }
310 
312  osl::MutexGuard g(*lock_);
313  if (parent_.is()) {
314  parent_->releaseChild(name_);
315  }
316 }
317 
318 void ChildAccess::addTypes(std::vector< css::uno::Type > * types) const {
319  assert(types != nullptr);
322 }
323 
325  std::vector<OUString> * services)
326 {
327  assert(services != nullptr);
328  services->push_back(
329  getParentNode()->kind() == Node::KIND_GROUP
330  ? OUString("com.sun.star.configuration.GroupElement")
331  : OUString("com.sun.star.configuration.SetElement"));
332 }
333 
334 css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType)
335 {
336  assert(thisIs(IS_ANY));
337  osl::MutexGuard g(*lock_);
339  css::uno::Any res(Access::queryInterface(aType));
340  return res.hasValue()
341  ? res
343  aType, static_cast< css::container::XChild * >(this),
344  static_cast< css::lang::XUnoTunnel * >(this));
345 }
346 
347 }
348 
349 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ChildAccess(Components &components, rtl::Reference< RootAccess > const &root, rtl::Reference< Access > const &parent, OUString const &name, rtl::Reference< Node > const &node)
Definition: childaccess.cxx:64
RegError REGISTRY_CALLTYPE setValue(RegKeyHandle hKey, rtl_uString *keyName, RegValueType valueType, RegValue pData, sal_uInt32 valueSize)
rtl::Reference< Node > getParentNode()
Definition: access.cxx:1359
static bool allLocales(std::u16string_view locale)
Definition: components.cxx:205
virtual OUString getRelativePathRepresentation() override
virtual void addSupportedServiceNames(std::vector< OUString > *services) override
Components & getComponents() const
Definition: access.hxx:320
void unbind() noexcept
virtual void addTypes(std::vector< css::uno::Type > *types) const override
static OUString createSegment(std::u16string_view templateName, OUString const &name)
Definition: data.cxx:79
virtual rtl::Reference< RootAccess > getRootAccess() override
std::shared_ptr< osl::Mutex > lock_
virtual void SAL_CALL release() noexcept override
void setNode(rtl::Reference< Node > const &node)
virtual std::vector< OUString > getAbsolutePath() override
Definition: childaccess.cxx:84
virtual rtl::Reference< Node > getNode() override
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
rtl::Reference< Node > node_
void commitChildChanges(bool valid, Modifications *globalModifications)
Definition: access.cxx:1544
OUString name_
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &aType) override
virtual rtl::Reference< Access > getParentAccess() override
virtual void SAL_CALL acquire() noexcept override
rtl::Reference< ChildAccess > getChild(OUString const &name)
Definition: access.cxx:1364
virtual bool isFinalized() override
rtl::Reference< RootAccess > root_
rtl::Reference< RootAccess > root_
void insertLocalizedValueChild(OUString const &name, css::uno::Any const &value, Modifications *localModifications)
Definition: access.cxx:1510
const css::uno::Sequence< sal_Int8 > & getSeq() const
static css::uno::Sequence< sal_Int8 > const & getUnoTunnelId()
Definition: childaccess.cxx:58
void checkValue(css::uno::Any const &value, Type type, bool nillable)
Definition: access.cxx:1476
void add(std::vector< OUString > const &path)
virtual std::vector< OUString > getRelativePath() override
Definition: childaccess.cxx:92
void checkLocalizedPropertyAccess()
Definition: access.cxx:1349
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &aType) override
Definition: access.cxx:1291
void commitChanges(bool valid, Modifications *globalModifications)
std::optional< css::uno::Any > changedValue_
static bool asSimpleValue(const rtl::Reference< Node > &rNode, css::uno::Any &value, Components &components)
Can we quickly extract a simple value into value ? if so returns true.
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
void addModification(std::vector< OUString > const &path)
Definition: components.cxx:268
const LanguageTag & getLocale()
bool thisIs(int what)
Definition: access.cxx:2191
virtual ~ChildAccess() override
sal_Int64 getSomethingImpl(const css::uno::Sequence< sal_Int8 > &rId, T *pThis, FallbackToGetSomethingOf< Base >={})
bool isNillable() const
void bind(rtl::Reference< RootAccess > const &root, rtl::Reference< Access > const &parent, OUString const &name) noexcept
Type getStaticType() const
Any value
virtual sal_Int64 SAL_CALL getSomething(css::uno::Sequence< sal_Int8 > const &aIdentifier) override
ResultType type
css::uno::Any asValue()
void setProperty(css::uno::Any const &value, Modifications *localModifications)
OUString name
Definition: components.cxx:83
rtl::Reference< Access > parent_
std::shared_ptr< osl::Mutex > lock_
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
std::shared_ptr< osl::Mutex > const & lock()
Definition: lock.cxx:28
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
virtual void SAL_CALL setParent(css::uno::Reference< css::uno::XInterface > const &) override
virtual OUString getNameInternal() override