From 84f4f7f99f92c0ecec0dd9d754fdfa8c652a7ec0 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Sat, 24 Jul 2021 19:01:52 +0200 Subject: simplify SvFontSubst in the process, needed to expose some functionality in ConfigManager and ConfigItem, to avoid repeating code Change-Id: Ic0256a010070a79cd649dfd11267bec2f77e5221 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119470 Tested-by: Jenkins Reviewed-by: Noel Grandin --- unotools/source/config/configitem.cxx | 434 +++++++++++++++++++++------------- unotools/source/config/configmgr.cxx | 13 + 2 files changed, 284 insertions(+), 163 deletions(-) (limited to 'unotools') diff --git a/unotools/source/config/configitem.cxx b/unotools/source/config/configitem.cxx index 60ded67dc837..28c4159e21ad 100644 --- a/unotools/source/config/configitem.cxx +++ b/unotools/source/config/configitem.cxx @@ -172,9 +172,7 @@ void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& const Sequence< Any >& lInValues , Sequence< Any >& lOutValues ) { - // Safe impossible cases. - // This method should be called for special ConfigItem-mode only! - OSL_ENSURE( ((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales), "ConfigItem::impl_packLocalizedProperties() Wrong call of this method detected!" ); + // This method should be called for special AllLocales ConfigItem-mode only! sal_Int32 nSourceCounter; // used to step during input lists sal_Int32 nSourceSize; // marks end of loop over input lists @@ -238,11 +236,9 @@ void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& void ConfigItem::impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames , const Sequence< Any >& lInValues , Sequence< OUString >& lOutNames , - Sequence< Any >& lOutValues ) + Sequence< Any >& lOutValues) { - // Safe impossible cases. - // This method should be called for special ConfigItem-mode only! - OSL_ENSURE( ((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales), "ConfigItem::impl_unpackLocalizedProperties() Wrong call of this method detected!" ); + // This method should be called for special AllLocales ConfigItem-mode only! sal_Int32 nSourceSize; // marks end of loop over input lists sal_Int32 nDestinationCounter; // actual position in output lists @@ -388,36 +384,43 @@ Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const css::uno::Sequence< OUS } Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames) +{ + Reference xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + return GetProperties(xHierarchyAccess, rNames, + (m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales); + return Sequence< Any >(rNames.getLength()); +} + +Sequence< Any > ConfigItem::GetProperties( + css::uno::Reference const & xHierarchyAccess, + const Sequence< OUString >& rNames, + bool bAllLocales) { Sequence< Any > aRet(rNames.getLength()); const OUString* pNames = rNames.getConstArray(); Any* pRet = aRet.getArray(); - Reference xHierarchyAccess = GetTree(); - if(xHierarchyAccess.is()) + for(int i = 0; i < rNames.getLength(); i++) { - for(int i = 0; i < rNames.getLength(); i++) + try { - try - { - pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]); - } - catch (const Exception&) - { - TOOLS_WARN_EXCEPTION( - "unotools.config", - "ignoring XHierarchicalNameAccess to /org.openoffice." - << sSubTree << "/" << pNames[i]); - } + pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]); } - - // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >. - if((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales) + catch (const Exception&) { - Sequence< Any > lValues; - impl_packLocalizedProperties( rNames, aRet, lValues ); - aRet = lValues; + TOOLS_WARN_EXCEPTION( + "unotools.config", + "ignoring XHierarchicalNameAccess " << pNames[i]); } } + + // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >. + if(bAllLocales) + { + Sequence< Any > lValues; + impl_packLocalizedProperties( rNames, aRet, lValues ); + aRet = lValues; + } return aRet; } @@ -501,6 +504,87 @@ bool ConfigItem::PutProperties( const Sequence< OUString >& rNames, return bRet; } +bool ConfigItem::PutProperties( + css::uno::Reference const & xHierarchyAccess, + const Sequence< OUString >& rNames, + const Sequence< Any>& rValues, + bool bAllLocales) +{ + Reference xTopNodeReplace(xHierarchyAccess, UNO_QUERY); + bool bRet = xTopNodeReplace.is(); + if(bRet) + { + Sequence< OUString > lNames; + Sequence< Any > lValues; + const OUString* pNames = nullptr; + const Any* pValues = nullptr; + sal_Int32 nNameCount; + if(bAllLocales) + { + // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue > + // as value of a localized configuration entry! + // How we can do that? + // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"! + impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues ); + pNames = lNames.getConstArray (); + pValues = lValues.getConstArray (); + nNameCount = lNames.getLength (); + } + else + { + // This is the normal mode ... + // Use given input lists directly. + pNames = rNames.getConstArray (); + pValues = rValues.getConstArray (); + nNameCount = rNames.getLength (); + } + for(int i = 0; i < nNameCount; i++) + { + try + { + OUString sNode, sProperty; + if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty)) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(sNode); + + Reference xNodeAcc; + aNode >>= xNodeAcc; + Reference xNodeReplace(xNodeAcc, UNO_QUERY); + Reference xNodeCont (xNodeAcc, UNO_QUERY); + + bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty)); + if (bExist && xNodeReplace.is()) + xNodeReplace->replaceByName(sProperty, pValues[i]); + else + if (!bExist && xNodeCont.is()) + xNodeCont->insertByName(sProperty, pValues[i]); + else + bRet = false; + } + else //direct value + { + xTopNodeReplace->replaceByName(sProperty, pValues[i]); + } + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from PutProperties"); + } + } + try + { + Reference xBatch(xHierarchyAccess, UNO_QUERY); + xBatch->commitChanges(); + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + } + } + + return bRet; +} + void ConfigItem::DisableNotification() { OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" ); @@ -597,31 +681,38 @@ Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode) Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat) { - Sequence< OUString > aRet; Reference xHierarchyAccess = GetTree(); if(xHierarchyAccess.is()) + return GetNodeNames(xHierarchyAccess, rNode, eFormat); + return Sequence< OUString >(); +} + +Sequence< OUString > ConfigItem::GetNodeNames( + css::uno::Reference const & xHierarchyAccess, + const OUString& rNode, + ConfigNameFormat eFormat) +{ + Sequence< OUString > aRet; + try { - try + Reference xCont; + if(!rNode.isEmpty()) { - Reference xCont; - if(!rNode.isEmpty()) - { - Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); - aNode >>= xCont; - } - else - xCont.set(xHierarchyAccess, UNO_QUERY); - if(xCont.is()) - { - aRet = xCont->getElementNames(); - lcl_normalizeLocalNames(aRet,eFormat,xCont); - } - + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; } - catch (css::uno::Exception &) + else + xCont.set(xHierarchyAccess, UNO_QUERY); + if(xCont.is()) { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from GetNodeNames"); + aRet = xCont->getElementNames(); + lcl_normalizeLocalNames(aRet,eFormat,xCont); } + + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from GetNodeNames"); } return aRet; } @@ -632,39 +723,46 @@ bool ConfigItem::ClearNodeSet(const OUString& rNode) bool bRet = false; Reference xHierarchyAccess = GetTree(); if(xHierarchyAccess.is()) + bRet = ClearNodeSet(xHierarchyAccess, rNode); + return bRet; +} + +bool ConfigItem::ClearNodeSet( + css::uno::Reference const & xHierarchyAccess, + const OUString& rNode) +{ + bool bRet = false; + try { - try + Reference xCont; + if(!rNode.isEmpty()) { - Reference xCont; - if(!rNode.isEmpty()) + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont.set(xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return false; + const Sequence< OUString > aNames = xCont->getElementNames(); + Reference xBatch(xHierarchyAccess, UNO_QUERY); + for(const OUString& rName : aNames) + { + try { - Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); - aNode >>= xCont; + xCont->removeByName(rName); } - else - xCont.set(xHierarchyAccess, UNO_QUERY); - if(!xCont.is()) - return false; - const Sequence< OUString > aNames = xCont->getElementNames(); - Reference xBatch(xHierarchyAccess, UNO_QUERY); - for(const OUString& rName : aNames) + catch (css::uno::Exception &) { - try - { - xCont->removeByName(rName); - } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from removeByName"); - } + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from removeByName"); } - xBatch->commitChanges(); - bRet = true; - } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ClearNodeSet"); } + xBatch->commitChanges(); + bRet = true; + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ClearNodeSet"); } return bRet; } @@ -848,124 +946,134 @@ bool ConfigItem::ReplaceSetProperties( bool bRet = true; Reference xHierarchyAccess = GetTree(); if(xHierarchyAccess.is()) + bRet = ReplaceSetProperties(xHierarchyAccess, rNode, rValues, + ( m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales); + return bRet; +} + +bool ConfigItem::ReplaceSetProperties( + css::uno::Reference const & xHierarchyAccess, + const OUString& rNode, + const Sequence< PropertyValue >& rValues, + bool bAllLocales) +{ + bool bRet = true; + Reference xBatch(xHierarchyAccess, UNO_QUERY); + try { - Reference xBatch(xHierarchyAccess, UNO_QUERY); - try + Reference xCont; + if(!rNode.isEmpty()) { - Reference xCont; - if(!rNode.isEmpty()) - { - Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); - aNode >>= xCont; - } - else - xCont.set(xHierarchyAccess, UNO_QUERY); - if(!xCont.is()) - return false; + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont.set(xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return false; - // JB: Change: now the same name handling for sets of simple values - const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); + // JB: Change: now the same name handling for sets of simple values + const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); - Reference xFac(xCont, UNO_QUERY); - const bool isSimpleValueSet = !xFac.is(); + Reference xFac(xCont, UNO_QUERY); + const bool isSimpleValueSet = !xFac.is(); - //remove unknown members first - { - const Sequence aContainerSubNodes = xCont->getElementNames(); + //remove unknown members first + { + const Sequence aContainerSubNodes = xCont->getElementNames(); - for(const OUString& rContainerSubNode : aContainerSubNodes) - { - bool bFound = comphelper::findValue(aSubNodeNames, rContainerSubNode) != -1; - if(!bFound) - try - { - xCont->removeByName(rContainerSubNode); - } - catch (const Exception&) + for(const OUString& rContainerSubNode : aContainerSubNodes) + { + bool bFound = comphelper::findValue(aSubNodeNames, rContainerSubNode) != -1; + if(!bFound) + try + { + xCont->removeByName(rContainerSubNode); + } + catch (const Exception&) + { + if (isSimpleValueSet) { - if (isSimpleValueSet) + try { - try - { - // #i37322#: fallback action: replace with - xCont->replaceByName(rContainerSubNode, Any()); - // fallback successful: continue looping - continue; - } - catch (Exception &) - {} // propagate original exception, if fallback fails + // #i37322#: fallback action: replace with + xCont->replaceByName(rContainerSubNode, Any()); + // fallback successful: continue looping + continue; } - throw; + catch (Exception &) + {} // propagate original exception, if fallback fails } - } - try { xBatch->commitChanges(); } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); - } + throw; + } } + try { xBatch->commitChanges(); } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + } + } - if(xFac.is()) // !isSimpleValueSet + if(xFac.is()) // !isSimpleValueSet + { + for(const OUString& rSubNodeName : aSubNodeNames) { - for(const OUString& rSubNodeName : aSubNodeNames) - { - if(!xCont->hasByName(rSubNodeName)) - { - //create if not available - Reference xInst = xFac->createInstance(); - Any aVal; aVal <<= xInst; - xCont->insertByName(rSubNodeName, aVal); - } - } - try { xBatch->commitChanges(); } - catch (css::uno::Exception &) + if(!xCont->hasByName(rSubNodeName)) { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + //create if not available + Reference xInst = xFac->createInstance(); + Any aVal; aVal <<= xInst; + xCont->insertByName(rSubNodeName, aVal); } + } + try { xBatch->commitChanges(); } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + } - const PropertyValue* pProperties = rValues.getConstArray(); + const PropertyValue* pProperties = rValues.getConstArray(); - Sequence< OUString > aSetNames(rValues.getLength()); - OUString* pSetNames = aSetNames.getArray(); + Sequence< OUString > aSetNames(rValues.getLength()); + OUString* pSetNames = aSetNames.getArray(); - Sequence< Any> aSetValues(rValues.getLength()); - Any* pSetValues = aSetValues.getArray(); + Sequence< Any> aSetValues(rValues.getLength()); + Any* pSetValues = aSetValues.getArray(); - bool bEmptyNode = rNode.isEmpty(); - for(sal_Int32 k = 0; k < rValues.getLength(); k++) - { - pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); - pSetValues[k] = pProperties[k].Value; - } - bRet = PutProperties(aSetNames, aSetValues); + bool bEmptyNode = rNode.isEmpty(); + for(sal_Int32 k = 0; k < rValues.getLength(); k++) + { + pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); + pSetValues[k] = pProperties[k].Value; } - else + bRet = PutProperties(xHierarchyAccess, aSetNames, aSetValues, bAllLocales); + } + else + { + //if no factory is available then the node contains basic data elements + for(const PropertyValue& rValue : rValues) { - //if no factory is available then the node contains basic data elements - for(const PropertyValue& rValue : rValues) + try { - try - { - OUString sSubNode = lcl_extractSetPropertyName( rValue.Name, rNode ); + OUString sSubNode = lcl_extractSetPropertyName( rValue.Name, rNode ); - if(xCont->hasByName(sSubNode)) - xCont->replaceByName(sSubNode, rValue.Value); - else - xCont->insertByName(sSubNode, rValue.Value); - } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from insert/replaceByName"); - } + if(xCont->hasByName(sSubNode)) + xCont->replaceByName(sSubNode, rValue.Value); + else + xCont->insertByName(sSubNode, rValue.Value); + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from insert/replaceByName"); } - xBatch->commitChanges(); } + xBatch->commitChanges(); } - catch (const Exception& ) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ReplaceSetProperties"); - bRet = false; - } + } + catch (const Exception& ) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ReplaceSetProperties"); + bRet = false; } return bRet; } diff --git a/unotools/source/config/configmgr.cxx b/unotools/source/config/configmgr.cxx index 610246295d55..f1a897a6edab 100644 --- a/unotools/source/config/configmgr.cxx +++ b/unotools/source/config/configmgr.cxx @@ -134,6 +134,19 @@ utl::ConfigManager::acquireTree(utl::ConfigItem const & item) { css::uno::UNO_QUERY_THROW); } +css::uno::Reference< css::container::XHierarchicalNameAccess > +utl::ConfigManager::acquireTree(std::u16string_view rSubTreeName) { + css::uno::Sequence< css::uno::Any > args(1); + args[0] <<= css::beans::NamedValue( + "nodepath", + css::uno::makeAny(OUString::Concat(u"/org.openoffice.") + rSubTreeName)); + return css::uno::Reference< css::container::XHierarchicalNameAccess >( + getConfigurationProvider()->createInstanceWithArguments( + "com.sun.star.configuration.ConfigurationUpdateAccess", + args), + css::uno::UNO_QUERY_THROW); +} + utl::ConfigManager::ConfigManager() {} utl::ConfigManager::~ConfigManager() { -- cgit