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::getTunnelId()
59 {
60  static const UnoTunnelIdInit 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 aIdentifier == getTunnelId()
168  ? reinterpret_cast< sal_Int64 >(this) : 0;
169 }
170 
172  rtl::Reference< RootAccess > const & root,
173  rtl::Reference< Access > const & parent, OUString const & name)
174  noexcept
175 {
176  assert(!parent_.is() && root.is() && parent.is() && !name.isEmpty());
177  root_ = root;
178  parent_ = parent;
179  name_ = name;
180 }
181 
182 void ChildAccess::unbind() noexcept {
183  assert(parent_.is());
184  parent_->releaseChild(name_);
185  parent_.clear();
186  inTransaction_ = true;
187 }
188 
190  inTransaction_ = false;
191 }
192 
194  node_ = node;
195 }
196 
198  css::uno::Any const & value, Modifications * localModifications)
199 {
200  assert(localModifications != nullptr);
201  Type type = TYPE_ERROR;
202  bool isNillable = false;
203  switch (node_->kind()) {
204  case Node::KIND_PROPERTY:
205  {
206  PropertyNode * prop = static_cast< PropertyNode * >(node_.get());
207  type = prop->getStaticType();
208  isNillable = prop->isNillable();
209  }
210  break;
212  {
213  OUString locale(getRootAccess()->getLocale());
214  if (!Components::allLocales(locale)) {
216  if (child.is()) {
217  child->setProperty(value, localModifications);
218  } else {
220  locale, value, localModifications);
221  }
222  return;
223  }
224  }
225  break;
227  {
228  LocalizedPropertyNode * locprop =
229  static_cast< LocalizedPropertyNode * >(getParentNode().get());
230  type = locprop->getStaticType();
231  isNillable = locprop->isNillable();
232  }
233  break;
234  default:
235  break;
236  }
237  checkValue(value, type, isNillable);
238  getParentAccess()->markChildAsModified(this);
239  changedValue_.reset(new css::uno::Any(value));
240  localModifications->add(getRelativePath());
241 }
242 
243 
244 css::uno::Any ChildAccess::asValue()
245 {
246  if (changedValue_ != nullptr)
247  {
248  return *changedValue_;
249  }
250  css::uno::Any value;
251  if (!asSimpleValue(node_, value, getComponents()))
252  {
253  if (node_->kind() == Node::KIND_LOCALIZED_PROPERTY)
254  {
255  OUString locale(getRootAccess()->getLocale());
256  if (!Components::allLocales(locale)) {
257  rtl::Reference< ChildAccess > child(getChild("*" + locale));
258  // As a last resort, return a nil value even though it may be
259  // illegal for the given property:
260  return child.is() ? child->asValue() : css::uno::Any();
261  }
262  }
263  value <<= css::uno::Reference< css::uno::XInterface >(
264  static_cast< cppu::OWeakObject * >(this));
265  }
266  return value;
267 }
268 
271  css::uno::Any &value,
272  Components &components)
273 {
274  switch (rNode->kind()) {
275  case Node::KIND_PROPERTY:
276  value = static_cast< PropertyNode * >(rNode.get())->getValue(components);
277  return true;
279  value = static_cast< LocalizedValueNode * >(rNode.get())->getValue();
280  return true;
281  default:
282  return false;
283  }
284 }
285 
286 void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
287 {
288  assert(globalModifications != nullptr);
289  commitChildChanges(valid, globalModifications);
290  if (valid && changedValue_ != nullptr)
291  {
292  std::vector<OUString> path(getAbsolutePath());
294  globalModifications->add(path);
295  switch (node_->kind()) {
296  case Node::KIND_PROPERTY:
297  static_cast< PropertyNode * >(node_.get())->setValue(
299  break;
301  static_cast< LocalizedValueNode * >(node_.get())->setValue(
303  break;
304  default:
305  assert(false); // this cannot happen
306  break;
307  }
308  }
309  changedValue_.reset();
310 }
311 
313  osl::MutexGuard g(*lock_);
314  if (parent_.is()) {
315  parent_->releaseChild(name_);
316  }
317 }
318 
319 void ChildAccess::addTypes(std::vector< css::uno::Type > * types) const {
320  assert(types != nullptr);
323 }
324 
326  std::vector<OUString> * services)
327 {
328  assert(services != nullptr);
329  services->push_back(
330  getParentNode()->kind() == Node::KIND_GROUP
331  ? OUString("com.sun.star.configuration.GroupElement")
332  : OUString("com.sun.star.configuration.SetElement"));
333 }
334 
335 css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType)
336 {
337  assert(thisIs(IS_ANY));
338  osl::MutexGuard g(*lock_);
340  css::uno::Any res(Access::queryInterface(aType));
341  return res.hasValue()
342  ? res
344  aType, static_cast< css::container::XChild * >(this),
345  static_cast< css::lang::XUnoTunnel * >(this));
346 }
347 
348 }
349 
350 /* 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:1358
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
std::unique_ptr< css::uno::Any > changedValue_
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:1537
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:1363
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:1503
void checkValue(css::uno::Any const &value, Type type, bool nillable)
Definition: access.cxx:1469
void add(std::vector< OUString > const &path)
virtual std::vector< OUString > getRelativePath() override
Definition: childaccess.cxx:92
void checkLocalizedPropertyAccess()
Definition: access.cxx:1348
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:1290
void commitChanges(bool valid, Modifications *globalModifications)
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
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
static css::uno::Sequence< sal_Int8 > const & getTunnelId()
Definition: childaccess.cxx:58
const css::uno::Sequence< sal_Int8 > & getSeq() const
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