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 namespace
59 {
60  class theChildAccessUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theChildAccessUnoTunnelId > {};
61 }
62 
63 css::uno::Sequence< sal_Int8 > const & ChildAccess::getTunnelId()
64 {
65  return theChildAccessUnoTunnelId::get().getSeq();
66 }
67 
69  Components & components, rtl::Reference< RootAccess > const & root,
70  rtl::Reference< Access > const & parent, OUString const & name,
71  rtl::Reference< Node > const & node):
72  Access(components), root_(root), parent_(parent), name_(name), node_(node),
73  inTransaction_(false),
74  lock_( lock() )
75 {
76  assert(root.is() && parent.is() && node.is());
77 }
78 
80  Components & components, rtl::Reference< RootAccess > const & root,
81  rtl::Reference< Node > const & node):
82  Access(components), root_(root), node_(node), inTransaction_(false),
83  lock_( lock() )
84 {
85  assert(root.is() && node.is());
86 }
87 
88 std::vector<OUString> ChildAccess::getAbsolutePath() {
90  assert(parent.is());
91  std::vector<OUString> path(parent->getAbsolutePath());
92  path.push_back(name_);
93  return path;
94 }
95 
96 std::vector<OUString> ChildAccess::getRelativePath() {
97  std::vector<OUString> path;
99  if (parent.is()) {
100  path = parent->getRelativePath();
101  }
102  path.push_back(name_);
103  return path;
104 }
105 
107  OUStringBuffer path(128);
109  if (parent.is()) {
110  path.append(parent->getRelativePathRepresentation());
111  if (!path.isEmpty()) {
112  path.append('/');
113  }
114  }
115  path.append(Data::createSegment(node_->getTemplateName(), name_));
116  return path.makeStringAndClear();
117 }
118 
120  return node_;
121 }
122 
124  return node_->getFinalized() != Data::NO_LAYER ||
125  (parent_.is() && parent_->isFinalized());
126 }
127 
129  return name_;
130 }
131 
133  return root_;
134 }
135 
137  return parent_;
138 }
139 
140 void ChildAccess::acquire() throw () {
141  Access::acquire();
142 }
143 
144 void ChildAccess::release() throw () {
145  Access::release();
146 }
147 
148 css::uno::Reference< css::uno::XInterface > ChildAccess::getParent()
149 {
150  assert(thisIs(IS_ANY));
151  osl::MutexGuard g(*lock_);
153  return static_cast< cppu::OWeakObject * >(parent_.get());
154 }
155 
156 void ChildAccess::setParent(css::uno::Reference< css::uno::XInterface > const &)
157 {
158  assert(thisIs(IS_ANY));
159  osl::MutexGuard g(*lock_);
161  throw css::lang::NoSupportException(
162  "setParent", static_cast< cppu::OWeakObject * >(this));
163 }
164 
166  css::uno::Sequence< sal_Int8 > const & aIdentifier)
167 {
168  assert(thisIs(IS_ANY));
169  osl::MutexGuard g(*lock_);
171  return aIdentifier == getTunnelId()
172  ? reinterpret_cast< sal_Int64 >(this) : 0;
173 }
174 
176  rtl::Reference< RootAccess > const & root,
177  rtl::Reference< Access > const & parent, OUString const & name)
178  throw ()
179 {
180  assert(!parent_.is() && root.is() && parent.is() && !name.isEmpty());
181  root_ = root;
182  parent_ = parent;
183  name_ = name;
184 }
185 
186 void ChildAccess::unbind() throw () {
187  assert(parent_.is());
188  parent_->releaseChild(name_);
189  parent_.clear();
190  inTransaction_ = true;
191 }
192 
194  inTransaction_ = false;
195 }
196 
198  node_ = node;
199 }
200 
202  css::uno::Any const & value, Modifications * localModifications)
203 {
204  assert(localModifications != nullptr);
205  Type type = TYPE_ERROR;
206  bool isNillable = false;
207  switch (node_->kind()) {
208  case Node::KIND_PROPERTY:
209  {
210  PropertyNode * prop = static_cast< PropertyNode * >(node_.get());
211  type = prop->getStaticType();
212  isNillable = prop->isNillable();
213  }
214  break;
216  {
217  OUString locale(getRootAccess()->getLocale());
218  if (!Components::allLocales(locale)) {
220  if (child.is()) {
221  child->setProperty(value, localModifications);
222  } else {
224  locale, value, localModifications);
225  }
226  return;
227  }
228  }
229  break;
231  {
232  LocalizedPropertyNode * locprop =
233  static_cast< LocalizedPropertyNode * >(getParentNode().get());
234  type = locprop->getStaticType();
235  isNillable = locprop->isNillable();
236  }
237  break;
238  default:
239  break;
240  }
241  checkValue(value, type, isNillable);
242  getParentAccess()->markChildAsModified(this);
243  changedValue_.reset(new css::uno::Any(value));
244  localModifications->add(getRelativePath());
245 }
246 
247 
248 css::uno::Any ChildAccess::asValue()
249 {
250  if (changedValue_ != nullptr)
251  {
252  return *changedValue_;
253  }
254  css::uno::Any value;
255  if (!asSimpleValue(node_, value, getComponents()))
256  {
257  if (node_->kind() == Node::KIND_LOCALIZED_PROPERTY)
258  {
259  OUString locale(getRootAccess()->getLocale());
260  if (!Components::allLocales(locale)) {
261  rtl::Reference< ChildAccess > child(getChild("*" + locale));
262  // As a last resort, return a nil value even though it may be
263  // illegal for the given property:
264  return child.is() ? child->asValue() : css::uno::Any();
265  }
266  }
267  value <<= css::uno::Reference< css::uno::XInterface >(
268  static_cast< cppu::OWeakObject * >(this));
269  }
270  return value;
271 }
272 
275  css::uno::Any &value,
276  Components &components)
277 {
278  switch (rNode->kind()) {
279  case Node::KIND_PROPERTY:
280  value = static_cast< PropertyNode * >(rNode.get())->getValue(components);
281  return true;
283  value = static_cast< LocalizedValueNode * >(rNode.get())->getValue();
284  return true;
285  default:
286  return false;
287  }
288 }
289 
290 void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
291 {
292  assert(globalModifications != nullptr);
293  commitChildChanges(valid, globalModifications);
294  if (valid && changedValue_ != nullptr)
295  {
296  std::vector<OUString> path(getAbsolutePath());
298  globalModifications->add(path);
299  switch (node_->kind()) {
300  case Node::KIND_PROPERTY:
301  static_cast< PropertyNode * >(node_.get())->setValue(
303  break;
305  static_cast< LocalizedValueNode * >(node_.get())->setValue(
307  break;
308  default:
309  assert(false); // this cannot happen
310  break;
311  }
312  }
313  changedValue_.reset();
314 }
315 
317  osl::MutexGuard g(*lock_);
318  if (parent_.is()) {
319  parent_->releaseChild(name_);
320  }
321 }
322 
323 void ChildAccess::addTypes(std::vector< css::uno::Type > * types) const {
324  assert(types != nullptr);
327 }
328 
330  std::vector<OUString> * services)
331 {
332  assert(services != nullptr);
333  services->push_back(
334  getParentNode()->kind() == Node::KIND_GROUP
335  ? OUString("com.sun.star.configuration.GroupElement")
336  : OUString("com.sun.star.configuration.SetElement"));
337 }
338 
339 css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType)
340 {
341  assert(thisIs(IS_ANY));
342  osl::MutexGuard g(*lock_);
344  css::uno::Any res(Access::queryInterface(aType));
345  return res.hasValue()
346  ? res
348  aType, static_cast< css::container::XChild * >(this),
349  static_cast< css::lang::XUnoTunnel * >(this));
350 }
351 
352 }
353 
354 /* 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:68
RegError REGISTRY_CALLTYPE setValue(RegKeyHandle hKey, rtl_uString *keyName, RegValueType valueType, RegValue pData, sal_uInt32 valueSize)
rtl::Reference< Node > getParentNode()
Definition: access.cxx:1358
void bind(rtl::Reference< RootAccess > const &root, rtl::Reference< Access > const &parent, OUString const &name)
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_
virtual void addTypes(std::vector< css::uno::Type > *types) const override
virtual rtl::Reference< RootAccess > getRootAccess() override
std::shared_ptr< osl::Mutex > lock_
css::beans::Optional< css::uno::Any > getValue(OUString const &id)
void setNode(rtl::Reference< Node > const &node)
virtual std::vector< OUString > getAbsolutePath() override
Definition: childaccess.cxx:88
virtual rtl::Reference< Node > getNode() override
rtl::Reference< Node > node_
void commitChildChanges(bool valid, Modifications *globalModifications)
Definition: access.cxx:1537
OUString name_
virtual void SAL_CALL acquire() SAL_OVERRIDE
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual void SAL_CALL acquire() override
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &aType) override
virtual rtl::Reference< Access > getParentAccess() 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:96
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.
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
virtual void SAL_CALL release() override
Type getStaticType() const
virtual void SAL_CALL release() SAL_OVERRIDE
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)
static OUString createSegment(OUString const &templateName, OUString const &name)
Definition: data.cxx:79
OUString name
Definition: components.cxx:83
rtl::Reference< Access > parent_
std::shared_ptr< osl::Mutex > lock_
static css::uno::Sequence< sal_Int8 > const & getTunnelId()
Definition: childaccess.cxx:63
static bool allLocales(OUString const &locale)
Definition: components.cxx:205
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