diff options
Diffstat (limited to 'configmgr/source/access.cxx')
-rw-r--r-- | configmgr/source/access.cxx | 368 |
1 files changed, 233 insertions, 135 deletions
diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx index dc16b0211ade..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,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> @@ -82,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" @@ -107,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 == '/')) @@ -117,7 +121,7 @@ bool isValidName(OUString const & name, bool setMember) { return false; } } - return !name.isEmpty(); + return !name.empty(); } } @@ -131,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: @@ -215,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); @@ -280,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; @@ -301,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); @@ -310,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 &) {} } @@ -330,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( @@ -345,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()); } } @@ -353,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) @@ -400,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; } @@ -409,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) @@ -435,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)); @@ -460,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()); @@ -475,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; @@ -499,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); @@ -508,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 &) {} } @@ -536,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); } @@ -553,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(); } @@ -594,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()) { @@ -626,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)); @@ -669,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; @@ -703,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); } @@ -723,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; } @@ -737,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_) { @@ -747,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 &) {} } @@ -782,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_) { @@ -793,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 &) {} } @@ -829,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); @@ -856,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; @@ -878,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); @@ -887,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 &) {} } @@ -912,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); } @@ -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); @@ -1013,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])); @@ -1020,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; } @@ -1035,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(); } @@ -1059,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; @@ -1099,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; @@ -1114,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( @@ -1130,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)); @@ -1160,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; @@ -1192,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)); } @@ -1208,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(); } @@ -1226,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_) { @@ -1241,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_) @@ -1251,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()); @@ -1299,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), @@ -1352,7 +1416,7 @@ void Access::checkLocalizedPropertyAccess() { { throw css::uno::RuntimeException( "configmgr Access to specialized LocalizedPropertyNode", - static_cast< cppu::OWeakObject * >(this)); + getXWeak()); } } @@ -1374,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")); @@ -1391,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)); @@ -1405,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: @@ -1440,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 >(); @@ -1452,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()); @@ -1467,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) { @@ -1503,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); } } @@ -1620,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 @@ -1634,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())); } @@ -1647,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())); } @@ -1663,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()); } @@ -1678,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 @@ -1700,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 @@ -1714,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())); } @@ -1726,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())); } @@ -1741,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()); } @@ -1757,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())); } @@ -1794,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 @@ -1821,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 @@ -1834,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())); } @@ -1846,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())); } @@ -1866,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()); } @@ -1880,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 @@ -1923,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( @@ -2015,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()) || @@ -2067,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: { @@ -2115,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 } @@ -2123,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); } } @@ -2151,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( @@ -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) && |