diff options
Diffstat (limited to 'configmgr/source/access.cxx')
-rw-r--r-- | configmgr/source/access.cxx | 424 |
1 files changed, 261 insertions, 163 deletions
diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx index 0308a0361761..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> @@ -57,7 +59,6 @@ #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XSingleServiceFactory.hpp> #include <com/sun/star/lang/XTypeProvider.hpp> -#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/uno/Any.hxx> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/RuntimeException.hpp> @@ -66,7 +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: @@ -173,19 +178,19 @@ css::uno::Sequence< css::uno::Type > Access::getTypes() assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - std::vector< css::uno::Type > types; - types.push_back(cppu::UnoType< css::uno::XInterface >::get()); - types.push_back(cppu::UnoType< css::uno::XWeak >::get()); - types.push_back(cppu::UnoType< css::lang::XTypeProvider >::get()); - types.push_back(cppu::UnoType< css::lang::XServiceInfo >::get()); - types.push_back(cppu::UnoType< css::lang::XComponent >::get()); - types.push_back(cppu::UnoType< css::container::XContainer >::get()); - types.push_back(cppu::UnoType< css::beans::XExactName >::get()); - types.push_back(cppu::UnoType< css::container::XHierarchicalName >::get()); - types.push_back(cppu::UnoType< css::container::XNamed >::get()); - types.push_back(cppu::UnoType< css::beans::XProperty >::get()); - types.push_back(cppu::UnoType< css::container::XElementAccess >::get()); - types.push_back(cppu::UnoType< css::container::XNameAccess >::get()); + std::vector< css::uno::Type > types { cppu::UnoType< css::uno::XInterface >::get(), + cppu::UnoType< css::uno::XWeak >::get(), + cppu::UnoType< css::lang::XTypeProvider >::get(), + cppu::UnoType< css::lang::XServiceInfo >::get(), + cppu::UnoType< css::lang::XComponent >::get(), + cppu::UnoType< css::container::XContainer >::get(), + cppu::UnoType< css::beans::XExactName >::get(), + cppu::UnoType< css::container::XHierarchicalName >::get(), + cppu::UnoType< css::container::XNamed >::get(), + cppu::UnoType< css::beans::XProperty >::get(), + cppu::UnoType< css::container::XElementAccess >::get(), + cppu::UnoType< css::container::XNameAccess >::get() + }; if (getNode()->kind() == Node::KIND_GROUP) { types.push_back(cppu::UnoType< css::beans::XPropertySetInfo >::get()); types.push_back(cppu::UnoType< css::beans::XPropertySet >::get()); @@ -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); @@ -855,13 +917,13 @@ css::uno::Sequence< css::uno::Any > Access::getPropertyValues( assert(thisIs(IS_GROUP)); osl::MutexGuard g(*lock_); css::uno::Sequence< css::uno::Any > vals(aPropertyNames.getLength()); - + auto aValsRange = asNonConstRange(vals); for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i) { - if (!getByNameFast(aPropertyNames[i], vals[i])) + 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 &) {} } @@ -911,11 +973,12 @@ void Access::firePropertiesChangeEvent( assert(thisIs(IS_GROUP)); css::uno::Sequence< css::beans::PropertyChangeEvent > events( aPropertyNames.getLength()); + auto aEventsRange = asNonConstRange(events); for (sal_Int32 i = 0; i < events.getLength(); ++i) { - events[i].Source = static_cast< cppu::OWeakObject * >(this); - events[i].PropertyName = aPropertyNames[i]; - events[i].Further = false; - events[i].PropertyHandle = -1; + aEventsRange[i].Source = getXWeak(); + aEventsRange[i].PropertyName = aPropertyNames[i]; + aEventsRange[i].Further = false; + aEventsRange[i].PropertyHandle = -1; } xListener->propertiesChange(events); } @@ -937,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; @@ -963,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(); } @@ -979,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) { @@ -995,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); @@ -1012,6 +1075,7 @@ css::uno::Sequence< css::uno::Any > Access::getHierarchicalPropertyValues( osl::MutexGuard g(*lock_); css::uno::Sequence< css::uno::Any > vals( aHierarchicalPropertyNames.getLength()); + auto aValsRange = asNonConstRange(vals); for (sal_Int32 i = 0; i < aHierarchicalPropertyNames.getLength(); ++i) { rtl::Reference< ChildAccess > child( getSubChild(aHierarchicalPropertyNames[i])); @@ -1019,9 +1083,9 @@ 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); } - vals[i] = child->asValue(); + aValsRange[i] = child->asValue(); } return vals; } @@ -1034,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(); } @@ -1058,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; @@ -1098,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; @@ -1113,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( @@ -1129,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)); @@ -1159,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; @@ -1191,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)); } @@ -1207,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(); } @@ -1225,22 +1289,22 @@ 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.get(), - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + containerListener, + css::lang::EventObject(getXWeak())); } for (auto const& propertyChangeListener : propertyChangeListeners_) { for (auto const& propertyChangeListenerElement : propertyChangeListener.second) { broadcaster->addDisposeNotification( - propertyChangeListenerElement.get(), + propertyChangeListenerElement, css::lang::EventObject( - static_cast< cppu::OWeakObject * >(this))); + getXWeak())); } } for (auto const& vetoableChangeListener : vetoableChangeListeners_) @@ -1248,16 +1312,16 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { for (auto const& vetoableChangeListenerElement : vetoableChangeListener.second) { broadcaster->addDisposeNotification( - vetoableChangeListenerElement.get(), + vetoableChangeListenerElement, css::lang::EventObject( - static_cast< cppu::OWeakObject * >(this))); + getXWeak())); } } for (auto const& propertiesChangeListener : propertiesChangeListeners_) { broadcaster->addDisposeNotification( - propertiesChangeListener.get(), - css::lang::EventObject(static_cast< cppu::OWeakObject * >(this))); + propertiesChangeListener, + css::lang::EventObject(getXWeak())); } //TODO: iterate over children w/ listeners (incl. unmodified ones): for (ModifiedChildren::iterator i(modifiedChildren_.begin()); @@ -1270,7 +1334,7 @@ void Access::initDisposeBroadcaster(Broadcaster * broadcaster) { } } -void Access::clearListeners() throw() { +void Access::clearListeners() noexcept { disposeListeners_.clear(); containerListeners_.clear(); propertyChangeListeners_.clear(); @@ -1298,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), @@ -1351,7 +1416,7 @@ void Access::checkLocalizedPropertyAccess() { { throw css::uno::RuntimeException( "configmgr Access to specialized LocalizedPropertyNode", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } } @@ -1373,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")); @@ -1385,8 +1450,24 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { locale = comphelper::LibreOfficeKit::getLanguageTag().getBcp47(); if (!locale.isEmpty()) { - // Find the best match using the LanguageTag fallback mechanism - std::vector<OUString> aFallbacks = LanguageTag(locale).getFallbackStrings(true); + // Try exact match first, avoiding all fallback overhead. + rtl::Reference<ChildAccess> directChild(getChild(locale)); + 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 = aLanguageTag.getFallbackStrings(false); for (const OUString& rFallback : aFallbacks) { rtl::Reference<ChildAccess> child(getChild(rFallback)); @@ -1398,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): - assert(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: @@ -1433,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 >(); @@ -1445,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()); @@ -1460,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) { @@ -1496,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); } } @@ -1613,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 @@ -1627,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())); } @@ -1640,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())); } @@ -1656,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()); } @@ -1671,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 @@ -1693,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 @@ -1707,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())); } @@ -1719,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())); } @@ -1734,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()); } @@ -1750,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())); } @@ -1787,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 @@ -1797,7 +1900,7 @@ void Access::initBroadcasterAndChanges( if (!path.isEmpty()) { path.append('/'); } - path.append(Data::createSegment("*", i.first)); + path.append(Data::createSegment(u"*", i.first)); allChanges->push_back( css::util::ElementChange( css::uno::Any(path.makeStringAndClear()), @@ -1814,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 @@ -1827,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())); } @@ -1839,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())); } @@ -1859,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()); } @@ -1873,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 @@ -1884,7 +1987,7 @@ void Access::initBroadcasterAndChanges( if (!path.isEmpty()) { path.append('/'); } - path.append(Data::createSegment("*", i.first)); + path.append(Data::createSegment(u"*", i.first)); allChanges->push_back( css::util::ElementChange( css::uno::Any(path.makeStringAndClear()), @@ -1916,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( @@ -2008,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()) || @@ -2060,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: { @@ -2108,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 } @@ -2116,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); } } @@ -2144,27 +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; - css::uno::Reference< css::lang::XUnoTunnel > tunnel; - value >>= tunnel; - if (tunnel.is()) { - freeAcc.set( - reinterpret_cast< ChildAccess * >( - tunnel->getSomething(ChildAccess::getTunnelId()))); - } + 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( @@ -2172,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; } @@ -2190,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) && |