diff options
Diffstat (limited to 'configmgr')
40 files changed, 710 insertions, 455 deletions
diff --git a/configmgr/qa/unit/test.cxx b/configmgr/qa/unit/test.cxx index daa2070086f7..d6213692405d 100644 --- a/configmgr/qa/unit/test.cxx +++ b/configmgr/qa/unit/test.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/beans/XPropertyChangeListener.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/configuration/ReadOnlyAccess.hpp> #include <com/sun/star/configuration/theDefaultProvider.hpp> #include <com/sun/star/container/XHierarchicalNameAccess.hpp> #include <com/sun/star/container/XNameContainer.hpp> @@ -38,6 +39,7 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/uno/XInterface.hpp> #include <com/sun/star/util/XChangesBatch.hpp> +#include <cppu/unotype.hxx> #include <cppuhelper/implbase.hxx> #include <osl/time.h> #include <rtl/ref.hxx> @@ -63,6 +65,7 @@ public: void testKeyReset(); void testSetSetMemberName(); void testInsertSetMember(); + void testLocalizedProperty(); void testReadCommands(); void testListener(); void testRecursive(); @@ -89,6 +92,7 @@ public: CPPUNIT_TEST(testKeyReset); CPPUNIT_TEST(testSetSetMemberName); CPPUNIT_TEST(testInsertSetMember); + CPPUNIT_TEST(testLocalizedProperty); CPPUNIT_TEST(testReadCommands); CPPUNIT_TEST(testListener); CPPUNIT_TEST(testRecursive); @@ -202,12 +206,18 @@ void Test::setUp() void Test::testKeyFetch() { - OUString s; - CPPUNIT_ASSERT( - getKey( - "/org.openoffice.System", - "L10N/Locale") >>= - s); + { + OUString s; + CPPUNIT_ASSERT( + getKey( + "/org.openoffice.System", + "L10N/Locale") >>= + s); + } + { + auto const v = getKey("/org.openoffice.System", "L10N/['Locale']"); + CPPUNIT_ASSERT_EQUAL(cppu::UnoType<OUString>::get(), v.getValueType()); + } } void Test::testKeySet() @@ -309,6 +319,51 @@ void Test::testInsertSetMember() { access, css::uno::UNO_QUERY_THROW)->dispose(); } +void Test::testLocalizedProperty() { + auto const access = css::configuration::ReadOnlyAccess::create( + comphelper::getProcessComponentContext(), "*"); + { + // See <https://bugs.documentfoundation.org/show_bug.cgi?id=33638> "Pagination extension + // not localized in LibreOffice", which wants to retrieve the non-canonical xml:lang="pt-PT" + // value for the passed-in "pt" locale: + OUString v; + CPPUNIT_ASSERT( + access->getByHierarchicalName("/org.libreoffice.unittest/localized/*pt") >>= v); + CPPUNIT_ASSERT_EQUAL(OUString("pt-PT"), v); + } + { + // See <https://gerrit.libreoffice.org/c/core/+/147089> "configmgr: fix no longer found + // es-419 -> es fallback", which wants to retrieve the xml:lang="es" value for the passed-in + // "es-419" locale: + OUString v; + CPPUNIT_ASSERT( + access->getByHierarchicalName("/org.libreoffice.unittest/localized/*es-419") >>= v); + CPPUNIT_ASSERT_EQUAL(OUString("es"), v); + } + { + // See <https://git.libreoffice.org/core/+/dfc28be2487c13be36a90efd778b8d8f179c589d%5E%21> + // "configmgr: Use a proper LanguageTag-based locale fallback mechanism": + OUString v; + CPPUNIT_ASSERT( + access->getByHierarchicalName("/org.libreoffice.unittest/localized/*zh-Hant-TW") >>= v); + CPPUNIT_ASSERT_EQUAL(OUString("zh-TW"), v); + } + { + // Make sure a degenerate passed-in "-" locale is handled gracefully: + OUString v; + CPPUNIT_ASSERT( + access->getByHierarchicalName("/org.libreoffice.unittest/localized/*-") >>= v); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), v); + } + { + // Make sure a degenerate passed-in "-" locale is handled gracefully: + OUString v; + CPPUNIT_ASSERT( + access->getByHierarchicalName("/org.libreoffice.unittest/noDefaultLang/*-") >>= v); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), v); + } +} + void Test::testReadCommands() { css::uno::Reference< css::container::XNameAccess > access( diff --git a/configmgr/qa/unit/urebootstrap.ini b/configmgr/qa/unit/urebootstrap.ini deleted file mode 100644 index 24b5e0f71c86..000000000000 --- a/configmgr/qa/unit/urebootstrap.ini +++ /dev/null @@ -1,20 +0,0 @@ -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This file incorporates work covered by the following license notice: -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed -# with this work for additional information regarding copyright -# ownership. The ASF licenses this file to you under the Apache -# License, Version 2.0 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.apache.org/licenses/LICENSE-2.0 . -# - -[Bootstrap] -BRAND_BASE_DIR = $ORIGIN/brand diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx index 30e75eb9e8b7..44a47e74b331 100644 --- a/configmgr/source/access.cxx +++ b/configmgr/source/access.cxx @@ -20,7 +20,9 @@ #include <sal/config.h> #include <cassert> +#include <cstddef> #include <cstdlib> +#include <utility> #include <vector> #include <com/sun/star/beans/Property.hpp> @@ -65,8 +67,10 @@ #include <com/sun/star/uno/XInterface.hpp> #include <com/sun/star/uno/XWeak.hpp> #include <com/sun/star/util/ElementChange.hpp> +#include <com/sun/star/util/InvalidStateException.hpp> #include <comphelper/sequence.hxx> #include <comphelper/servicehelper.hxx> +#include <comphelper/string.hxx> #include <comphelper/lok.hxx> #include <i18nlangtag/languagetag.hxx> #include <cppu/unotype.hxx> @@ -81,6 +85,7 @@ #include <rtl/ustring.hxx> #include <sal/log.hxx> #include <sal/types.h> +#include <o3tl/string_view.hxx> #include "access.hxx" #include "broadcaster.hxx" @@ -106,9 +111,9 @@ namespace { // Conservatively forbid what is either not an XML Char (including lone // surrogates, even though they should not appear in well-formed UNO OUString // instances anyway), or is a slash (as it causes problems in path syntax): -bool isValidName(OUString const & name, bool setMember) { - for (sal_Int32 i = 0; i != name.getLength();) { - sal_uInt32 c = name.iterateCodePoints(&i); +bool isValidName(std::u16string_view name, bool setMember) { + for (std::size_t i = 0; i != name.size();) { + sal_uInt32 c = o3tl::iterateCodePoints(name, &i); if ((c < 0x20 && !(c == 0x09 || c == 0x0A || c == 0x0D)) || rtl::isSurrogate(c) || c == 0xFFFE || c == 0xFFFF || (!setMember && c == '/')) @@ -116,7 +121,7 @@ bool isValidName(OUString const & name, bool setMember) { return false; } } - return !name.isEmpty(); + return !name.empty(); } } @@ -130,7 +135,7 @@ void Access::releaseNondeleting() { } bool Access::isValue() { - rtl::Reference< Node > p(getNode()); + const rtl::Reference< Node > & p(getNode()); switch (p->kind()) { case Node::KIND_PROPERTY: case Node::KIND_LOCALIZED_VALUE: @@ -214,6 +219,8 @@ css::uno::Sequence< css::uno::Type > Access::getTypes() } else { types.push_back( cppu::UnoType< css::container::XHierarchicalNameAccess >::get()); + types.push_back( + cppu::UnoType< css::configuration::XDocumentation >::get()); } addTypes(&types); return comphelper::containerToSequence(types); @@ -279,7 +286,7 @@ void Access::dispose() { if (getParentAccess().is()) { throw css::uno::RuntimeException( "configmgr dispose inappropriate Access", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } if (disposed_) { return; @@ -300,7 +307,7 @@ void Access::addEventListener( checkLocalizedPropertyAccess(); if (!xListener.is()) { throw css::uno::RuntimeException( - "null listener", static_cast< cppu::OWeakObject * >(this)); + "null listener", getXWeak()); } if (!disposed_) { disposeListeners_.insert(xListener); @@ -309,7 +316,7 @@ void Access::addEventListener( } try { xListener->disposing( - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } catch (css::lang::DisposedException &) {} } @@ -329,7 +336,7 @@ css::uno::Type Access::getElementType() { assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - rtl::Reference< Node > p(getNode()); + const rtl::Reference< Node > & p(getNode()); switch (p->kind()) { case Node::KIND_LOCALIZED_PROPERTY: return mapType( @@ -344,7 +351,7 @@ css::uno::Type Access::getElementType() { default: assert(false); throw css::uno::RuntimeException( - "this cannot happen", static_cast< cppu::OWeakObject * >(this)); + "this cannot happen", getXWeak()); } } @@ -352,7 +359,7 @@ sal_Bool Access::hasElements() { assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - return !getAllChildren().empty(); //TODO: optimize + return !isAllChildrenEmpty(); } bool Access::getByNameFast(const OUString & name, css::uno::Any & value) @@ -399,7 +406,7 @@ css::uno::Any Access::getByName(OUString const & aName) css::uno::Any value; if (!getByNameFast(aName, value)) throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); return value; } @@ -408,14 +415,13 @@ css::uno::Sequence< OUString > Access::getElementNames() assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - std::vector< rtl::Reference< ChildAccess > > children(getAllChildren()); - std::vector<OUString> names; - names.reserve(children.size()); - for (auto const& child : children) + std::vector<OUString> childNames; + forAllChildren([&childNames] (ChildAccess& rChild) { - names.push_back(child->getNameInternal()); - } - return comphelper::containerToSequence(names); + childNames.push_back(rChild.getNameInternal()); + return true; + }); + return comphelper::containerToSequence(childNames); } sal_Bool Access::hasByName(OUString const & aName) @@ -434,11 +440,68 @@ css::uno::Any Access::getByHierarchicalName(OUString const & aName) rtl::Reference< ChildAccess > child(getSubChild(aName)); if (!child.is()) { throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } return child->asValue(); } +OUString Access::getDescriptionByHierarchicalName(OUString const & aName) +{ + assert(thisIs(IS_ANY)); + osl::MutexGuard g(*lock_); + checkLocalizedPropertyAccess(); + rtl::Reference< ChildAccess > child(getSubChild(aName)); + if (!child.is()) { + throw css::container::NoSuchElementException( + aName, getXWeak()); + } + return child->getNode()->getDescription(); +} + +css::uno::Type Access::getTypeByHierarchicalName(OUString const & aName) +{ + assert(thisIs(IS_ANY)); + osl::MutexGuard g(*lock_); + checkLocalizedPropertyAccess(); + rtl::Reference< ChildAccess > child(getSubChild(aName)); + if (!child.is()) { + throw css::container::NoSuchElementException( + aName, getXWeak()); + } + auto const & p = child->getNode(); + switch (p->kind()) { + case Node::KIND_PROPERTY: + return mapType(static_cast<PropertyNode *>(p.get())->getStaticType()); + case Node::KIND_LOCALIZED_PROPERTY: + return mapType(static_cast<LocalizedPropertyNode *>(p.get())->getStaticType()); + default: + throw css::util::InvalidStateException( + aName, getXWeak()); + } +} + +sal_Bool Access::getModifiedByHierarchicalName(OUString const & aName) +{ + assert(thisIs(IS_ANY)); + osl::MutexGuard g(*lock_); + checkLocalizedPropertyAccess(); + rtl::Reference< ChildAccess > child(getSubChild(aName)); + if (!child.is()) { + throw css::container::NoSuchElementException( + aName, getXWeak()); + } + auto const & p = child->getNode(); + switch (p->kind()) { + case Node::KIND_PROPERTY: + return static_cast<PropertyNode *>(p.get())->isModified(); + case Node::KIND_LOCALIZED_VALUE: + return static_cast<LocalizedValueNode *>(p.get())->isModified(); + default: + throw css::util::InvalidStateException( + aName, getXWeak()); + } +} + sal_Bool Access::hasByHierarchicalName(OUString const & aName) { assert(thisIs(IS_ANY)); @@ -459,7 +522,7 @@ void Access::replaceByHierarchicalName( rtl::Reference< ChildAccess > child(getSubChild(aName)); if (!child.is()) { throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } child->checkFinalized(); rtl::Reference< Node > parent(child->getParentNode()); @@ -474,12 +537,12 @@ void Access::replaceByHierarchicalName( throw css::lang::IllegalArgumentException( ("configmgr::Access::replaceByHierarchicalName does not" " currently support set members"), - static_cast< cppu::OWeakObject * >(this), 0); + getXWeak(), 0); case Node::KIND_ROOT: throw css::lang::IllegalArgumentException( ("configmgr::Access::replaceByHierarchicalName does not allow" " changing component " + aName), - static_cast< cppu::OWeakObject * >(this), 0); + getXWeak(), 0); default: assert(false); // this cannot happen break; @@ -498,7 +561,7 @@ void Access::addContainerListener( checkLocalizedPropertyAccess(); if (!xListener.is()) { throw css::uno::RuntimeException( - "null listener", static_cast< cppu::OWeakObject * >(this)); + "null listener", getXWeak()); } if (!disposed_) { containerListeners_.insert(xListener); @@ -507,7 +570,7 @@ void Access::addContainerListener( } try { xListener->disposing( - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } catch (css::lang::DisposedException &) {} } @@ -535,13 +598,12 @@ css::uno::Sequence< css::beans::Property > Access::getProperties() { assert(thisIs(IS_GROUP)); osl::MutexGuard g(*lock_); - std::vector< rtl::Reference< ChildAccess > > children(getAllChildren()); std::vector< css::beans::Property > properties; - properties.reserve(children.size()); - for (auto const& child : children) + forAllChildren([&properties] (ChildAccess& rChild) { - properties.push_back(child->asProperty()); - } + properties.push_back(rChild.asProperty()); + return true; + }); return comphelper::containerToSequence(properties); } @@ -552,7 +614,7 @@ css::beans::Property Access::getPropertyByName(OUString const & aName) rtl::Reference< ChildAccess > child(getChild(aName)); if (!child.is()) { throw css::beans::UnknownPropertyException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } return child->asProperty(); } @@ -593,7 +655,7 @@ OUString Access::composeHierarchicalName( if (aRelativeName.isEmpty() || aRelativeName[0] == '/') { throw css::lang::IllegalArgumentException( "configmgr composeHierarchicalName inappropriate relative name", - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } OUStringBuffer path(getRelativePathRepresentation()); if (!path.isEmpty()) { @@ -625,7 +687,7 @@ void Access::setName(OUString const & aName) { rtl::Reference< Access > parent(getParentAccess()); if (parent.is()) { - rtl::Reference< Node > node(getNode()); + const rtl::Reference< Node > & node(getNode()); if (! node->getTemplateName().isEmpty()) { rtl::Reference< ChildAccess > other( parent->getChild(aName)); @@ -668,7 +730,7 @@ void Access::setName(OUString const & aName) // but a localized property is never an extension property throw css::uno::RuntimeException( "configmgr setName inappropriate node", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); default: assert(false); // this cannot happen break; @@ -702,12 +764,12 @@ void Access::setPropertyValue( if (!getRootAccess()->isUpdate()) { throw css::uno::RuntimeException( "configmgr setPropertyValue on non-update access", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } Modifications localMods; if (!setChildProperty(aPropertyName, aValue, &localMods)) { throw css::beans::UnknownPropertyException( - aPropertyName, static_cast< cppu::OWeakObject * >(this)); + aPropertyName, getXWeak()); } getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc); } @@ -722,7 +784,7 @@ css::uno::Any Access::getPropertyValue(OUString const & PropertyName) css::uno::Any value; if (!getByNameFast(PropertyName, value)) throw css::beans::UnknownPropertyException( - PropertyName, static_cast< cppu::OWeakObject * >(this)); + PropertyName, getXWeak()); return value; } @@ -736,7 +798,7 @@ void Access::addPropertyChangeListener( osl::MutexGuard g(*lock_); if (!xListener.is()) { throw css::uno::RuntimeException( - "null listener", static_cast< cppu::OWeakObject * >(this)); + "null listener", getXWeak()); } checkKnownProperty(aPropertyName); if (!disposed_) { @@ -746,7 +808,7 @@ void Access::addPropertyChangeListener( } try { xListener->disposing( - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } catch (css::lang::DisposedException &) {} } @@ -781,7 +843,7 @@ void Access::addVetoableChangeListener( osl::MutexGuard g(*lock_); if (!aListener.is()) { throw css::uno::RuntimeException( - "null listener", static_cast< cppu::OWeakObject * >(this)); + "null listener", getXWeak()); } checkKnownProperty(PropertyName); if (!disposed_) { @@ -792,7 +854,7 @@ void Access::addVetoableChangeListener( } try { aListener->disposing( - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } catch (css::lang::DisposedException &) {} } @@ -828,20 +890,20 @@ void Access::setPropertyValues( if (!getRootAccess()->isUpdate()) { throw css::uno::RuntimeException( "configmgr setPropertyValues on non-update access", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } if (aPropertyNames.getLength() != aValues.getLength()) { throw css::lang::IllegalArgumentException( ("configmgr setPropertyValues: aPropertyNames/aValues of" " different length"), - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } Modifications localMods; for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i) { if (!setChildProperty(aPropertyNames[i], aValues[i], &localMods)) { throw css::lang::IllegalArgumentException( "configmgr setPropertyValues inappropriate property name", - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } } getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc); @@ -861,7 +923,7 @@ css::uno::Sequence< css::uno::Any > Access::getPropertyValues( if (!getByNameFast(aPropertyNames[i], aValsRange[i])) throw css::uno::RuntimeException( "configmgr getPropertyValues inappropriate property name", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } return vals; @@ -877,7 +939,7 @@ void Access::addPropertiesChangeListener( osl::MutexGuard g(*lock_); if (!xListener.is()) { throw css::uno::RuntimeException( - "null listener", static_cast< cppu::OWeakObject * >(this)); + "null listener", getXWeak()); } if (!disposed_) { propertiesChangeListeners_.insert(xListener); @@ -886,7 +948,7 @@ void Access::addPropertiesChangeListener( } try { xListener->disposing( - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } catch (css::lang::DisposedException &) {} } @@ -913,7 +975,7 @@ void Access::firePropertiesChangeEvent( aPropertyNames.getLength()); auto aEventsRange = asNonConstRange(events); for (sal_Int32 i = 0; i < events.getLength(); ++i) { - aEventsRange[i].Source = static_cast< cppu::OWeakObject * >(this); + aEventsRange[i].Source = getXWeak(); aEventsRange[i].PropertyName = aPropertyNames[i]; aEventsRange[i].Further = false; aEventsRange[i].PropertyHandle = -1; @@ -938,14 +1000,14 @@ void Access::setHierarchicalPropertyValue( if (!getRootAccess()->isUpdate()) { throw css::uno::RuntimeException( "configmgr setHierarchicalPropertyName on non-update access", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } rtl::Reference< ChildAccess > child( getSubChild(aHierarchicalPropertyName)); if (!child.is()) { throw css::beans::UnknownPropertyException( aHierarchicalPropertyName, - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } child->checkFinalized(); Modifications localMods; @@ -964,7 +1026,7 @@ css::uno::Any Access::getHierarchicalPropertyValue( if (!child.is()) { throw css::beans::UnknownPropertyException( aHierarchicalPropertyName, - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } return child->asValue(); } @@ -980,13 +1042,13 @@ void Access::setHierarchicalPropertyValues( if (!getRootAccess()->isUpdate()) { throw css::uno::RuntimeException( "configmgr setPropertyValues on non-update access", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } if (aHierarchicalPropertyNames.getLength() != Values.getLength()) { throw css::lang::IllegalArgumentException( ("configmgr setHierarchicalPropertyValues:" " aHierarchicalPropertyNames/Values of different length"), - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } Modifications localMods; for (sal_Int32 i = 0; i < aHierarchicalPropertyNames.getLength(); ++i) { @@ -996,7 +1058,7 @@ void Access::setHierarchicalPropertyValues( throw css::lang::IllegalArgumentException( ("configmgr setHierarchicalPropertyValues inappropriate" " property name"), - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } child->checkFinalized(); child->setProperty(Values[i], &localMods); @@ -1021,7 +1083,7 @@ css::uno::Sequence< css::uno::Any > Access::getHierarchicalPropertyValues( throw css::lang::IllegalArgumentException( ("configmgr getHierarchicalPropertyValues inappropriate" " hierarchical property name"), - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } aValsRange[i] = child->asValue(); } @@ -1036,7 +1098,7 @@ css::beans::Property Access::getPropertyByHierarchicalName( rtl::Reference< ChildAccess > child(getSubChild(aHierarchicalName)); if (!child.is()) { throw css::beans::UnknownPropertyException( - aHierarchicalName, static_cast< cppu::OWeakObject * >(this)); + aHierarchicalName, getXWeak()); } return child->asProperty(); } @@ -1060,7 +1122,7 @@ void Access::replaceByName( rtl::Reference< ChildAccess > child(getChild(aName)); if (!child.is()) { throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } child->checkFinalized(); Modifications localMods; @@ -1100,14 +1162,14 @@ void Access::insertByName( checkFinalized(); if (getChild(aName).is()) { throw css::container::ElementExistException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } Modifications localMods; switch (getNode()->kind()) { case Node::KIND_LOCALIZED_PROPERTY: if (!isValidName(aName, false)) { throw css::lang::IllegalArgumentException( - aName, static_cast<cppu::OWeakObject *>(this), 0); + aName, getXWeak(), 0); } insertLocalizedValueChild(aName, aElement, &localMods); break; @@ -1115,7 +1177,7 @@ void Access::insertByName( { if (!isValidName(aName, false)) { throw css::lang::IllegalArgumentException( - aName, static_cast<cppu::OWeakObject *>(this), 0); + aName, getXWeak(), 0); } checkValue(aElement, TYPE_ANY, true); rtl::Reference child( @@ -1131,7 +1193,7 @@ void Access::insertByName( { if (!isValidName(aName, true)) { throw css::lang::IllegalArgumentException( - aName, static_cast<cppu::OWeakObject *>(this), 0); + aName, getXWeak(), 0); } rtl::Reference< ChildAccess > freeAcc( getFreeSetMember(aElement)); @@ -1161,15 +1223,15 @@ void Access::removeByName(OUString const & aName) child->getNode()->getMandatory() != Data::NO_LAYER) { throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } if (getNode()->kind() == Node::KIND_GROUP) { - rtl::Reference< Node > p(child->getNode()); + const rtl::Reference< Node >& p(child->getNode()); if (p->kind() != Node::KIND_PROPERTY || !static_cast< PropertyNode * >(p.get())->isExtension()) { throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); + aName, getXWeak()); } } Modifications localMods; @@ -1193,11 +1255,11 @@ css::uno::Reference< css::uno::XInterface > Access::createInstance() if (!tmpl.is()) { throw css::uno::Exception( "unknown template " + tmplName, - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } rtl::Reference< Node > node(tmpl->clone(true)); node->setLayer(Data::NO_LAYER); - return static_cast< cppu::OWeakObject * >( + return cppu::getXWeak( new ChildAccess(components_, getRootAccess(), node)); } @@ -1209,7 +1271,7 @@ css::uno::Reference< css::uno::XInterface > Access::createInstanceWithArguments( throw css::uno::Exception( ("configuration SimpleSetUpdate createInstanceWithArguments" " must not specify any arguments"), - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } return createInstance(); } @@ -1227,13 +1289,13 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { { broadcaster->addDisposeNotification( disposeListener, - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } for (auto const& containerListener : containerListeners_) { broadcaster->addDisposeNotification( containerListener, - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } for (auto const& propertyChangeListener : propertyChangeListeners_) { @@ -1242,7 +1304,7 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { broadcaster->addDisposeNotification( propertyChangeListenerElement, css::lang::EventObject( - static_cast< cppu::OWeakObject * >(this))); + getXWeak())); } } for (auto const& vetoableChangeListener : vetoableChangeListeners_) @@ -1252,14 +1314,14 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { broadcaster->addDisposeNotification( vetoableChangeListenerElement, css::lang::EventObject( - static_cast< cppu::OWeakObject * >(this))); + getXWeak())); } } for (auto const& propertiesChangeListener : propertiesChangeListeners_) { broadcaster->addDisposeNotification( propertiesChangeListener, - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } //TODO: iterate over children w/ listeners (incl. unmodified ones): for (ModifiedChildren::iterator i(modifiedChildren_.begin()); @@ -1300,6 +1362,7 @@ css::uno::Any Access::queryInterface(css::uno::Type const & aType) static_cast< css::lang::XServiceInfo * >(this), static_cast< css::lang::XComponent * >(this), static_cast< css::container::XHierarchicalNameAccess * >(this), + static_cast< css::configuration::XDocumentation * >(this), static_cast< css::container::XContainer * >(this), static_cast< css::beans::XExactName * >(this), static_cast< css::container::XHierarchicalName * >(this), @@ -1353,7 +1416,7 @@ void Access::checkLocalizedPropertyAccess() { { throw css::uno::RuntimeException( "configmgr Access to specialized LocalizedPropertyNode", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } } @@ -1375,7 +1438,7 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { << locale << "\" recursively starting with \"*\""); return getChild(locale); } - SAL_WARN_IF( + SAL_INFO_IF( locale.isEmpty(), "configmgr", ("access best-matching localized property value via \"*<locale>\"" " with empty <locale>; falling back to defaults")); @@ -1392,9 +1455,19 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { if (directChild.is()) return directChild; + LanguageTag aLanguageTag(locale, true); + if (aLanguageTag.getBcp47() != locale) + { + // Original may be overridden by a known locale, for example + // "zh-Hant-TW" by "zh-TW". + rtl::Reference<ChildAccess> child(getChild(aLanguageTag.getBcp47())); + if (child.is()) + return child; + } + // Find the best match using the LanguageTag fallback mechanism, // excluding the original tag. - std::vector<OUString> aFallbacks = LanguageTag(locale).getFallbackStrings(false); + std::vector<OUString> aFallbacks = aLanguageTag.getFallbackStrings(false); for (const OUString& rFallback : aFallbacks) { rtl::Reference<ChildAccess> child(getChild(rFallback)); @@ -1406,25 +1479,27 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { // xml:lang attributes, look for the first entry with the same first // segment as the requested language tag before falling back to // defaults (see fdo#33638): - if (aFallbacks.size() > 0) - locale = aFallbacks[aFallbacks.size() - 1]; - assert( - !locale.isEmpty() && locale.indexOf('-') == -1 && - locale.indexOf('_') == -1); - - std::vector< rtl::Reference< ChildAccess > > children( - getAllChildren()); - for (auto const& child : children) + auto const i = comphelper::string::indexOfAny(locale, u"-_", 1); + if (i != -1) { + locale = locale.copy(0, i); + } + assert(!locale.isEmpty()); + rtl::Reference< ChildAccess > foundChild; + forAllChildren([&foundChild, &locale] (ChildAccess& rChild) { - OUString name2(child->getNameInternal()); + const OUString & name2(rChild.getNameInternal()); if (name2.startsWith(locale) && (name2.getLength() == locale.getLength() || name2[locale.getLength()] == '-' || name2[locale.getLength()] == '_')) { - return child; + foundChild = &rChild; + return false; } - } + return true; + }); + if (foundChild) + return foundChild; } // Defaults are the "en-US" locale, the "en" locale, the empty string locale, the first child (if // any, and if the property is non-nillable), or a null ChildAccess, in that order: @@ -1441,9 +1516,15 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { return child; } if (!static_cast<LocalizedPropertyNode *>(getNode().get())->isNillable()) { - std::vector< rtl::Reference< ChildAccess > > children(getAllChildren()); - if (!children.empty()) { - return children.front(); + // look for first child in list + rtl::Reference< ChildAccess > foundChild; + forAllChildren([&foundChild] (ChildAccess& rChild) + { + foundChild = &rChild; + return false; + }); + if (foundChild) { + return foundChild; } } return rtl::Reference< ChildAccess >(); @@ -1453,14 +1534,14 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { ? getUnmodifiedChild(name) : getModifiedChild(i); } -std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() { - std::vector< rtl::Reference< ChildAccess > > vec; +void Access::forAllChildren(const std::function<bool(ChildAccess&)> & func) { NodeMap const & members = getNode()->getMembers(); for (auto const& member : members) { if (modifiedChildren_.find(member.first) == modifiedChildren_.end()) { - vec.push_back(getUnmodifiedChild(member.first)); - assert(vec.back().is()); + bool bContinue = func(*getUnmodifiedChild(member.first)); + if (!bContinue) + return; } } for (ModifiedChildren::iterator i(modifiedChildren_.begin()); @@ -1468,10 +1549,28 @@ std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() { { rtl::Reference< ChildAccess > child(getModifiedChild(i)); if (child.is()) { - vec.push_back(child); + bool bContinue = func(*child); + if (!bContinue) + return; } } - return vec; +} + +bool Access::isAllChildrenEmpty() { + NodeMap const & members = getNode()->getMembers(); + for (auto const& member : members) + { + if (modifiedChildren_.find(member.first) == modifiedChildren_.end()) + return false; + } + for (ModifiedChildren::iterator i(modifiedChildren_.begin()); + i != modifiedChildren_.end(); ++i) + { + rtl::Reference< ChildAccess > child(getModifiedChild(i)); + if (child.is()) + return false; + } + return true; } void Access::checkValue(css::uno::Any const & value, Type type, bool nillable) { @@ -1504,7 +1603,7 @@ void Access::checkValue(css::uno::Any const & value, Type type, bool nillable) { if (!ok) { throw css::lang::IllegalArgumentException( "configmgr inappropriate property value", - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } } @@ -1621,8 +1720,7 @@ void Access::initBroadcasterAndChanges( addContainerElementReplacedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >( - this), + getXWeak(), css::uno::Any(i.first), css::uno::Any(), css::uno::Any())); //TODO: non-void Element, ReplacedElement @@ -1635,8 +1733,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addPropertyChangeNotification( propertyChangeListenerElement, css::beans::PropertyChangeEvent( - static_cast< cppu::OWeakObject * >( - this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any())); } @@ -1648,8 +1745,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addPropertyChangeNotification( propertyChangeListenerElement, css::beans::PropertyChangeEvent( - static_cast< cppu::OWeakObject * >( - this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any())); } @@ -1664,7 +1760,7 @@ void Access::initBroadcasterAndChanges( } if (collectPropChanges) { propChanges.emplace_back( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any()); } @@ -1679,7 +1775,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addContainerElementReplacedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), css::uno::Any(i.first), child->asValue(), css::uno::Any())); //TODO: distinguish add/modify; non-void ReplacedElement @@ -1701,7 +1797,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addContainerElementReplacedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), css::uno::Any(i.first), child->asValue(), css::uno::Any())); //TODO: distinguish add/remove/modify; non-void @@ -1715,7 +1811,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addPropertyChangeNotification( propertyChangeListenerElement, css::beans::PropertyChangeEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any())); } @@ -1727,7 +1823,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addPropertyChangeNotification( propertyChangeListenerElement, css::beans::PropertyChangeEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any())); } @@ -1742,7 +1838,7 @@ void Access::initBroadcasterAndChanges( } if (collectPropChanges) { propChanges.emplace_back( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any()); } @@ -1758,8 +1854,7 @@ void Access::initBroadcasterAndChanges( addContainerElementInsertedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >( - this), + getXWeak(), css::uno::Any(i.first), child->asValue(), css::uno::Any())); } @@ -1795,7 +1890,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addContainerElementRemovedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), css::uno::Any(i.first), css::uno::Any(), css::uno::Any())); //TODO: non-void ReplacedElement @@ -1822,7 +1917,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addContainerElementRemovedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), css::uno::Any(i.first), css::uno::Any(), css::uno::Any())); //TODO: non-void ReplacedElement @@ -1835,7 +1930,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addPropertyChangeNotification( propertyChangeListenerElement, css::beans::PropertyChangeEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any())); } @@ -1847,7 +1942,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addPropertyChangeNotification( propertyChangeListenerElement, css::beans::PropertyChangeEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any())); } @@ -1867,7 +1962,7 @@ void Access::initBroadcasterAndChanges( } if (collectPropChanges) { propChanges.emplace_back( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), i.first, false, -1, css::uno::Any(), css::uno::Any()); } @@ -1881,7 +1976,7 @@ void Access::initBroadcasterAndChanges( broadcaster->addContainerElementRemovedNotification( containerListener, css::container::ContainerEvent( - static_cast< cppu::OWeakObject * >(this), + getXWeak(), css::uno::Any(i.first), css::uno::Any(), css::uno::Any())); //TODO: non-void ReplacedElement @@ -1924,8 +2019,8 @@ Access::ModifiedChild::ModifiedChild(): {} Access::ModifiedChild::ModifiedChild( - rtl::Reference< ChildAccess > const & theChild, bool theDirectlyModified): - child(theChild), directlyModified(theDirectlyModified) + rtl::Reference< ChildAccess > theChild, bool theDirectlyModified): + child(std::move(theChild)), directlyModified(theDirectlyModified) {} rtl::Reference< ChildAccess > Access::getModifiedChild( @@ -2016,7 +2111,7 @@ rtl::Reference< ChildAccess > Access::getSubChild(OUString const & path) { return rtl::Reference< ChildAccess >(); } if (setElement) { - rtl::Reference< Node > p(parent->getNode()); + const rtl::Reference< Node >& p(parent->getNode()); switch (p->kind()) { case Node::KIND_LOCALIZED_PROPERTY: if (!Components::allLocales(getRootAccess()->getLocale()) || @@ -2068,7 +2163,7 @@ css::beans::Property Access::asProperty() { css::uno::Type type; bool nillable; bool removable; - rtl::Reference< Node > p(getNode()); + const rtl::Reference< Node >& p(getNode()); switch (p->kind()) { case Node::KIND_PROPERTY: { @@ -2116,7 +2211,7 @@ css::beans::Property Access::asProperty() { (nillable ? css::beans::PropertyAttribute::MAYBEVOID : 0) | (getRootAccess()->isUpdate() && removable ? css::beans::PropertyAttribute::REMOVABLE : 0) | - (!getRootAccess()->isUpdate() || p->getFinalized() != Data::NO_LAYER + (!getRootAccess()->isUpdate() || isFinalized() ? css::beans::PropertyAttribute::READONLY : 0))); //TODO: MAYBEDEFAULT } @@ -2124,7 +2219,7 @@ void Access::checkFinalized() { if (isFinalized()) { throw css::lang::IllegalArgumentException( "configmgr modification of finalized item", - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } } @@ -2152,20 +2247,22 @@ void Access::checkKnownProperty(OUString const & descriptor) { } } throw css::beans::UnknownPropertyException( - descriptor, static_cast< cppu::OWeakObject * >(this)); + descriptor, getXWeak()); } rtl::Reference< ChildAccess > Access::getFreeSetMember( css::uno::Any const & value) { - rtl::Reference< ChildAccess > freeAcc = comphelper::getFromUnoTunnel<ChildAccess>(value); + css::uno::Reference<XInterface> xTmp; + value >>= xTmp; + rtl::Reference< ChildAccess > freeAcc = dynamic_cast<ChildAccess*>(xTmp.get()); if (!freeAcc.is() || freeAcc->getParentAccess().is() || (freeAcc->isInTransaction() && freeAcc->getRootAccess() != getRootAccess())) { throw css::lang::IllegalArgumentException( "configmgr inappropriate set element", - static_cast< cppu::OWeakObject * >(this), 1); + getXWeak(), 1); } assert(dynamic_cast< SetNode * >(getNode().get()) != nullptr); if (!static_cast< SetNode * >(getNode().get())->isValidTemplate( @@ -2173,7 +2270,7 @@ rtl::Reference< ChildAccess > Access::getFreeSetMember( { throw css::lang::IllegalArgumentException( "configmgr inappropriate set element", - static_cast< cppu::OWeakObject * >(this), 1); + getXWeak(), 1); } return freeAcc; } @@ -2191,7 +2288,7 @@ rtl::Reference< Access > Access::getNotificationRoot() { #if !defined NDEBUG bool Access::thisIs(int what) { osl::MutexGuard g(*lock_); - rtl::Reference< Node > p(getNode()); + const rtl::Reference< Node >& p(getNode()); Node::Kind k(p->kind()); return (k != Node::KIND_PROPERTY && k != Node::KIND_LOCALIZED_VALUE && ((what & IS_GROUP) == 0 || k == Node::KIND_GROUP) && diff --git a/configmgr/source/access.hxx b/configmgr/source/access.hxx index 6d4ca787f3cc..bd93b4222177 100644 --- a/configmgr/source/access.hxx +++ b/configmgr/source/access.hxx @@ -35,6 +35,8 @@ #include <com/sun/star/beans/XPropertySetInfo.hpp> #include <com/sun/star/container/XContainer.hpp> #include <com/sun/star/container/XHierarchicalName.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/configuration/XDocumentation.hpp> #include <com/sun/star/container/XHierarchicalNameReplace.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/container/XNamed.hpp> @@ -82,6 +84,7 @@ class Access: public cppu::OWeakObject, public css::lang::XTypeProvider, public css::lang::XServiceInfo, public css::lang::XComponent, + public css::configuration::XDocumentation, public css::container::XHierarchicalNameReplace, public css::container::XContainer, public css::beans::XExactName, @@ -111,7 +114,7 @@ public: virtual std::vector<OUString> getRelativePath() = 0; virtual OUString getRelativePathRepresentation() = 0; - virtual rtl::Reference< Node > getNode() = 0; + virtual const rtl::Reference< Node > & getNode() = 0; virtual bool isFinalized() = 0; @@ -159,6 +162,15 @@ public: virtual css::uno::Any SAL_CALL getByHierarchicalName( OUString const & aName) override; + virtual OUString SAL_CALL getDescriptionByHierarchicalName( + OUString const & aName) override; + + virtual css::uno::Type SAL_CALL getTypeByHierarchicalName( + OUString const & aName) override; + + virtual sal_Bool SAL_CALL getModifiedByHierarchicalName( + OUString const & aName) override; + virtual sal_Bool SAL_CALL hasByHierarchicalName(OUString const & aName) override; virtual void SAL_CALL replaceByHierarchicalName( @@ -301,7 +313,7 @@ protected: virtual ~Access() override; - virtual OUString getNameInternal() = 0; + virtual const OUString & getNameInternal() = 0; virtual rtl::Reference< RootAccess > getRootAccess() = 0; virtual rtl::Reference< Access > getParentAccess() = 0; @@ -323,7 +335,8 @@ protected: rtl::Reference< Node > getParentNode(); rtl::Reference< ChildAccess > getChild(OUString const & name); - std::vector< rtl::Reference< ChildAccess > > getAllChildren(); + void forAllChildren(const std::function<bool(ChildAccess&)> & f); + bool isAllChildrenEmpty(); void checkValue( css::uno::Any const & value, Type type, bool nillable); @@ -354,7 +367,7 @@ private: ModifiedChild(); ModifiedChild( - rtl::Reference< ChildAccess > const & theChild, + rtl::Reference< ChildAccess > theChild, bool theDirectlyModified); }; diff --git a/configmgr/source/broadcaster.cxx b/configmgr/source/broadcaster.cxx index 24b047e9d5a4..365e25f9eb02 100644 --- a/configmgr/source/broadcaster.cxx +++ b/configmgr/source/broadcaster.cxx @@ -35,6 +35,7 @@ #include <cppuhelper/exc_hlp.hxx> #include <rtl/ustrbuf.hxx> #include <rtl/ustring.hxx> +#include <utility> #include "broadcaster.hxx" @@ -96,9 +97,12 @@ void Broadcaster::addPropertiesChangeNotification( void Broadcaster::addChangesNotification( css::uno::Reference< css::util::XChangesListener > const & listener, - css::util::ChangesEvent const & event) + css::util::ChangesEvent const & event, bool bRootListener) { - changesNotifications_.emplace_back(listener, event); + if (bRootListener) + rootChangesNotifications_.emplace_back(listener, event); + else + changesNotifications_.emplace_back(listener, event); } void Broadcaster::send() { @@ -163,19 +167,23 @@ void Broadcaster::send() { appendMessage(messages, e); } } - for (auto& rNotification : changesNotifications_) { - try { - rNotification.listener->changesOccurred(rNotification.event); - } catch (css::lang::DisposedException &) { - } catch (css::uno::Exception & e) { - exception = cppu::getCaughtException(); - appendMessage(messages, e); + // First root listeners, then the rest + for (const auto& container : { rootChangesNotifications_ , changesNotifications_}) + { + for (auto& rNotification : container) { + try { + rNotification.listener->changesOccurred(rNotification.event); + } catch (css::lang::DisposedException &) { + } catch (css::uno::Exception & e) { + exception = cppu::getCaughtException(); + appendMessage(messages, e); + } } } if (exception.hasValue()) { throw css::lang::WrappedTargetRuntimeException( ("configmgr exceptions during listener notification" + - messages.makeStringAndClear()), + messages), css::uno::Reference< css::uno::XInterface >(), exception); } @@ -183,8 +191,8 @@ void Broadcaster::send() { Broadcaster::DisposeNotification::DisposeNotification( css::uno::Reference< css::lang::XEventListener > const & theListener, - css::lang::EventObject const & theEvent): - listener(theListener), event(theEvent) + css::lang::EventObject theEvent): + listener(theListener), event(std::move(theEvent)) { assert(theListener.is()); } @@ -192,8 +200,8 @@ Broadcaster::DisposeNotification::DisposeNotification( Broadcaster::ContainerNotification::ContainerNotification( css::uno::Reference< css::container::XContainerListener > const & theListener, - css::container::ContainerEvent const & theEvent): - listener(theListener), event(theEvent) + css::container::ContainerEvent theEvent): + listener(theListener), event(std::move(theEvent)) { assert(theListener.is()); } @@ -201,8 +209,8 @@ Broadcaster::ContainerNotification::ContainerNotification( Broadcaster::PropertyChangeNotification::PropertyChangeNotification( css::uno::Reference< css::beans::XPropertyChangeListener > const & theListener, - css::beans::PropertyChangeEvent const & theEvent): - listener(theListener), event(theEvent) + css::beans::PropertyChangeEvent theEvent): + listener(theListener), event(std::move(theEvent)) { assert(theListener.is()); } @@ -218,8 +226,8 @@ Broadcaster::PropertiesChangeNotification::PropertiesChangeNotification( Broadcaster::ChangesNotification::ChangesNotification( css::uno::Reference< css::util::XChangesListener > const & theListener, - css::util::ChangesEvent const & theEvent): - listener(theListener), event(theEvent) + css::util::ChangesEvent theEvent): + listener(theListener), event(std::move(theEvent)) { assert(theListener.is()); } diff --git a/configmgr/source/broadcaster.hxx b/configmgr/source/broadcaster.hxx index 6c4943f5526e..711e7a83bd9e 100644 --- a/configmgr/source/broadcaster.hxx +++ b/configmgr/source/broadcaster.hxx @@ -72,7 +72,7 @@ public: void addChangesNotification( css::uno::Reference< css::util::XChangesListener > const & listener, - css::util::ChangesEvent const & event); + css::util::ChangesEvent const & event, bool bRootListener); void send(); @@ -86,7 +86,7 @@ private: DisposeNotification( css::uno::Reference< css::lang::XEventListener > const & theListener, - css::lang::EventObject const & theEvent); + css::lang::EventObject theEvent); }; struct ContainerNotification { @@ -95,7 +95,7 @@ private: ContainerNotification( css::uno::Reference< css::container::XContainerListener > const & theListener, - css::container::ContainerEvent const & theEvent); + css::container::ContainerEvent theEvent); }; struct PropertyChangeNotification { @@ -104,7 +104,7 @@ private: PropertyChangeNotification( css::uno::Reference< css::beans::XPropertyChangeListener > const & theListener, - css::beans::PropertyChangeEvent const & theEvent); + css::beans::PropertyChangeEvent theEvent); }; struct PropertiesChangeNotification { @@ -122,7 +122,7 @@ private: ChangesNotification( css::uno::Reference< css::util::XChangesListener > const & theListener, - css::util::ChangesEvent const & theEvent); + css::util::ChangesEvent theEvent); }; std::vector< DisposeNotification > disposeNotifications_; @@ -131,6 +131,7 @@ private: std::vector< ContainerNotification > containerElementReplacedNotifications_; std::vector< PropertyChangeNotification > propertyChangeNotifications_; std::vector< PropertiesChangeNotification > propertiesChangeNotifications_; + std::vector< ChangesNotification > rootChangesNotifications_; std::vector< ChangesNotification > changesNotifications_; }; diff --git a/configmgr/source/childaccess.cxx b/configmgr/source/childaccess.cxx index 87def984be17..abf3795f1d55 100644 --- a/configmgr/source/childaccess.cxx +++ b/configmgr/source/childaccess.cxx @@ -20,6 +20,7 @@ #include <sal/config.h> #include <cassert> +#include <utility> #include <vector> #include <com/sun/star/container/XChild.hpp> @@ -55,17 +56,11 @@ namespace configmgr { -css::uno::Sequence< sal_Int8 > const & ChildAccess::getUnoTunnelId() -{ - static const comphelper::UnoIdInit theChildAccessUnoTunnelId; - return theChildAccessUnoTunnelId.getSeq(); -} - ChildAccess::ChildAccess( Components & components, rtl::Reference< RootAccess > const & root, - rtl::Reference< Access > const & parent, OUString const & name, + rtl::Reference< Access > const & parent, OUString name, rtl::Reference< Node > const & node): - Access(components), root_(root), parent_(parent), name_(name), node_(node), + Access(components), root_(root), parent_(parent), name_(std::move(name)), node_(node), inTransaction_(false), lock_( lock() ) { @@ -112,7 +107,7 @@ OUString ChildAccess::getRelativePathRepresentation() { return path.makeStringAndClear(); } -rtl::Reference< Node > ChildAccess::getNode() { +const rtl::Reference< Node > & ChildAccess::getNode() { return node_; } @@ -121,7 +116,7 @@ bool ChildAccess::isFinalized() { (parent_.is() && parent_->isFinalized()); } -OUString ChildAccess::getNameInternal() { +const OUString & ChildAccess::getNameInternal() { return name_; } @@ -146,7 +141,7 @@ css::uno::Reference< css::uno::XInterface > ChildAccess::getParent() assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - return static_cast< cppu::OWeakObject * >(parent_.get()); + return cppu::getXWeak(parent_.get()); } void ChildAccess::setParent(css::uno::Reference< css::uno::XInterface > const &) @@ -155,16 +150,7 @@ void ChildAccess::setParent(css::uno::Reference< css::uno::XInterface > const &) osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); throw css::lang::NoSupportException( - "setParent", static_cast< cppu::OWeakObject * >(this)); -} - -sal_Int64 ChildAccess::getSomething( - css::uno::Sequence< sal_Int8 > const & aIdentifier) -{ - assert(thisIs(IS_ANY)); - osl::MutexGuard g(*lock_); - checkLocalizedPropertyAccess(); - return comphelper::getSomethingImpl(aIdentifier, this); + "setParent", getXWeak()); } void ChildAccess::bind( @@ -259,8 +245,7 @@ css::uno::Any ChildAccess::asValue() return child.is() ? child->asValue() : css::uno::Any(); } } - value <<= css::uno::Reference< css::uno::XInterface >( - static_cast< cppu::OWeakObject * >(this)); + value <<= css::uno::Reference(getXWeak()); } return value; } @@ -294,11 +279,11 @@ void ChildAccess::commitChanges(bool valid, Modifications * globalModifications) switch (node_->kind()) { case Node::KIND_PROPERTY: static_cast< PropertyNode * >(node_.get())->setValue( - Data::NO_LAYER, *changedValue_); + Data::NO_LAYER, *changedValue_, true); break; case Node::KIND_LOCALIZED_VALUE: static_cast< LocalizedValueNode * >(node_.get())->setValue( - Data::NO_LAYER, *changedValue_); + Data::NO_LAYER, *changedValue_, true); break; default: assert(false); // this cannot happen @@ -340,8 +325,7 @@ css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType) return res.hasValue() ? res : cppu::queryInterface( - aType, static_cast< css::container::XChild * >(this), - static_cast< css::lang::XUnoTunnel * >(this)); + aType, static_cast< css::container::XChild * >(this)); } } diff --git a/configmgr/source/childaccess.hxx b/configmgr/source/childaccess.hxx index d063a28c9c9c..f3948a08ab50 100644 --- a/configmgr/source/childaccess.hxx +++ b/configmgr/source/childaccess.hxx @@ -26,7 +26,6 @@ #include <vector> #include <com/sun/star/container/XChild.hpp> -#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <rtl/ref.hxx> @@ -48,15 +47,13 @@ class Node; class RootAccess; class ChildAccess: - public Access, public css::container::XChild, - public css::lang::XUnoTunnel + public Access, public css::container::XChild { public: - static css::uno::Sequence< sal_Int8 > const & getUnoTunnelId(); ChildAccess( Components & components, rtl::Reference< RootAccess > const & root, - rtl::Reference< Access > const & parent, OUString const & name, + rtl::Reference< Access > const & parent, OUString name, rtl::Reference< Node > const & node); ChildAccess( @@ -67,11 +64,11 @@ public: virtual std::vector<OUString> getRelativePath() override; virtual OUString getRelativePathRepresentation() override; - virtual rtl::Reference< Node > getNode() override; + virtual const rtl::Reference< Node > & getNode() override; virtual bool isFinalized() override; - virtual OUString getNameInternal() override; + virtual const OUString & getNameInternal() override; virtual rtl::Reference< RootAccess > getRootAccess() override; virtual rtl::Reference< Access > getParentAccess() override; @@ -85,9 +82,6 @@ public: virtual void SAL_CALL setParent( css::uno::Reference< css::uno::XInterface > const &) override; - virtual sal_Int64 SAL_CALL getSomething( - css::uno::Sequence< sal_Int8 > const & aIdentifier) override; - void bind( rtl::Reference< RootAccess > const & root, rtl::Reference< Access > const & parent, OUString const & name) diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index 65bc00da9517..3c35a258c12c 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -21,6 +21,7 @@ #include <cassert> #include <chrono> +#include <utility> #include <vector> #include <set> @@ -49,8 +50,9 @@ #include <sal/log.hxx> #include <sal/types.h> #include <salhelper/thread.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <comphelper/backupfilehelper.hxx> +#include <o3tl/string_view.hxx> #include "additions.hxx" #include "components.hxx" @@ -84,9 +86,9 @@ struct UnresolvedVectorItem { rtl::Reference< ParseManager > manager; UnresolvedVectorItem( - OUString const & theName, - rtl::Reference< ParseManager > const & theManager): - name(theName), manager(theManager) {} + OUString theName, + rtl::Reference< ParseManager > theManager): + name(std::move(theName)), manager(std::move(theManager)) {} }; typedef std::vector< UnresolvedVectorItem > UnresolvedVector; @@ -150,7 +152,7 @@ class Components::WriteThread: public salhelper::Thread { public: WriteThread( rtl::Reference< WriteThread > * reference, Components & components, - OUString const & url, Data const & data); + OUString url, Data const & data); void flush() { delay_.set(); } @@ -169,9 +171,9 @@ private: Components::WriteThread::WriteThread( rtl::Reference< WriteThread > * reference, Components & components, - OUString const & url, Data const & data): + OUString url, Data const & data): Thread("configmgrWriter"), reference_(reference), components_(components), - url_(url), data_(data), + url_(std::move(url)), data_(data), lock_( lock() ) { assert(reference != nullptr); @@ -404,15 +406,15 @@ void Components::insertModificationXcuFile( } css::beans::Optional< css::uno::Any > Components::getExternalValue( - OUString const & descriptor) + std::u16string_view descriptor) { - sal_Int32 i = descriptor.indexOf(' '); - if (i <= 0) { + size_t i = descriptor.find(' '); + if (i == 0 || i == std::u16string_view::npos) { throw css::uno::RuntimeException( - "bad external value descriptor " + descriptor); + OUString::Concat("bad external value descriptor ") + descriptor); } //TODO: Do not make calls with mutex locked: - OUString name(descriptor.copy(0, i)); + OUString name(descriptor.substr(0, i)); ExternalServices::iterator j(externalServices_.find(name)); if (j == externalServices_.end()) { css::uno::Reference< css::uno::XInterface > service; @@ -438,11 +440,11 @@ css::beans::Optional< css::uno::Any > Components::getExternalValue( css::beans::Optional< css::uno::Any > value; if (j->second.is()) { try { - if (!(j->second->getPropertyValue(descriptor.copy(i + 1)) >>= + if (!(j->second->getPropertyValue(OUString(descriptor.substr(i + 1))) >>= value)) { throw css::uno::RuntimeException( - "cannot obtain external value through " + descriptor); + OUString::Concat("cannot obtain external value through ") + descriptor); } } catch (css::beans::UnknownPropertyException & e) { throw css::uno::RuntimeException( @@ -715,11 +717,11 @@ void Components::parseFiles( } void Components::parseFileList( - int layer, FileParser * parseFile, OUString const & urls, + int layer, FileParser * parseFile, std::u16string_view urls, bool recordAdditions) { for (sal_Int32 i = 0;;) { - OUString url(urls.getToken(0, ' ', i)); + OUString url(o3tl::getToken(urls, 0, ' ', i)); if (!url.isEmpty()) { Additions * adds = nullptr; if (recordAdditions) { @@ -843,12 +845,12 @@ void Components::parseXcsXcuIniLayer( } } prefix.append(':'); - OUString urls(prefix.toString() + "SCHEMA}"); + OUString urls(prefix + "SCHEMA}"); rtl::Bootstrap::expandMacros(urls); if (!urls.isEmpty()) { parseFileList(layer, &parseXcsFile, urls, false); } - urls = prefix.makeStringAndClear() + "DATA}"; + urls = prefix + "DATA}"; rtl::Bootstrap::expandMacros(urls); if (!urls.isEmpty()) { parseFileList(layer + 1, &parseXcuFile, urls, recordAdditions); diff --git a/configmgr/source/components.hxx b/configmgr/source/components.hxx index a44097810015..5d7b6b5967ee 100644 --- a/configmgr/source/components.hxx +++ b/configmgr/source/components.hxx @@ -96,7 +96,7 @@ public: Modifications * modifications); css::beans::Optional< css::uno::Any > - getExternalValue(OUString const & descriptor); + getExternalValue(std::u16string_view descriptor); private: Components(const Components&) = delete; @@ -122,7 +122,7 @@ private: OUString const & url, bool recursive); void parseFileList( - int layer, FileParser * parseFile, OUString const & urls, + int layer, FileParser * parseFile, std::u16string_view urls, bool recordAdditions); void parseXcdFiles(int layer, OUString const & url); diff --git a/configmgr/source/config_map.hxx b/configmgr/source/config_map.hxx index af15f23ae9cf..46a553cdde39 100644 --- a/configmgr/source/config_map.hxx +++ b/configmgr/source/config_map.hxx @@ -6,8 +6,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef CONFIG_MAP_HXX -#define CONFIG_MAP_HXX +#pragma once #include <map> #include <rtl/ustring.hxx> @@ -19,12 +18,12 @@ struct LengthContentsCompare { - bool operator()(const OUString& a, const OUString& b) const + bool operator()(std::u16string_view a, std::u16string_view b) const { - if (a.getLength() == b.getLength()) + if (a.size() == b.size()) return a < b; else - return a.getLength() < b.getLength(); + return a.size() < b.size(); } }; @@ -32,6 +31,4 @@ template <class T> struct config_map : public std::map<OUString, T, LengthConten { }; -#endif // CONFIG_MAP_HXX - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/configmgr/source/configurationprovider.cxx b/configmgr/source/configurationprovider.cxx index f9936b6ba1a3..9789e0721bd6 100644 --- a/configmgr/source/configurationprovider.cxx +++ b/configmgr/source/configurationprovider.cxx @@ -39,8 +39,7 @@ #include <com/sun/star/util/XRefreshListener.hpp> #include <com/sun/star/util/XRefreshable.hpp> #include <cppu/unotype.hxx> -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase.hxx> +#include <comphelper/compbase.hxx> #include <cppuhelper/supportsservice.hxx> #include <cppuhelper/weak.hxx> #include <osl/mutex.hxx> @@ -49,6 +48,7 @@ #include <rtl/ustring.hxx> #include <i18nlangtag/languagetag.hxx> +#include <utility> #include "components.hxx" #include "configurationprovider.hxx" @@ -60,10 +60,10 @@ namespace configmgr::configuration_provider { namespace { -constexpr OUStringLiteral accessServiceName = - u"com.sun.star.configuration.ConfigurationAccess"; -constexpr OUStringLiteral updateAccessServiceName = - u"com.sun.star.configuration.ConfigurationUpdateAccess"; +constexpr OUString accessServiceName = + u"com.sun.star.configuration.ConfigurationAccess"_ustr; +constexpr OUString updateAccessServiceName = + u"com.sun.star.configuration.ConfigurationUpdateAccess"_ustr; void badNodePath() { throw css::uno::Exception( @@ -73,19 +73,18 @@ void badNodePath() { } typedef - cppu::WeakComponentImplHelper< + comphelper::WeakComponentImplHelper< css::lang::XServiceInfo, css::lang::XMultiServiceFactory, css::util::XRefreshable, css::util::XFlushable, css::lang::XLocalizable > ServiceBase; -class Service: - private cppu::BaseMutex, public ServiceBase +class Service : public ServiceBase { public: explicit Service( const css::uno::Reference< css::uno::XComponentContext >& context): - ServiceBase(m_aMutex), context_(context), default_(true), + context_(context), default_(true), lock_( lock() ) { assert(context.is()); @@ -93,8 +92,8 @@ public: Service( const css::uno::Reference< css::uno::XComponentContext >& context, - OUString const & locale): - ServiceBase(m_aMutex), context_(context), locale_(locale), + OUString locale): + context_(context), locale_(std::move(locale)), default_(false), lock_( lock() ) { @@ -107,7 +106,7 @@ private: virtual ~Service() override {} - virtual void SAL_CALL disposing() override { flushModifications(); } + virtual void disposing(std::unique_lock<std::mutex>& rGuard) override; virtual OUString SAL_CALL getImplementationName() override { @@ -164,6 +163,8 @@ private: OUString locale_; bool default_; std::shared_ptr<osl::Mutex> lock_; + comphelper::OInterfaceContainerHelper4<css::util::XRefreshListener> maRefreshListeners; + comphelper::OInterfaceContainerHelper4<css::util::XFlushListener> maFlushListeners; }; css::uno::Reference< css::uno::XInterface > Service::createInstance( @@ -247,7 +248,7 @@ Service::createInstanceWithArguments( throw css::uno::Exception( ("com.sun.star.configuration.ConfigurationProvider does not support" " service " + ServiceSpecifier), - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } osl::MutexGuard guard(*lock_); Components & components = Components::getSingleton(context_); @@ -257,10 +258,10 @@ Service::createInstanceWithArguments( throw css::uno::Exception( ("com.sun.star.configuration.ConfigurationProvider: there is a leaf" " value at nodepath " + nodepath), - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } components.addRootAccess(root); - return static_cast< cppu::OWeakObject * >(root.get()); + return root->getXWeak(); } css::uno::Sequence< OUString > Service::getAvailableServiceNames() @@ -270,49 +271,48 @@ css::uno::Sequence< OUString > Service::getAvailableServiceNames() void Service::refresh() { //TODO - cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer( - cppu::UnoType< css::util::XRefreshListener >::get()); - if (cont != nullptr) { - css::lang::EventObject ev(static_cast< cppu::OWeakObject * >(this)); - cont->notifyEach(&css::util::XRefreshListener::refreshed, ev); + std::unique_lock g(m_aMutex); + if (maRefreshListeners.getLength(g)) { + css::lang::EventObject ev(getXWeak()); + maRefreshListeners.notifyEach(g, &css::util::XRefreshListener::refreshed, ev); } } void Service::addRefreshListener( css::uno::Reference< css::util::XRefreshListener > const & l) { - rBHelper.addListener( - cppu::UnoType< css::util::XRefreshListener >::get(), l); + std::unique_lock g(m_aMutex); + maRefreshListeners.addInterface(g, l); } void Service::removeRefreshListener( css::uno::Reference< css::util::XRefreshListener > const & l) { - rBHelper.removeListener( - cppu::UnoType< css::util::XRefreshListener >::get(), l); + std::unique_lock g(m_aMutex); + maRefreshListeners.removeInterface(g, l); } void Service::flush() { flushModifications(); - cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer( - cppu::UnoType< css::util::XFlushListener >::get()); - if (cont != nullptr) { - css::lang::EventObject ev(static_cast< cppu::OWeakObject * >(this)); - cont->notifyEach(&css::util::XFlushListener::flushed, ev); + std::unique_lock g(m_aMutex); + if (maFlushListeners.getLength(g)) { + css::lang::EventObject ev(getXWeak()); + maFlushListeners.notifyEach(g, &css::util::XFlushListener::flushed, ev); } } void Service::addFlushListener( css::uno::Reference< css::util::XFlushListener > const & l) { - rBHelper.addListener(cppu::UnoType< css::util::XFlushListener >::get(), l); + std::unique_lock g(m_aMutex); + maFlushListeners.addInterface(g, l); } void Service::removeFlushListener( css::uno::Reference< css::util::XFlushListener > const & l) { - rBHelper.removeListener( - cppu::UnoType< css::util::XFlushListener >::get(), l); + std::unique_lock g(m_aMutex); + maFlushListeners.removeInterface(g, l); } void Service::setLocale(css::lang::Locale const & eLocale) @@ -330,6 +330,12 @@ css::lang::Locale Service::getLocale() { return loc; } +void Service::disposing(std::unique_lock<std::mutex>& rGuard) { + rGuard.unlock(); // just in case we call back into Service during dispose() + flushModifications(); + rGuard.lock(); +} + void Service::flushModifications() const { Components * components; { @@ -394,7 +400,7 @@ com_sun_star_comp_configuration_ConfigurationProvider_get_implementation( css::uno::Reference< css::uno::XInterface > createDefault( css::uno::Reference< css::uno::XComponentContext > const & context) { - return static_cast< cppu::OWeakObject * >(new Service(context)); + return getXWeak(new Service(context)); } } diff --git a/configmgr/source/configurationregistry.cxx b/configmgr/source/configurationregistry.cxx index 1301fcf134ce..4900b9f97d52 100644 --- a/configmgr/source/configurationregistry.cxx +++ b/configmgr/source/configurationregistry.cxx @@ -52,6 +52,7 @@ #include <cppuhelper/weak.hxx> #include <mutex> #include <rtl/ustring.hxx> +#include <utility> #include <sal/types.h> namespace com::sun::star::util { @@ -131,8 +132,8 @@ class RegistryKey: public cppu::WeakImplHelper< css::registry::XRegistryKey > { public: - RegistryKey(Service & service, css::uno::Any const & value): - service_(service), value_(value) {} + RegistryKey(Service & service, css::uno::Any value): + service_(service), value_(std::move(value)) {} private: RegistryKey(const RegistryKey&) = delete; @@ -262,7 +263,7 @@ void Service::open(OUString const & rURL, sal_Bool bReadOnly, sal_Bool) throw css::lang::WrappedTargetRuntimeException( "com.sun.star.configuration.ConfigurationRegistry: open failed: " + e.Message, - static_cast< cppu::OWeakObject * >(this), anyEx ); + getXWeak(), anyEx ); } url_ = rURL; readOnly_ = bReadOnly; @@ -284,7 +285,7 @@ void Service::destroy() { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Reference< css::registry::XRegistryKey > Service::getRootKey() @@ -304,14 +305,14 @@ void Service::mergeKey(OUString const &, OUString const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void Service::flush() { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void Service::addFlushListener( @@ -319,7 +320,7 @@ void Service::addFlushListener( { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void Service::removeFlushListener( @@ -327,14 +328,14 @@ void Service::removeFlushListener( { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void Service::checkValid() { if (!access_.is()) { throw css::registry::InvalidRegistryException( "com.sun.star.configuration.ConfigurationRegistry: not valid", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } } @@ -342,7 +343,7 @@ void Service::checkValid_RuntimeException() { if (!access_.is()) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not valid", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } } @@ -359,7 +360,7 @@ OUString RegistryKey::getKeyName() { } throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } sal_Bool RegistryKey::isReadOnly() @@ -417,14 +418,14 @@ sal_Int32 RegistryKey::getLongValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setLongValue(sal_Int32) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Sequence< sal_Int32 > RegistryKey::getLongListValue() @@ -437,14 +438,14 @@ css::uno::Sequence< sal_Int32 > RegistryKey::getLongListValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setLongListValue(css::uno::Sequence< sal_Int32 > const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } OUString RegistryKey::getAsciiValue() @@ -457,14 +458,14 @@ OUString RegistryKey::getAsciiValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setAsciiValue(OUString const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Sequence< OUString > RegistryKey::getAsciiListValue() @@ -477,14 +478,14 @@ css::uno::Sequence< OUString > RegistryKey::getAsciiListValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setAsciiListValue(css::uno::Sequence< OUString > const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } OUString RegistryKey::getStringValue() @@ -497,14 +498,14 @@ OUString RegistryKey::getStringValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setStringValue(OUString const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Sequence< OUString > RegistryKey::getStringListValue() @@ -517,7 +518,7 @@ css::uno::Sequence< OUString > RegistryKey::getStringListValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setStringListValue( @@ -525,7 +526,7 @@ void RegistryKey::setStringListValue( { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Sequence< sal_Int8 > RegistryKey::getBinaryValue() @@ -538,14 +539,14 @@ css::uno::Sequence< sal_Int8 > RegistryKey::getBinaryValue() } throw css::registry::InvalidValueException( "com.sun.star.configuration.ConfigurationRegistry", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::setBinaryValue(css::uno::Sequence< sal_Int8 > const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Reference< css::registry::XRegistryKey > RegistryKey::openKey( @@ -568,7 +569,7 @@ css::uno::Reference< css::registry::XRegistryKey > RegistryKey::createKey( { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } void RegistryKey::closeKey() @@ -581,7 +582,7 @@ void RegistryKey::deleteKey(OUString const &) { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > @@ -589,14 +590,14 @@ RegistryKey::openKeys() { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } css::uno::Sequence< OUString > RegistryKey::getKeyNames() { throw css::uno::RuntimeException( "com.sun.star.configuration.ConfigurationRegistry: not implemented", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } sal_Bool RegistryKey::createLink(OUString const &, OUString const &) diff --git a/configmgr/source/data.cxx b/configmgr/source/data.cxx index 6e95f1665726..dd15026c17de 100644 --- a/configmgr/source/data.cxx +++ b/configmgr/source/data.cxx @@ -21,6 +21,7 @@ #include <algorithm> #include <cassert> +#include <cstddef> #include <com/sun/star/uno/RuntimeException.hpp> #include <rtl/ref.hxx> @@ -30,6 +31,7 @@ #include <rtl/ustring.hxx> #include <sal/log.hxx> #include <sal/types.h> +#include <o3tl/string_view.hxx> #include "additions.hxx" #include "data.hxx" @@ -43,23 +45,23 @@ namespace configmgr { namespace { bool decode( - OUString const & encoded, sal_Int32 begin, sal_Int32 end, + std::u16string_view encoded, std::size_t begin, std::size_t end, OUString * decoded) { assert( - begin >= 0 && begin <= end && end <= encoded.getLength() && + begin <= end && end <= encoded.size() && decoded != nullptr); OUStringBuffer buf(end - begin); while (begin != end) { sal_Unicode c = encoded[begin++]; if (c == '&') { - if (encoded.match("amp;", begin)) { + if (o3tl::starts_with(encoded.substr(begin), u"amp;")) { buf.append('&'); begin += RTL_CONSTASCII_LENGTH("amp;"); - } else if (encoded.match("quot;", begin)) { + } else if (o3tl::starts_with(encoded.substr(begin), u"quot;")) { buf.append('"'); begin += RTL_CONSTASCII_LENGTH("quot;"); - } else if (encoded.match("apos;", begin)) { + } else if (o3tl::starts_with(encoded.substr(begin), u"apos;")) { buf.append('\''); begin += RTL_CONSTASCII_LENGTH("apos;"); } else { @@ -83,9 +85,8 @@ OUString Data::createSegment( return name; } OUStringBuffer buf(128); - buf.append(templateName); - //TODO: verify template name contains no bad chars? - buf.append("['"); + //TODO: verify template name contains no bad chars? + buf.append(OUString::Concat(templateName) + "['"); for (sal_Int32 i = 0; i < name.getLength(); ++i) { sal_Unicode c = name[i]; switch (c) { @@ -123,10 +124,14 @@ sal_Int32 Data::parseSegment( *setElement = false; return i; } - if (templateName != nullptr) { - if (i - index == 1 && path[index] == '*') { + if (i - index == 1 && path[index] == '*') { + *setElement = true; + if (templateName != nullptr) { templateName->clear(); - } else { + } + } else { + *setElement = i != index; + if (templateName != nullptr) { *templateName = path.copy(index, i - index); } } @@ -143,19 +148,18 @@ sal_Int32 Data::parseSegment( { return -1; } - *setElement = true; return j + 2; } OUString Data::fullTemplateName( - OUString const & component, OUString const & name) + std::u16string_view component, std::u16string_view name) { - if (component.indexOf(':') != -1 || name.indexOf(':') != -1) { + if (component.find(':') != std::u16string_view::npos || name.find(':') != std::u16string_view::npos) { throw css::uno::RuntimeException( - "bad component/name pair containing colon " + component + "/" + + OUString::Concat("bad component/name pair containing colon ") + component + "/" + name); } - return component + ":" + name; + return OUString::Concat(component) + ":" + name; } bool Data::equalTemplateNames( @@ -216,8 +220,7 @@ rtl::Reference< Node > Data::resolvePathRepresentation( return p; } if (canonicRepresentation != nullptr) { - canonic.append('/'); - canonic.append(createSegment(templateName, seg)); + canonic.append("/" + createSegment(templateName, seg)); } if (path != nullptr) { path->push_back(seg); diff --git a/configmgr/source/data.hxx b/configmgr/source/data.hxx index 9e1da0829679..c3614e6435da 100644 --- a/configmgr/source/data.hxx +++ b/configmgr/source/data.hxx @@ -58,7 +58,7 @@ struct Data { bool * setElement, OUString * templateName); static OUString fullTemplateName( - OUString const & component, OUString const & name); + std::u16string_view component, std::u16string_view name); //TODO: better rules under which circumstances a short template name matches static bool equalTemplateNames( diff --git a/configmgr/source/dconf.cxx b/configmgr/source/dconf.cxx index 9db51fa17cfb..c12f4a2814fd 100644 --- a/configmgr/source/dconf.cxx +++ b/configmgr/source/dconf.cxx @@ -16,14 +16,7 @@ #include <limits> #include <vector> -extern "C" { - //TODO: <https://bugzilla.gnome.org/show_bug.cgi?id=754245> - // "common/dconf-changeset.h etc. lack extern "C" wrapper for C++", fixed on current dconf - // master (towards 0.40?) now with - // <https://gitlab.gnome.org/GNOME/dconf/-/commit/db3d4df6d1a763698f27b013dc42da8d4ae02639> - // "Merge branch 'wip/issue-23' into 'master'" #include <dconf/dconf.h> -} #include <com/sun/star/uno/Sequence.hxx> #include <o3tl/safeint.hxx> @@ -221,7 +214,7 @@ private: }; OString getRoot() { - return "/org/libreoffice/registry"; + return "/org/libreoffice/registry"_ostr; } bool decode(OUString * string, bool slash) { @@ -980,7 +973,7 @@ void readDir( case ReadValue::Error: continue; case ReadValue::Value: - prop->setValue(layer, value); + prop->setValue(layer, value, false); finalize(client, path, member, layer); break; case ReadValue::Remove: @@ -1012,7 +1005,7 @@ void readDir( continue; } static_cast<LocalizedValueNode *>(member.get())->setValue( - layer, value); + layer, value, false); finalize(client, path, member, layer); break; } diff --git a/configmgr/source/groupnode.cxx b/configmgr/source/groupnode.cxx index eab65427c252..00934e9171e8 100644 --- a/configmgr/source/groupnode.cxx +++ b/configmgr/source/groupnode.cxx @@ -21,6 +21,7 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <utility> #include "data.hxx" #include "groupnode.hxx" @@ -30,8 +31,8 @@ namespace configmgr { GroupNode::GroupNode( - int layer, bool extensible, OUString const & templateName): - Node(layer), extensible_(extensible), templateName_(templateName), + int layer, bool extensible, OUString templateName): + Node(layer), extensible_(extensible), templateName_(std::move(templateName)), mandatory_(Data::NO_LAYER) {} diff --git a/configmgr/source/groupnode.hxx b/configmgr/source/groupnode.hxx index 12e18b37bc90..961ecc090622 100644 --- a/configmgr/source/groupnode.hxx +++ b/configmgr/source/groupnode.hxx @@ -32,7 +32,7 @@ namespace configmgr class GroupNode : public Node { public: - GroupNode(int layer, bool extensible, OUString const& templateName); + GroupNode(int layer, bool extensible, OUString templateName); virtual rtl::Reference<Node> clone(bool keepTemplateName) const override; diff --git a/configmgr/source/localizedvaluenode.cxx b/configmgr/source/localizedvaluenode.cxx index 6404ff7a06a7..407040a560c0 100644 --- a/configmgr/source/localizedvaluenode.cxx +++ b/configmgr/source/localizedvaluenode.cxx @@ -22,18 +22,19 @@ #include <com/sun/star/uno/Any.hxx> #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <utility> #include "localizedvaluenode.hxx" #include "node.hxx" namespace configmgr { -LocalizedValueNode::LocalizedValueNode(int layer, css::uno::Any const & value): - Node(layer), value_(value) +LocalizedValueNode::LocalizedValueNode(int layer, css::uno::Any value): + Node(layer), value_(std::move(value)), modified_(false) {} LocalizedValueNode::LocalizedValueNode(int layer): - Node(layer) + Node(layer), modified_(false) {} rtl::Reference< Node > LocalizedValueNode::clone(bool) const { @@ -45,9 +46,10 @@ OUString LocalizedValueNode::getTemplateName() const { } -void LocalizedValueNode::setValue(int layer, css::uno::Any const & value) +void LocalizedValueNode::setValue(int layer, css::uno::Any const & value, bool bIsUserModification) { setLayer(layer); + modified_ = bIsUserModification; if (&value != &value_) value_ = value; } diff --git a/configmgr/source/localizedvaluenode.hxx b/configmgr/source/localizedvaluenode.hxx index 34fe2815365a..305c82811f33 100644 --- a/configmgr/source/localizedvaluenode.hxx +++ b/configmgr/source/localizedvaluenode.hxx @@ -32,20 +32,23 @@ class LocalizedValueNode : public Node { public: explicit LocalizedValueNode(int layer); - LocalizedValueNode(int layer, css::uno::Any const& value); + LocalizedValueNode(int layer, css::uno::Any value); virtual rtl::Reference<Node> clone(bool keepTemplateName) const override; virtual OUString getTemplateName() const override; const css::uno::Any& getValue() const { return value_; } - css::uno::Any* getValuePtr(int layer) + css::uno::Any* getValuePtr(int layer, bool bIsUserModification) { setLayer(layer); + modified_ = bIsUserModification; return &value_; } - void setValue(int layer, css::uno::Any const& value); + void setValue(int layer, css::uno::Any const& value, bool bIsUserModification); + + bool isModified() { return modified_; } private: LocalizedValueNode(LocalizedValueNode const&) = default; @@ -55,6 +58,7 @@ private: virtual Kind kind() const override; css::uno::Any value_; + bool modified_; }; } diff --git a/configmgr/source/node.cxx b/configmgr/source/node.cxx index 8f00d3887da3..2c8c697b5338 100644 --- a/configmgr/source/node.cxx +++ b/configmgr/source/node.cxx @@ -59,7 +59,6 @@ void Node::setFinalized(int layer) { finalized_ = layer; } - rtl::Reference< Node > Node::getMember(OUString const & name) { NodeMap const & members = getMembers(); NodeMap::const_iterator i(members.find(name)); diff --git a/configmgr/source/node.hxx b/configmgr/source/node.hxx index b858c9e42e95..cce8e3d4abb3 100644 --- a/configmgr/source/node.hxx +++ b/configmgr/source/node.hxx @@ -23,7 +23,9 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> #include <salhelper/simplereferenceobject.hxx> +#include <xmlreader/span.hxx> namespace configmgr { @@ -51,6 +53,9 @@ public: void setFinalized(int layer); int getFinalized() const { return finalized_;} + void setDescription(OUString const& description) { description_ = description; }; + OUString getDescription() { return description_; } + rtl::Reference< Node > getMember(OUString const & name); protected: @@ -61,6 +66,7 @@ protected: private: int layer_; int finalized_; + OUString description_; }; } diff --git a/configmgr/source/propertynode.cxx b/configmgr/source/propertynode.cxx index 119bce5c9be3..6a9d2a6e2817 100644 --- a/configmgr/source/propertynode.cxx +++ b/configmgr/source/propertynode.cxx @@ -26,6 +26,7 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> #include <sal/log.hxx> +#include <utility> #include "components.hxx" #include "node.hxx" @@ -35,10 +36,10 @@ namespace configmgr { PropertyNode::PropertyNode( - int layer, Type staticType, bool nillable, css::uno::Any const & value, + int layer, Type staticType, bool nillable, css::uno::Any value, bool extension): Node(layer), staticType_(staticType), nillable_(nillable), - extension_(extension), value_(value) + extension_(extension), modified_(false), value_(std::move(value)) {} rtl::Reference< Node > PropertyNode::clone(bool) const { @@ -61,15 +62,18 @@ css::uno::Any const & PropertyNode::getValue(Components & components) { return value_; } -void PropertyNode::setValue(int layer, css::uno::Any const & value) { +void PropertyNode::setValue(int layer, css::uno::Any const & value, bool bIsUserModification) { setLayer(layer); value_ = value; + // Consider as modified when modified during runtime or by user registry modifications + modified_ = bIsUserModification; externalDescriptor_.clear(); } -css::uno::Any *PropertyNode::getValuePtr(int layer) +css::uno::Any *PropertyNode::getValuePtr(int layer, bool bIsUserModification) { setLayer(layer); + modified_ = bIsUserModification; externalDescriptor_.clear(); return &value_; } diff --git a/configmgr/source/propertynode.hxx b/configmgr/source/propertynode.hxx index 9a3f8f91e87e..db6fb926adbf 100644 --- a/configmgr/source/propertynode.hxx +++ b/configmgr/source/propertynode.hxx @@ -36,7 +36,7 @@ class PropertyNode: public Node { public: PropertyNode( int layer, Type staticType, bool nillable, - css::uno::Any const & value, bool extension); + css::uno::Any value, bool extension); virtual rtl::Reference< Node > clone(bool keepTemplateName) const override; @@ -46,13 +46,15 @@ public: css::uno::Any const & getValue(Components & components); - void setValue(int layer, css::uno::Any const & value); - css::uno::Any *getValuePtr(int layer); + void setValue(int layer, css::uno::Any const & value, bool bIsUserModification); + css::uno::Any *getValuePtr(int layer, bool bIsUserModification); void setExternal(int layer, OUString const & descriptor); bool isExtension() const { return extension_;} + bool isModified() const { return modified_;} + private: PropertyNode(PropertyNode const&) = default; @@ -65,6 +67,8 @@ private: // TYPE_HEXBINARY_LIST; not TYPE_ERROR or TYPE_NIL) bool nillable_; bool extension_; + /// Whether the property was modified by the user: + bool modified_; OUString externalDescriptor_; css::uno::Any value_; }; diff --git a/configmgr/source/readonlyaccess.cxx b/configmgr/source/readonlyaccess.cxx index 286963c783a2..c070e47f71ce 100644 --- a/configmgr/source/readonlyaccess.cxx +++ b/configmgr/source/readonlyaccess.cxx @@ -22,14 +22,15 @@ #include <cppuhelper/implbase.hxx> #include <cppuhelper/supportsservice.hxx> #include <cppuhelper/weak.hxx> -#include <osl/mutex.hxx> #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <utility> #include <sal/types.h> #include "components.hxx" #include "lock.hxx" #include "rootaccess.hxx" +#include <mutex> namespace configmgr::read_only_access { @@ -42,8 +43,8 @@ class Service: { public: explicit Service( - css::uno::Reference< css::uno::XComponentContext > const & context): - context_(context) {} + css::uno::Reference< css::uno::XComponentContext > context): + context_(std::move(context)) {} private: Service(const Service&) = delete; @@ -75,7 +76,7 @@ private: css::uno::Reference< css::uno::XComponentContext > context_; - osl::Mutex mutex_; + std::mutex mutex_; rtl::Reference< RootAccess > root_; }; @@ -85,12 +86,12 @@ void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments) if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) { throw css::lang::IllegalArgumentException( "not exactly one string argument", - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } - osl::MutexGuard g1(mutex_); + std::unique_lock g1(mutex_); if (root_.is()) { throw css::uno::RuntimeException( - "already initialized", static_cast< cppu::OWeakObject * >(this)); + "already initialized", getXWeak()); } osl::MutexGuard g2(*lock()); Components & components = Components::getSingleton(context_); @@ -99,10 +100,10 @@ void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments) } rtl::Reference< RootAccess > Service::getRoot() { - osl::MutexGuard g(mutex_); + std::unique_lock g(mutex_); if (!root_.is()) { throw css::lang::NotInitializedException( - "not initialized", static_cast< cppu::OWeakObject * >(this)); + "not initialized", getXWeak()); } return root_; } diff --git a/configmgr/source/readwriteaccess.cxx b/configmgr/source/readwriteaccess.cxx index 292124ddec25..18148b377c1d 100644 --- a/configmgr/source/readwriteaccess.cxx +++ b/configmgr/source/readwriteaccess.cxx @@ -22,9 +22,10 @@ #include <cppuhelper/implbase.hxx> #include <cppuhelper/supportsservice.hxx> #include <cppuhelper/weak.hxx> -#include <osl/mutex.hxx> #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <mutex> +#include <utility> #include <sal/types.h> #include "components.hxx" @@ -42,8 +43,8 @@ class Service: { public: explicit Service( - css::uno::Reference< css::uno::XComponentContext > const & context): - context_(context) {} + css::uno::Reference< css::uno::XComponentContext > context): + context_(std::move(context)) {} private: Service(const Service&) = delete; @@ -97,7 +98,7 @@ private: css::uno::Reference< css::uno::XComponentContext > context_; - osl::Mutex mutex_; + std::mutex mutex_; rtl::Reference< RootAccess > root_; }; @@ -107,12 +108,12 @@ void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments) if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) { throw css::lang::IllegalArgumentException( "not exactly one string argument", - static_cast< cppu::OWeakObject * >(this), -1); + getXWeak(), -1); } - osl::MutexGuard g1(mutex_); + std::unique_lock g1(mutex_); if (root_.is()) { throw css::uno::RuntimeException( - "already initialized", static_cast< cppu::OWeakObject * >(this)); + "already initialized", getXWeak()); } osl::MutexGuard g2(*lock()); Components & components = Components::getSingleton(context_); @@ -121,10 +122,10 @@ void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments) } rtl::Reference< RootAccess > Service::getRoot() { - osl::MutexGuard g(mutex_); + std::unique_lock g(mutex_); if (!root_.is()) { throw css::lang::NotInitializedException( - "not initialized", static_cast< cppu::OWeakObject * >(this)); + "not initialized", getXWeak()); } return root_; } diff --git a/configmgr/source/rootaccess.cxx b/configmgr/source/rootaccess.cxx index 17c8f7ec12a2..122401f6b068 100644 --- a/configmgr/source/rootaccess.cxx +++ b/configmgr/source/rootaccess.cxx @@ -20,6 +20,7 @@ #include <sal/config.h> #include <cassert> +#include <utility> #include <vector> #include <com/sun/star/lang/DisposedException.hpp> @@ -54,10 +55,10 @@ namespace configmgr { RootAccess::RootAccess( - Components & components, OUString const & pathRepresentation, - OUString const & locale, bool update): - Access(components), pathRepresentation_(pathRepresentation), - locale_(locale), + Components & components, OUString pathRepresentation, + OUString locale, bool update): + Access(components), pathRepresentation_(std::move(pathRepresentation)), + locale_(std::move(locale)), lock_( lock() ), update_(update), finalized_(false), alive_(true) { @@ -86,7 +87,7 @@ void RootAccess::initBroadcaster( broadcaster->addChangesNotification( changesListener, css::util::ChangesEvent( - pSource, css::uno::Any( xBase ), set)); + pSource, css::uno::Any( xBase ), set), path_.empty()); } } @@ -117,7 +118,7 @@ void RootAccess::addChangesListener( checkLocalizedPropertyAccess(); if (!aListener.is()) { throw css::uno::RuntimeException( - "null listener", static_cast< cppu::OWeakObject * >(this)); + "null listener", getXWeak()); } if (!isDisposed()) { changesListeners_.insert(aListener); @@ -126,7 +127,7 @@ void RootAccess::addChangesListener( } try { aListener->disposing( - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } catch (css::lang::DisposedException &) {} } @@ -203,7 +204,7 @@ OUString RootAccess::getRelativePathRepresentation() { return OUString(); } -rtl::Reference< Node > RootAccess::getNode() { +const rtl::Reference< Node > & RootAccess::getNode() { if (!node_.is()) { OUString canonic; int finalizedLayer; @@ -233,7 +234,7 @@ bool RootAccess::isFinalized() { return finalized_; } -OUString RootAccess::getNameInternal() { +const OUString & RootAccess::getNameInternal() { getNode(); return name_; } @@ -268,7 +269,7 @@ void RootAccess::initDisposeBroadcaster(Broadcaster * broadcaster) { { broadcaster->addDisposeNotification( changesListener, - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + css::lang::EventObject(getXWeak())); } Access::initDisposeBroadcaster(broadcaster); } diff --git a/configmgr/source/rootaccess.hxx b/configmgr/source/rootaccess.hxx index 11fbea450eed..a30975dd652d 100644 --- a/configmgr/source/rootaccess.hxx +++ b/configmgr/source/rootaccess.hxx @@ -53,8 +53,8 @@ class RootAccess: { public: RootAccess( - Components & components, OUString const & pathRepresentation, - OUString const & locale, bool update); + Components & components, OUString pathRepresentation, + OUString locale, bool update); virtual std::vector<OUString> getAbsolutePath() override; @@ -94,11 +94,11 @@ private: virtual OUString getRelativePathRepresentation() override; - virtual rtl::Reference< Node > getNode() override; + virtual const rtl::Reference< Node > & getNode() override; virtual bool isFinalized() override; - virtual OUString getNameInternal() override; + virtual const OUString & getNameInternal() override; virtual rtl::Reference< RootAccess > getRootAccess() override; diff --git a/configmgr/source/setnode.cxx b/configmgr/source/setnode.cxx index 2ba4c50be681..5e15ac31d61f 100644 --- a/configmgr/source/setnode.cxx +++ b/configmgr/source/setnode.cxx @@ -23,6 +23,7 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <utility> #include "data.hxx" #include "node.hxx" @@ -32,10 +33,10 @@ namespace configmgr { SetNode::SetNode( - int layer, OUString const & defaultTemplateName, - OUString const & templateName): - Node(layer), defaultTemplateName_(defaultTemplateName), - templateName_(templateName), mandatory_(Data::NO_LAYER) + int layer, OUString defaultTemplateName, + OUString templateName): + Node(layer), defaultTemplateName_(std::move(defaultTemplateName)), + templateName_(std::move(templateName)), mandatory_(Data::NO_LAYER) {} rtl::Reference< Node > SetNode::clone(bool keepTemplateName) const { diff --git a/configmgr/source/setnode.hxx b/configmgr/source/setnode.hxx index 1a8f44132940..706d153daf6f 100644 --- a/configmgr/source/setnode.hxx +++ b/configmgr/source/setnode.hxx @@ -34,8 +34,8 @@ namespace configmgr { class SetNode: public Node { public: SetNode( - int layer, OUString const & defaultTemplateName, - OUString const & templateName); + int layer, OUString defaultTemplateName, + OUString templateName); virtual rtl::Reference< Node > clone(bool keepTemplateName) const override; diff --git a/configmgr/source/update.cxx b/configmgr/source/update.cxx index 1cc2a06fe2a2..5851a6af05a3 100644 --- a/configmgr/source/update.cxx +++ b/configmgr/source/update.cxx @@ -23,10 +23,12 @@ #include <set> #include <com/sun/star/configuration/XUpdate.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/uno/XInterface.hpp> #include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> #include <cppuhelper/weak.hxx> #include <osl/mutex.hxx> #include <rtl/ref.hxx> @@ -50,7 +52,7 @@ std::set< OUString > seqToSet( } class Service: - public cppu::WeakImplHelper< css::configuration::XUpdate > + public cppu::WeakImplHelper< css::configuration::XUpdate, css::lang::XServiceInfo > { public: explicit Service(const css::uno::Reference< css::uno::XComponentContext >& context): @@ -79,6 +81,18 @@ private: css::uno::Sequence< OUString > const & includedPaths, css::uno::Sequence< OUString > const & excludedPaths) override; + OUString SAL_CALL getImplementationName() override { + return "com.sun.star.comp.configuration.Update"; + } + + sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override { + return cppu::supportsService(this, ServiceName); + } + + css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override { + return {"com.sun.star.configuration.Update_Service"}; + } + std::shared_ptr<osl::Mutex> lock_; css::uno::Reference< css::uno::XComponentContext > context_; }; diff --git a/configmgr/source/valueparser.cxx b/configmgr/source/valueparser.cxx index 82778e6c823b..83ddd245dc06 100644 --- a/configmgr/source/valueparser.cxx +++ b/configmgr/source/valueparser.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/uno/RuntimeException.hpp> #include <com/sun/star/uno/Sequence.hxx> #include <comphelper/sequence.hxx> +#include <o3tl/string_view.hxx> #include <rtl/math.h> #include <rtl/string.h> #include <rtl/string.hxx> @@ -33,6 +34,7 @@ #include <xmlreader/span.hxx> #include <xmlreader/xmlreader.hxx> +#include "data.hxx" #include "localizedvaluenode.hxx" #include "node.hxx" #include "nodemap.hxx" @@ -78,16 +80,21 @@ bool parseValue(xmlreader::Span const & text, sal_Bool * value) { bool parseValue(xmlreader::Span const & text, sal_Int16 * value) { assert(text.is() && value != nullptr); // For backwards compatibility, support hexadecimal values: - sal_Int32 n = + bool bStartWithHexPrefix = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( text.begin, text.length, RTL_CONSTASCII_STRINGPARAM("0X"), - RTL_CONSTASCII_LENGTH("0X")) == 0 ? - static_cast< sal_Int32 >( - OString( + RTL_CONSTASCII_LENGTH("0X")) == 0; + sal_Int32 n; + if (bStartWithHexPrefix) + { + std::string_view sView( text.begin + RTL_CONSTASCII_LENGTH("0X"), - text.length - RTL_CONSTASCII_LENGTH("0X")).toUInt32(16)) : - OString(text.begin, text.length).toInt32(); - //TODO: check valid lexical representation + text.length - RTL_CONSTASCII_LENGTH("0X")); + n = o3tl::toUInt32(sView, 16); + } + else + n = o3tl::toInt32(std::string_view(text.begin, text.length)); + //TODO: check valid lexical representation if (n >= SAL_MIN_INT16 && n <= SAL_MAX_INT16) { *value = static_cast< sal_Int16 >(n); return true; @@ -98,32 +105,41 @@ bool parseValue(xmlreader::Span const & text, sal_Int16 * value) { bool parseValue(xmlreader::Span const & text, sal_Int32 * value) { assert(text.is() && value != nullptr); // For backwards compatibility, support hexadecimal values: - *value = - rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + bool bStartWithHexPrefix = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( text.begin, text.length, RTL_CONSTASCII_STRINGPARAM("0X"), - RTL_CONSTASCII_LENGTH("0X")) == 0 ? - static_cast< sal_Int32 >( - OString( - text.begin + RTL_CONSTASCII_LENGTH("0X"), - text.length - RTL_CONSTASCII_LENGTH("0X")).toUInt32(16)) : - OString(text.begin, text.length).toInt32(); - //TODO: check valid lexical representation + RTL_CONSTASCII_LENGTH("0X")) == 0; + + if (bStartWithHexPrefix) + { + std::string_view sView(text.begin + RTL_CONSTASCII_LENGTH("0X"), + text.length - RTL_CONSTASCII_LENGTH("0X")); + *value = static_cast< sal_Int32 >(o3tl::toUInt32(sView, 16)); + } + else + { + std::string_view sView(text.begin, text.length); + *value = o3tl::toInt32(sView); + } + //TODO: check valid lexical representation return true; } bool parseValue(xmlreader::Span const & text, sal_Int64 * value) { assert(text.is() && value != nullptr); // For backwards compatibility, support hexadecimal values: - *value = + bool bStartWithHexPrefix = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( text.begin, text.length, RTL_CONSTASCII_STRINGPARAM("0X"), - RTL_CONSTASCII_LENGTH("0X")) == 0 ? - static_cast< sal_Int64 >( - OString( + RTL_CONSTASCII_LENGTH("0X")) == 0; + if (bStartWithHexPrefix) + { + OString sSuffix( text.begin + RTL_CONSTASCII_LENGTH("0X"), - text.length - RTL_CONSTASCII_LENGTH("0X")).toUInt64(16)) : - OString(text.begin, text.length).toInt64(); - //TODO: check valid lexical representation + text.length - RTL_CONSTASCII_LENGTH("0X")); + *value = static_cast< sal_Int64 >(sSuffix.toUInt64(16)); + } + else *value = o3tl::toInt64(std::string_view(text.begin, text.length)); + //TODO: check valid lexical representation return true; } @@ -347,21 +363,20 @@ bool ValueParser::endElement() { switch (node_->kind()) { case Node::KIND_PROPERTY: - pValue = static_cast< PropertyNode * >(node_.get())->getValuePtr(layer_); + pValue = static_cast< PropertyNode * >(node_.get())->getValuePtr(layer_, layer_ == Data::NO_LAYER); break; case Node::KIND_LOCALIZED_PROPERTY: { NodeMap & members = node_->getMembers(); - NodeMap::iterator i(members.find(localizedName_)); + auto [i, bInserted] = members.insert(NodeMap::value_type(localizedName_, nullptr)); LocalizedValueNode *pLVNode; - if (i == members.end()) { + if (bInserted) { pLVNode = new LocalizedValueNode(layer_); - members.insert( - NodeMap::value_type(localizedName_, pLVNode )); + i->second = pLVNode; } else { pLVNode = static_cast< LocalizedValueNode * >(i->second.get()); } - pValue = pLVNode->getValuePtr(layer_); + pValue = pLVNode->getValuePtr(layer_, layer_ == Data::NO_LAYER); } break; default: diff --git a/configmgr/source/winreg.cxx b/configmgr/source/winreg.cxx index 381150fc2d5e..0e90752d4d6d 100644 --- a/configmgr/source/winreg.cxx +++ b/configmgr/source/winreg.cxx @@ -238,7 +238,7 @@ void dumpWindowsRegistryKey(HKEY hKey, OUString const & aKeyName, TempFile &aFil else { writeAttributeValue( - aFileHandle, OUStringConcatenation("/" + aNextPathPart)); + aFileHandle, Concat2View("/" + aNextPathPart)); } } else diff --git a/configmgr/source/writemodfile.cxx b/configmgr/source/writemodfile.cxx index 09fe0949b0e9..3e7e281eb6aa 100644 --- a/configmgr/source/writemodfile.cxx +++ b/configmgr/source/writemodfile.cxx @@ -209,7 +209,7 @@ template< typename T > void writeListValue( if (i != 0) { handle.writeString(" "); } - writeValueContent_(handle, std::as_const(val)[i]); + writeValueContent_(handle, val[i]); } handle.writeString("</value>"); } @@ -220,7 +220,7 @@ template< typename T > void writeItemListValue( handle.writeString(">"); css::uno::Sequence< T > val; value >>= val; - for (const auto & i : std::as_const(val)) { + for (const auto & i : val) { handle.writeString("<it>"); writeValueContent_(handle, i); handle.writeString("</it>"); diff --git a/configmgr/source/xcsparser.cxx b/configmgr/source/xcsparser.cxx index 947792c0a62e..35f61fa1959e 100644 --- a/configmgr/source/xcsparser.cxx +++ b/configmgr/source/xcsparser.cxx @@ -109,12 +109,14 @@ void merge( } XcsParser::XcsParser(int layer, Data & data): - valueParser_(layer), data_(data), state_(STATE_START), ignoring_() + valueParser_(layer), data_(data), state_(STATE_START), ignoring_(), bIsParsingInfo_(false) {} XcsParser::~XcsParser() {} xmlreader::XmlReader::Text XcsParser::getTextMode() { + if (bIsParsingInfo_) + return xmlreader::XmlReader::Text::Raw; return valueParser_.getTextMode(); } @@ -122,6 +124,22 @@ bool XcsParser::startElement( xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name, std::set< OUString > const * /*existingDependencies*/) { + //TODO: ignoring component-schema import, component-schema uses, and + // prop constraints; accepting all four at illegal places (and with + // illegal content): + if (ignoring_ > 0 + || (nsId == xmlreader::XmlReader::NAMESPACE_NONE + && (name == "import" || name == "uses" || name == "constraints" || name == "desc" + // the following are unused by LO but valid + || name == "deprecated" || name == "author" || name == "label"))) + { + assert(ignoring_ < LONG_MAX); + ++ignoring_; + return true; + } + + if (bIsParsingInfo_) + return true; if (valueParser_.startElement(reader, nsId, name)) { return true; } @@ -135,18 +153,6 @@ bool XcsParser::startElement( return true; } } else { - //TODO: ignoring component-schema import, component-schema uses, and - // prop constraints; accepting all four at illegal places (and with - // illegal content): - if (ignoring_ > 0 || - (nsId == xmlreader::XmlReader::NAMESPACE_NONE && - (name == "info" || name == "import" || - name == "uses" || name == "constraints"))) - { - assert(ignoring_ < LONG_MAX); - ++ignoring_; - return true; - } switch (state_) { case STATE_COMPONENT_SCHEMA: if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && @@ -155,6 +161,12 @@ bool XcsParser::startElement( state_ = STATE_TEMPLATES; return true; } + if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && + name == "info") + { + bIsParsingInfo_ = true; + return true; + } [[fallthrough]]; case STATE_TEMPLATES_DONE: if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && @@ -170,6 +182,12 @@ bool XcsParser::startElement( } break; case STATE_TEMPLATES: + if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && + name == "info") + { + bIsParsingInfo_ = true; + return true; + } if (elements_.empty()) { if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && name == "group") @@ -183,6 +201,12 @@ bool XcsParser::startElement( handleSet(reader, true); return true; } + if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && + name == "info") + { + bIsParsingInfo_ = true; + return true; + } break; } [[fallthrough]]; @@ -197,6 +221,12 @@ bool XcsParser::startElement( handlePropValue(reader, elements_.top().node); return true; } + if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && + name == "info") + { + bIsParsingInfo_ = true; + return true; + } break; case Node::KIND_GROUP: if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && @@ -223,6 +253,12 @@ bool XcsParser::startElement( handleSet(reader, false); return true; } + if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && + name == "info") + { + bIsParsingInfo_ = true; + return true; + } break; case Node::KIND_SET: if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && @@ -233,6 +269,12 @@ bool XcsParser::startElement( static_cast< SetNode * >(elements_.top().node.get())); return true; } + if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && + name == "info") + { + bIsParsingInfo_ = true; + return true; + } break; default: // Node::KIND_LOCALIZED_VALUE assert(false); // this cannot happen @@ -251,15 +293,32 @@ bool XcsParser::startElement( } void XcsParser::endElement(xmlreader::XmlReader const & reader) { + if (ignoring_ > 0) { + --ignoring_; + return; + } + if (bIsParsingInfo_) + { + bIsParsingInfo_ = false; + return; + } if (valueParser_.endElement()) { return; } - if (ignoring_ > 0) { - --ignoring_; - } else if (!elements_.empty()) { + if (!elements_.empty()) { Element top(std::move(elements_.top())); elements_.pop(); if (top.node.is()) { + if (top.node->kind() == Node::KIND_PROPERTY + || top.node->kind() == Node::KIND_LOCALIZED_PROPERTY) + { + // Remove whitespace from description_ resulting from line breaks/indentation in xml files + OUString desc(description_.makeStringAndClear()); + desc = desc.trim(); + while (desc.indexOf(" ") != -1) + desc = desc.replaceAll(" ", " "); + top.node->setDescription(desc); + } if (elements_.empty()) { switch (state_) { case STATE_TEMPLATES: @@ -316,6 +375,11 @@ void XcsParser::endElement(xmlreader::XmlReader const & reader) { } void XcsParser::characters(xmlreader::Span const & text) { + if (bIsParsingInfo_) + { + description_.append(text.convertFromUtf8()); + return; + } valueParser_.characters(text); } diff --git a/configmgr/source/xcsparser.hxx b/configmgr/source/xcsparser.hxx index 36e5a1a0037a..aedcccde1147 100644 --- a/configmgr/source/xcsparser.hxx +++ b/configmgr/source/xcsparser.hxx @@ -26,6 +26,7 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <utility> #include <xmlreader/xmlreader.hxx> #include "node.hxx" @@ -80,9 +81,9 @@ private: OUString name; Element( - rtl::Reference< Node > const & theNode, - OUString const & theName): - node(theNode), name(theName) {} + rtl::Reference< Node > theNode, + OUString theName): + node(std::move(theNode)), name(std::move(theName)) {} }; typedef std::stack< Element > ElementStack; @@ -93,6 +94,8 @@ private: State state_; long ignoring_; ElementStack elements_; + bool bIsParsingInfo_; + OUStringBuffer description_; }; } diff --git a/configmgr/source/xcuparser.cxx b/configmgr/source/xcuparser.cxx index af21518abd78..b54e7aa95f01 100644 --- a/configmgr/source/xcuparser.cxx +++ b/configmgr/source/xcuparser.cxx @@ -427,7 +427,7 @@ void XcuParser::handlePropValue( "xsi:nil and oor:external attributes for prop in " + reader.getUrl()); } - prop->setValue(valueParser_.getLayer(), css::uno::Any()); + prop->setValue(valueParser_.getLayer(), css::uno::Any(), valueParser_.getLayer() == Data::NO_LAYER); state_.push(State::Ignore(false)); } else if (external.isEmpty()) { valueParser_.separator_ = separator; @@ -514,7 +514,7 @@ void XcuParser::handleLocpropValue( } else { static_cast< LocalizedValueNode * >( i->second.get())->setValue( - valueParser_.getLayer(), css::uno::Any()); + valueParser_.getLayer(), css::uno::Any(), valueParser_.getLayer() == Data::NO_LAYER); } state_.push(State::Ignore(true)); } else { diff --git a/configmgr/source/xcuparser.hxx b/configmgr/source/xcuparser.hxx index cf6fb3e91b2d..e50b7b5a0fc8 100644 --- a/configmgr/source/xcuparser.hxx +++ b/configmgr/source/xcuparser.hxx @@ -27,6 +27,7 @@ #include <rtl/ref.hxx> #include <rtl/ustring.hxx> +#include <utility> #include <xmlreader/xmlreader.hxx> #include "additions.hxx" @@ -124,13 +125,13 @@ private: private: explicit State(bool thePop): ignore(true), insert(false), pop(thePop) {} - explicit State(rtl::Reference< Node > const & theNode): - node(theNode), ignore(false), insert(false), pop(true) + explicit State(rtl::Reference< Node > theNode): + node(std::move(theNode)), ignore(false), insert(false), pop(true) {} State( - rtl::Reference< Node > const & theNode, OUString const & theName): - node(theNode), name(theName), ignore(false), insert(true), pop(true) + rtl::Reference< Node > theNode, OUString theName): + node(std::move(theNode)), name(std::move(theName)), ignore(false), insert(true), pop(true) {} }; diff --git a/configmgr/source/xmldata.cxx b/configmgr/source/xmldata.cxx index a2a05877674e..ecb4dacab41f 100644 --- a/configmgr/source/xmldata.cxx +++ b/configmgr/source/xmldata.cxx @@ -115,8 +115,8 @@ bool parseBoolean(xmlreader::Span const & text) { } OUString parseTemplateReference( - OUString const & component, bool hasNodeType, - OUString const & nodeType, OUString const * defaultTemplateName) + std::u16string_view component, bool hasNodeType, + std::u16string_view nodeType, OUString const * defaultTemplateName) { if (!hasNodeType) { if (defaultTemplateName != nullptr) { diff --git a/configmgr/source/xmldata.hxx b/configmgr/source/xmldata.hxx index c72050af84ce..44296b38d58d 100644 --- a/configmgr/source/xmldata.hxx +++ b/configmgr/source/xmldata.hxx @@ -38,8 +38,8 @@ Type parseType( bool parseBoolean(xmlreader::Span const & text); OUString parseTemplateReference( - OUString const & component, bool hasNodeType, - OUString const & nodeType, OUString const * defaultTemplateName); + std::u16string_view component, bool hasNodeType, + std::u16string_view nodeType, OUString const * defaultTemplateName); } |