diff options
Diffstat (limited to 'basic/source/uno/namecont.cxx')
-rw-r--r-- | basic/source/uno/namecont.cxx | 825 |
1 files changed, 405 insertions, 420 deletions
diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx index b92f5a590617..db97fe8794b3 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -25,11 +25,15 @@ #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/io/IOException.hpp> +#include <com/sun/star/lang/NoSupportException.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/ucb/ContentCreationException.hpp> #include <com/sun/star/xml/sax/SAXException.hpp> +#include <utility> #include <vcl/svapp.hxx> +#include <o3tl/string_view.hxx> +#include <o3tl/temporary.hxx> #include <osl/mutex.hxx> #include <vcl/errinf.hxx> #include <rtl/ustring.hxx> @@ -41,7 +45,7 @@ #include <namecont.hxx> #include <basic/basicmanagerrepository.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/urlobj.hxx> #include <unotools/pathoptions.hxx> #include <svtools/sfxecode.hxx> @@ -87,7 +91,6 @@ using namespace com::sun::star::frame; using namespace com::sun::star::deployment; using namespace com::sun::star; using namespace cppu; -using namespace osl; using com::sun::star::uno::Reference; @@ -105,169 +108,140 @@ Type NameContainer::getElementType() sal_Bool NameContainer::hasElements() { - bool bRet = (mnElementCount > 0); - return bRet; + return !maMap.empty(); } // Methods XNameAccess Any NameContainer::getByName( const OUString& aName ) { - NameContainerNameMap::iterator aIt = mHashMap.find( aName ); - if( aIt == mHashMap.end() ) + auto aIt = maMap.find(aName); + if (aIt == maMap.end()) { - throw NoSuchElementException(); + throw NoSuchElementException(aName); } - sal_Int32 iHashResult = (*aIt).second; - Any aRetAny = mValues[ iHashResult ]; - return aRetAny; + return aIt->second; } Sequence< OUString > NameContainer::getElementNames() { - return comphelper::containerToSequence(mNames); + return comphelper::mapKeysToSequence(maMap); } sal_Bool NameContainer::hasByName( const OUString& aName ) { - NameContainerNameMap::iterator aIt = mHashMap.find( aName ); - bool bRet = ( aIt != mHashMap.end() ); - return bRet; + return maMap.contains(aName); } // Methods XNameReplace -void NameContainer::replaceByName( const OUString& aName, const Any& aElement ) +void NameContainer::replaceByName(const OUString& aName, const Any& aElement, + std::unique_lock<std::mutex>& guard) { const Type& aAnyType = aElement.getValueType(); if( mType != aAnyType ) { - throw IllegalArgumentException("types do not match", static_cast<cppu::OWeakObject*>(this), 2); + throw IllegalArgumentException(u"types do not match"_ustr, rOwner, 2); } - NameContainerNameMap::iterator aIt = mHashMap.find( aName ); - if( aIt == mHashMap.end() ) + auto aIt = maMap.find(aName); + if (aIt == maMap.end()) { - throw NoSuchElementException(); + throw NoSuchElementException(aName); } - sal_Int32 iHashResult = (*aIt).second; - Any aOldElement = mValues[ iHashResult ]; - mValues[ iHashResult ] = aElement; - + Any aOldElement = aIt->second; + aIt->second = aElement; // Fire event - if( maContainerListeners.getLength() > 0 ) + if (maContainerListeners.getLength(guard) > 0) { ContainerEvent aEvent; aEvent.Source = mpxEventSource; aEvent.Accessor <<= aName; aEvent.Element = aElement; aEvent.ReplacedElement = aOldElement; - maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent ); + maContainerListeners.notifyEach(guard, &XContainerListener::elementReplaced, aEvent); } /* After the container event has been fired (one listener will update the core Basic manager), fire change event. Listeners can rely on that the Basic source code of the core Basic manager is up-to-date. */ - if( maChangesListeners.getLength() > 0 ) + if (maChangesListeners.getLength(guard) > 0) { ChangesEvent aEvent; aEvent.Source = mpxEventSource; aEvent.Base <<= aEvent.Source; aEvent.Changes = { { Any(aName), aElement, aOldElement } }; - maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent ); - } -} - -void NameContainer::insertCheck(const OUString& aName, const Any& aElement) -{ - NameContainerNameMap::iterator aIt = mHashMap.find(aName); - if( aIt != mHashMap.end() ) - { - throw ElementExistException(); + maChangesListeners.notifyEach(guard, &XChangesListener::changesOccurred, aEvent); } - insertNoCheck(aName, aElement); } -void NameContainer::insertNoCheck(const OUString& aName, const Any& aElement) +void NameContainer::insertNoCheck(const OUString& aName, const Any& aElement, + std::unique_lock<std::mutex>& guard) { const Type& aAnyType = aElement.getValueType(); if( mType != aAnyType ) { - throw IllegalArgumentException("types do not match", static_cast<cppu::OWeakObject*>(this), 2); + throw IllegalArgumentException(u"types do not match"_ustr, rOwner, 2); } - sal_Int32 nCount = mNames.size(); - mNames.push_back( aName ); - mValues.push_back( aElement ); - - mHashMap[ aName ] = nCount; - mnElementCount++; + maMap[aName] = aElement; // Fire event - if( maContainerListeners.getLength() > 0 ) + if (maContainerListeners.getLength(guard) > 0) { ContainerEvent aEvent; aEvent.Source = mpxEventSource; aEvent.Accessor <<= aName; aEvent.Element = aElement; - maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent ); + maContainerListeners.notifyEach(guard, &XContainerListener::elementInserted, aEvent); } /* After the container event has been fired (one listener will update the core Basic manager), fire change event. Listeners can rely on that the Basic source code of the core Basic manager is up-to-date. */ - if( maChangesListeners.getLength() > 0 ) + if (maChangesListeners.getLength(guard) > 0) { ChangesEvent aEvent; aEvent.Source = mpxEventSource; aEvent.Base <<= aEvent.Source; aEvent.Changes = { { Any(aName), aElement, {} } }; - maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent ); + maChangesListeners.notifyEach(guard, &XChangesListener::changesOccurred, aEvent); } } // Methods XNameContainer -void NameContainer::insertByName( const OUString& aName, const Any& aElement ) +void NameContainer::insertByName(const OUString& aName, const Any& aElement, + std::unique_lock<std::mutex>& guard) { - insertCheck(aName, aElement); + if (hasByName(aName)) + throw ElementExistException(aName); + insertNoCheck(aName, aElement, guard); } -void NameContainer::removeByName( const OUString& aName ) +void NameContainer::removeByName(const OUString& aName, std::unique_lock<std::mutex>& guard) { - NameContainerNameMap::iterator aIt = mHashMap.find( aName ); - if( aIt == mHashMap.end() ) + auto aIt = maMap.find(aName); + if (aIt == maMap.end()) { - OUString sMessage = "\"" + aName + "\" not found"; - throw NoSuchElementException(sMessage); + throw NoSuchElementException("\"" + aName + "\" not found"); } - sal_Int32 iHashResult = (*aIt).second; - Any aOldElement = mValues[ iHashResult ]; - mHashMap.erase( aIt ); - sal_Int32 iLast = mNames.size() - 1; - if( iLast != iHashResult ) - { - mNames[ iHashResult ] = mNames[ iLast ]; - mValues[ iHashResult ] = mValues[ iLast ]; - mHashMap[ mNames[ iHashResult ] ] = iHashResult; - } - mNames.resize( iLast ); - mValues.resize( iLast ); - mnElementCount--; + Any aOldElement = aIt->second; + maMap.erase(aIt); // Fire event - if( maContainerListeners.getLength() > 0 ) + if (maContainerListeners.getLength(guard) > 0) { ContainerEvent aEvent; aEvent.Source = mpxEventSource; aEvent.Accessor <<= aName; aEvent.Element = aOldElement; - maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent ); + maContainerListeners.notifyEach(guard, &XContainerListener::elementRemoved, aEvent); } /* After the container event has been fired (one listener will update the core Basic manager), fire change event. Listeners can rely on that the Basic source code of the core Basic manager is up-to-date. */ - if( maChangesListeners.getLength() > 0 ) + if (maChangesListeners.getLength(guard) > 0) { ChangesEvent aEvent; aEvent.Source = mpxEventSource; @@ -275,53 +249,57 @@ void NameContainer::removeByName( const OUString& aName ) aEvent.Changes = { { Any(aName), {}, // Element remains empty (meaning "replaced with nothing") aOldElement } }; - maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent ); + maChangesListeners.notifyEach(guard, &XChangesListener::changesOccurred, aEvent); } } // Methods XContainer -void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener ) +void NameContainer::addContainerListener(const Reference<XContainerListener>& xListener, + std::unique_lock<std::mutex>& guard) { if( !xListener.is() ) { - throw RuntimeException("addContainerListener called with null xListener",static_cast< cppu::OWeakObject * >(this)); + throw RuntimeException(u"addContainerListener called with null xListener"_ustr,rOwner); } - maContainerListeners.addInterface( xListener ); + maContainerListeners.addInterface(guard, xListener); } -void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener ) +void NameContainer::removeContainerListener(const Reference<XContainerListener>& xListener, + std::unique_lock<std::mutex>& guard) { if( !xListener.is() ) { - throw RuntimeException("removeContainerListener called with null xListener",static_cast< cppu::OWeakObject * >(this)); + throw RuntimeException(u"removeContainerListener called with null xListener"_ustr,rOwner); } - maContainerListeners.removeInterface( xListener ); + maContainerListeners.removeInterface(guard, xListener); } // Methods XChangesNotifier -void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener ) +void NameContainer::addChangesListener(const Reference<XChangesListener>& xListener, + std::unique_lock<std::mutex>& guard) { if( !xListener.is() ) { - throw RuntimeException("addChangesListener called with null xListener",static_cast< cppu::OWeakObject * >(this)); + throw RuntimeException(u"addChangesListener called with null xListener"_ustr,rOwner); } - maChangesListeners.addInterface( xListener ); + maChangesListeners.addInterface(guard, xListener); } -void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener ) +void NameContainer::removeChangesListener(const Reference<XChangesListener>& xListener, + std::unique_lock<std::mutex>& guard) { if( !xListener.is() ) { - throw RuntimeException("removeChangesListener called with null xListener",static_cast< cppu::OWeakObject * >(this)); + throw RuntimeException(u"removeChangesListener called with null xListener"_ustr,rOwner); } - maChangesListeners.removeInterface( xListener ); + maChangesListeners.removeInterface(guard, xListener); } // ModifiableHelper -void ModifiableHelper::setModified( bool _bModified ) +void ModifiableHelper::setModified(bool _bModified, std::unique_lock<std::mutex>& guard) { if ( _bModified == mbModified ) { @@ -329,27 +307,26 @@ void ModifiableHelper::setModified( bool _bModified ) } mbModified = _bModified; - if ( m_aModifyListeners.getLength() == 0 ) + if (m_aModifyListeners.getLength(guard) == 0) { return; } EventObject aModifyEvent( m_rEventSource ); - m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent ); + m_aModifyListeners.notifyEach(guard, &XModifyListener::modified, aModifyEvent); } // Ctor SfxLibraryContainer::SfxLibraryContainer() - : SfxLibraryContainer_BASE( m_aMutex ) - , maVBAScriptListeners( m_aMutex ) - , mnRunningVBAScripts( 0 ) + : mnRunningVBAScripts( 0 ) , mbVBACompat( false ) - , maModifiable( *this, m_aMutex ) - , maNameContainer( new NameContainer(cppu::UnoType<XNameAccess>::get()) ) - , mbOldInfoFormat( false ) - , mbOasis2OOoFormat( false ) + , meVBATextEncoding( RTL_TEXTENCODING_DONTKNOW ) + , maModifiable( *this ) + , maNameContainer( cppu::UnoType<XNameAccess>::get(), *this ) , mpBasMgr( nullptr ) , mbOwnBasMgr( false ) + , mbOldInfoFormat( false ) + , mbOasis2OOoFormat( false ) , meInitMode(DEFAULT) { mxContext = comphelper::getProcessComponentContext(); @@ -370,7 +347,7 @@ SfxLibraryContainer::~SfxLibraryContainer() void SfxLibraryContainer::enterMethod() { Application::GetSolarMutex().acquire(); - if ( rBHelper.bInDispose || rBHelper.bDisposed ) + if (m_bDisposed) { throw DisposedException( OUString(), *this ); } @@ -418,7 +395,7 @@ void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& LibraryContainerMethodGuard aGuard( *this ); if ( !_rxRootStorage.is() ) { - throw IllegalArgumentException("no root storage", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"no root storage"_ustr, getXWeak(), 1); } mxStorage = _rxRootStorage; onNewRootStorage(); @@ -429,11 +406,11 @@ void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XSt LibraryContainerMethodGuard aGuard( *this ); if ( !_rxRootStorage.is() ) { - throw IllegalArgumentException("no root storage", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"no root storage"_ustr, getXWeak(), 1); } try { - storeLibraries_Impl( _rxRootStorage, true ); + storeLibraries_Impl(_rxRootStorage, true, o3tl::temporary(std::unique_lock(m_aMutex))); } catch( const Exception& ) { @@ -452,13 +429,8 @@ sal_Bool SfxLibraryContainer::isModified() return true; } // the library container is not modified, go through the libraries and check whether they are modified - Sequence< OUString > aNames = maNameContainer->getElementNames(); - const OUString* pNames = aNames.getConstArray(); - sal_Int32 nNameCount = aNames.getLength(); - - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + for (auto& aName : maNameContainer.getElementNames()) { - OUString aName = pNames[ i ]; try { SfxLibrary* pImplLib = getImplLib( aName ); @@ -489,19 +461,19 @@ sal_Bool SfxLibraryContainer::isModified() void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified ) { LibraryContainerMethodGuard aGuard( *this ); - maModifiable.setModified( _bModified ); + maModifiable.setModified(_bModified, o3tl::temporary(std::unique_lock(m_aMutex))); } void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener ) { LibraryContainerMethodGuard aGuard( *this ); - maModifiable.addModifyListener( _rxListener ); + maModifiable.addModifyListener(_rxListener, o3tl::temporary(std::unique_lock(m_aMutex))); } void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener ) { LibraryContainerMethodGuard aGuard( *this ); - maModifiable.removeModifyListener( _rxListener ); + maModifiable.removeModifyListener(_rxListener, o3tl::temporary(std::unique_lock(m_aMutex))); } // Methods XPersistentLibraryContainer @@ -522,7 +494,7 @@ void SAL_CALL SfxLibraryContainer::storeLibraries( ) LibraryContainerMethodGuard aGuard( *this ); try { - storeLibraries_Impl( mxStorage, mxStorage.is() ); + storeLibraries_Impl(mxStorage, mxStorage.is(), o3tl::temporary(std::unique_lock(m_aMutex))); // we need to store *all* libraries if and only if we are based on a storage: // in this case, storeLibraries_Impl will remove the source storage, after loading // all libraries, so we need to force them to be stored, again @@ -533,7 +505,9 @@ void SAL_CALL SfxLibraryContainer::storeLibraries( ) } } -static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj, +namespace +{ +void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj, const INetURLObject& rTargetFolderInetObj, std::u16string_view rCheckFileName, std::u16string_view rCheckExtension, @@ -555,40 +529,47 @@ static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj, } } -static void createVariableURL( OUString& rStr, std::u16string_view rLibName, +constexpr OUString sUserBasicVariablePrefix = u"$(USER)/basic/"_ustr; +constexpr OUString sInstBasicVariablePrefix = u"$(INST)/" LIBO_SHARE_FOLDER "/basic/"_ustr; + +void createVariableURL( OUString& rStr, std::u16string_view rLibName, std::u16string_view rInfoFileName, bool bUser ) { if( bUser ) { - rStr = "$(USER)/basic/"; + rStr = sUserBasicVariablePrefix; } else { - rStr = "$(INST)/" LIBO_SHARE_FOLDER "/basic/"; + rStr = sInstBasicVariablePrefix; } rStr += OUString::Concat(rLibName) + "/" + rInfoFileName + ".xlb/"; } +} -void SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage ) +void SfxLibraryContainer::init(const OUString& rInitialDocumentURL, + const uno::Reference<embed::XStorage>& rxInitialStorage, + std::unique_lock<std::mutex>& guard) { // this might be called from within the ctor, and the impl_init might (indirectly) create // a UNO reference to ourself. // Ensure that we're not destroyed while we're in here osl_atomic_increment( &m_refCount ); - init_Impl( rInitialDocumentURL, rxInitialStorage ); + init_Impl(rInitialDocumentURL, rxInitialStorage, guard); osl_atomic_decrement( &m_refCount ); } void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, - const uno::Reference< embed::XStorage >& rxInitialStorage ) + const uno::Reference< embed::XStorage >& rxInitialStorage, + std::unique_lock<std::mutex>& guard ) { uno::Reference< embed::XStorage > xStorage = rxInitialStorage; maInitialDocumentURL = rInitialDocumentURL; - maInfoFileName = OUString::createFromAscii( getInfoFileName() ); - maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() ); - maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() ); - maLibrariesDir = OUString::createFromAscii( getLibrariesDir() ); + maInfoFileName = getInfoFileName(); + maOldInfoFileName = getOldInfoFileName(); + maLibElementFileExtension = getLibElementFileExtension(); + maLibrariesDir = getLibrariesDir(); meInitMode = DEFAULT; INetURLObject aInitUrlInetObj( maInitialDocumentURL ); @@ -604,7 +585,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, if( aExtension == "xlc" ) { meInitMode = CONTAINER_INIT_FILE; - INetURLObject aLibPathInetObj( aInitUrlInetObj ); + INetURLObject aLibPathInetObj( std::move(aInitUrlInetObj) ); aLibPathInetObj.removeSegment(); maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); } @@ -613,7 +594,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, meInitMode = LIBRARY_INIT_FILE; uno::Reference< embed::XStorage > xDummyStor; ::xmlscript::LibDescriptor aLibDesc; - implLoadLibraryIndexFile( nullptr, aLibDesc, xDummyStor, aInitFileName ); + implLoadLibraryIndexFile(nullptr, aLibDesc, xDummyStor, aInitFileName, guard); return; } else @@ -646,8 +627,6 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, maLibraryPath = SvtPathOptions().GetBasicPath(); } - Reference< XParser > xParser = xml::sax::Parser::create(mxContext); - uno::Reference< io::XInputStream > xInput; mxStorage = xStorage; @@ -731,11 +710,11 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, { if( nPass == 1 ) { - pLibInfoInetObj.reset(new INetURLObject( maLibraryPath.getToken(0, ';') )); + pLibInfoInetObj.reset(new INetURLObject( o3tl::getToken(maLibraryPath, 0, ';') )); } else { - pLibInfoInetObj.reset(new INetURLObject( maLibraryPath.getToken(1, ';') )); + pLibInfoInetObj.reset(new INetURLObject( o3tl::getToken(maLibraryPath, 1, ';') )); } pLibInfoInetObj->insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); pLibInfoInetObj->setExtension( u"xlc" ); @@ -755,7 +734,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, // Old variant? if( !xInput.is() && nPass == 0 ) { - INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, ';') ); + INetURLObject aLibInfoInetObj( o3tl::getToken(maLibraryPath, 1, ';') ); aLibInfoInetObj.insertName( maOldInfoFileName, false, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); aLibInfoInetObj.setExtension( u"xli" ); aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); @@ -779,11 +758,12 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, source.sSystemId = aFileName; // start parsing - auto pLibArray = std::make_unique<::xmlscript::LibDescriptorArray> ( ); + ::xmlscript::LibDescriptorArray aLibArray; + Reference< XParser > xParser = xml::sax::Parser::create(mxContext); try { - xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray.get() ) ); + xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( &aLibArray ) ); xParser->parseStream( source ); } catch ( const xml::sax::SAXException& ) @@ -797,10 +777,10 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, return; } - sal_Int32 nLibCount = pLibArray->mnLibCount; + sal_Int32 nLibCount = aLibArray.mnLibCount; for( sal_Int32 i = 0 ; i < nLibCount ; i++ ) { - ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i]; + ::xmlscript::LibDescriptor& rLib = aLibArray.mpLibs[i]; // Check storage URL OUString aStorageURL = rLib.aStorageURL; @@ -823,19 +803,19 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, if( mxSFI->isFolder( aLibDirPath ) ) { createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true ); - maModifiable.setModified( true ); + maModifiable.setModified(true, guard); } else if( rLib.bLink ) { // Check "share" path - INetURLObject aShareInetObj( maLibraryPath.getToken(0, ';') ); + INetURLObject aShareInetObj( o3tl::getToken(maLibraryPath, 0, ';') ); aShareInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); if( mxSFI->isFolder( aShareLibDirPath ) ) { createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false ); - maModifiable.setModified( true ); + maModifiable.setModified(true, guard); } else { @@ -857,12 +837,12 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, if( rLib.bLink ) { Reference< XNameAccess > xLib = - createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly ); + createLibraryLink_Impl(aLibName, rLib.aStorageURL, rLib.bReadOnly, guard); pImplLib = static_cast< SfxLibrary* >( xLib.get() ); } else { - Reference< XNameContainer > xLib = createLibrary( aLibName ); + Reference<XNameContainer> xLib = createLibrary_Impl(aLibName, guard); pImplLib = static_cast< SfxLibrary* >( xLib.get() ); pImplLib->mbLoaded = false; pImplLib->mbReadOnly = rLib.bReadOnly; @@ -872,7 +852,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL ); } } - maModifiable.setModified( false ); + maModifiable.setModified(false, guard); // Read library info files if( !mbOldInfoFormat ) @@ -895,10 +875,10 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, } } - // Link is already initialised in createLibraryLink() + // Link is already initialised in createLibraryLink_Impl() if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) ) { - bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, OUString() ); + bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, OUString(), guard ); SAL_WARN_IF( bLoaded && aLibName != rLib.aName, "basic", ("Different library names in library container and" @@ -918,7 +898,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage ); } - implImportLibDescriptor( pImplLib, rLib ); + implImportLibDescriptor(pImplLib, rLib, guard); if( nPass == 1 ) { @@ -942,7 +922,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, { try { - implScanExtensions(); + implScanExtensions(guard); } catch(const uno::Exception& ) { @@ -953,16 +933,12 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, // Preload? { - Sequence< OUString > aNames = maNameContainer->getElementNames(); - const OUString* pNames = aNames.getConstArray(); - sal_Int32 nNameCount = aNames.getLength(); - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + for (auto& aName : maNameContainer.getElementNames()) { - OUString aName = pNames[ i ]; SfxLibrary* pImplLib = getImplLib( aName ); if( pImplLib->mbPreload ) { - loadLibrary( aName ); + loadLibrary_Impl(aName, guard); } } } @@ -970,8 +946,12 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, if( meInitMode != DEFAULT ) return; - INetURLObject aUserBasicInetObj( maLibraryPath.getToken(1, ';') ); - OUString aStandardStr("Standard"); + // tdf#121740 speed up loading documents with lots of embedded documents by avoid the UCB work of updating non-existent VBA libraries + if (rInitialDocumentURL.isEmpty()) + return; + + INetURLObject aUserBasicInetObj( o3tl::getToken(maLibraryPath, 1, ';') ); + OUString aStandardStr(u"Standard"_ustr); INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj ); aPrevUserBasicInetObj_1.removeSegment(); @@ -997,7 +977,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); if( mxSFI->isFolder( aPrevStandardFolder ) ) { - OUString aXlbExtension( "xlb" ); + OUString aXlbExtension( u"xlb"_ustr ); OUString aCheckFileName; // Check if script.xlb exists @@ -1076,13 +1056,8 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, mxSFI->move( aFolderUserBasic, aPrevFolder ); mxSFI->move( aFolderTmp, aFolderUserBasic ); - Sequence< OUString > aNames = pPrevCont->getElementNames(); - const OUString* pNames = aNames.getConstArray(); - sal_Int32 nNameCount = aNames.getLength(); - - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + for (auto& aLibName : pPrevCont->getElementNames()) { - OUString aLibName = pNames[ i ]; if( hasByName( aLibName ) ) { if( aLibName == aStandardStr ) @@ -1111,7 +1086,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, } if( bCreateLink ) { - createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly ); + createLibraryLink_Impl( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly, guard ); } } else @@ -1132,21 +1107,21 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, if( aLibName == aStandardStr ) { - maNameContainer->removeByName( aLibName ); + maNameContainer.removeByName(aLibName, guard); } // Create library - Reference< XNameContainer > xLib = createLibrary( aLibName ); + Reference<XNameContainer> xLib = createLibrary_Impl(aLibName, guard); SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() ); pNewLib->mbLoaded = false; - pNewLib->implSetModified( false ); + pNewLib->implSetModified(false, guard); checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL, pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL ); uno::Reference< embed::XStorage > xDummyStor; ::xmlscript::LibDescriptor aLibDesc; - implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL ); - implImportLibDescriptor( pNewLib, aLibDesc ); + implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL, guard ); + implImportLibDescriptor(pNewLib, aLibDesc, guard); } } mxSFI->kill( aPrevFolder ); @@ -1162,7 +1137,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, if( !bCleanUp ) return; - INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj ); + INetURLObject aPrevUserBasicInetObj_Err(std::move(aUserBasicInetObj)); aPrevUserBasicInetObj_Err.removeSegment(); aPrevUserBasicInetObj_Err.Append( u"__basic_80_err" ); OUString aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::DecodeMechanism::NONE ); @@ -1195,7 +1170,7 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL, {} } -void SfxLibraryContainer::implScanExtensions() +void SfxLibraryContainer::implScanExtensions(std::unique_lock<std::mutex>& guard) { #if HAVE_FEATURE_EXTENSIONS ScriptExtensionIterator aScriptIt; @@ -1237,10 +1212,10 @@ void SfxLibraryContainer::implScanExtensions() // Create link const bool bReadOnly = false; - createLibraryLink( aLibName, aIndexFileURL, bReadOnly ); + createLibraryLink_Impl(aLibName, aIndexFileURL, bReadOnly, guard); } #else - (void) this; + (void)guard; #endif } @@ -1254,6 +1229,17 @@ void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL, { aUnexpandedStorageURL = aSourceURL; } + else + { + // try to re-create the variable URL: helps moving the profile + if (std::u16string_view aRest; aSourceURL.startsWith(expand_url(sUserBasicVariablePrefix), &aRest)) + aUnexpandedStorageURL = sUserBasicVariablePrefix + aRest; + else if (aSourceURL.startsWith(expand_url(sInstBasicVariablePrefix), &aRest)) + aUnexpandedStorageURL = sInstBasicVariablePrefix + aRest; + else + aUnexpandedStorageURL.clear(); // This will use eventual value of aLibInfoFileURL + } + INetURLObject aInetObj( aExpandedSourceURL ); OUString aExtension = aInetObj.getExtension(); if( aExtension == "xlb" ) @@ -1275,11 +1261,8 @@ void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL, SfxLibrary* SfxLibraryContainer::getImplLib( const OUString& rLibraryName ) { - Any aLibAny = maNameContainer->getByName( rLibraryName ) ; - Reference< XNameAccess > xNameAccess; - aLibAny >>= xNameAccess; - SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() ); - return pImplLib; + auto xNameAccess = maNameContainer.getByName(rLibraryName).query<XNameAccess>(); + return static_cast<SfxLibrary*>(xNameAccess.get()); } @@ -1308,7 +1291,8 @@ bool SfxLibraryContainer::implStorePasswordLibrary( bool SfxLibraryContainer::implLoadPasswordLibrary( SfxLibrary* /*pLib*/, const OUString& /*Name*/, - bool /*bVerifyPasswordOnly*/ ) + bool /*bVerifyPasswordOnly*/, + std::unique_lock<std::mutex>& /*guard*/ ) { return true; } @@ -1318,7 +1302,7 @@ OUString SfxLibraryContainer::createAppLibraryFolder( SfxLibrary* pLib, std::u16 OUString aLibDirPath = pLib->maStorageURL; if( aLibDirPath.isEmpty() ) { - INetURLObject aInetObj( maLibraryPath.getToken(1, ';') ); + INetURLObject aInetObj( o3tl::getToken(maLibraryPath, 1, ';') ); aInetObj.insertName( aName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); checkStorageURL( aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ), pLib->maLibInfoFileURL, pLib->maStorageURL, pLib->maUnexpandedStorageURL ); @@ -1345,29 +1329,24 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, { Reference< XSimpleFileAccess3 > xDummySFA; Reference< XInteractionHandler > xDummyHandler; - implStoreLibrary( pLib, aName, xStorage, OUString(), xDummySFA, xDummyHandler ); + implStoreLibrary( pLib, aName, xStorage, u"", xDummySFA, xDummyHandler ); } // New variant for library export void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, std::u16string_view aName, const uno::Reference< embed::XStorage >& xStorage, - const OUString& aTargetURL, + std::u16string_view aTargetURL, const Reference< XSimpleFileAccess3 >& rToUseSFI, const Reference< XInteractionHandler >& xHandler ) { bool bLink = pLib->mbLink; bool bStorage = xStorage.is() && !bLink; - Sequence< OUString > aElementNames = pLib->getElementNames(); - sal_Int32 nNameCount = aElementNames.getLength(); - const OUString* pNames = aElementNames.getConstArray(); - if( bStorage ) { - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + for (auto& aElementName : pLib->getElementNames()) { - OUString aElementName = pNames[ i ]; OUString aStreamName = aElementName + ".xml"; if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) @@ -1392,10 +1371,10 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, if ( xProps.is() ) { - xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) ); + xProps->setPropertyValue(u"MediaType"_ustr, uno::Any( u"text/xml"_ustr ) ); // #87671 Allow encryption - xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) ); + xProps->setPropertyValue(u"UseCommonStoragePasswordEncryption"_ustr, uno::Any( true ) ); Reference< XOutputStream > xOutput = xElementStream->getOutputStream(); Reference< XNameContainer > xLib( pLib ); @@ -1413,7 +1392,7 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, else { // Export? - bool bExport = !aTargetURL.isEmpty(); + bool bExport = !aTargetURL.empty(); try { Reference< XSimpleFileAccess3 > xSFI = mxSFI; @@ -1440,10 +1419,8 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, pLib->storeResources(); } - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + for (auto& aElementName : pLib->getElementNames()) { - OUString aElementName = pNames[ i ]; - INetURLObject aElementInetObj( aLibDirPath ); aElementInetObj.insertName( aElementName, false, INetURLObject::LAST_SEGMENT, @@ -1497,14 +1474,14 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, const uno::Reference< embed::XStorage >& xStorage ) { Reference< XSimpleFileAccess3 > xDummySFA; - implStoreLibraryIndexFile( pLib, rLib, xStorage, OUString(), xDummySFA ); + implStoreLibraryIndexFile( pLib, rLib, xStorage, u"", xDummySFA ); } // New variant for library export void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, - const OUString& aTargetURL, + std::u16string_view aTargetURL, const Reference< XSimpleFileAccess3 >& rToUseSFI ) { // Create sax writer @@ -1529,10 +1506,10 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, if ( xProps.is() ) { - xProps->setPropertyValue("MediaType", uno::Any( OUString("text/xml") ) ); + xProps->setPropertyValue(u"MediaType"_ustr, uno::Any( u"text/xml"_ustr ) ); // #87671 Allow encryption - xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) ); + xProps->setPropertyValue(u"UseCommonStoragePasswordEncryption"_ustr, uno::Any( true ) ); xOut = xInfoStream->getOutputStream(); } @@ -1546,7 +1523,7 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, else { // Export? - bool bExport = !aTargetURL.isEmpty(); + bool bExport = !aTargetURL.empty(); Reference< XSimpleFileAccess3 > xSFI = mxSFI; if( rToUseSFI.is() ) { @@ -1603,7 +1580,8 @@ void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib, bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, - const OUString& aIndexFileName ) + const OUString& aIndexFileName, + std::unique_lock<std::mutex>& guard ) { Reference< XParser > xParser = xml::sax::Parser::create(mxContext); @@ -1664,7 +1642,7 @@ bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib, } InputSource source; - source.aInputStream = xInput; + source.aInputStream = std::move(xInput); source.sSystemId = aLibInfoPath; // start parsing @@ -1683,59 +1661,51 @@ bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib, if( !pLib ) { - Reference< XNameContainer > xLib = createLibrary( rLib.aName ); + Reference<XNameContainer> xLib = createLibrary_Impl(rLib.aName, guard); pLib = static_cast< SfxLibrary* >( xLib.get() ); pLib->mbLoaded = false; rLib.aStorageURL = aIndexFileName; checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL, pLib->maUnexpandedStorageURL ); - implImportLibDescriptor( pLib, rLib ); + implImportLibDescriptor(pLib, rLib, guard); } return true; } void SfxLibraryContainer::implImportLibDescriptor( SfxLibrary* pLib, - ::xmlscript::LibDescriptor const & rLib ) + ::xmlscript::LibDescriptor const& rLib, + std::unique_lock<std::mutex>& guard) { if( pLib->mbInitialised ) return; - - sal_Int32 nElementCount = rLib.aElementNames.getLength(); - const OUString* pElementNames = rLib.aElementNames.getConstArray(); Any aDummyElement = createEmptyLibraryElement(); - for( sal_Int32 i = 0 ; i < nElementCount ; i++ ) + for (auto& name : rLib.aElementNames) { - pLib->maNameContainer->insertByName( pElementNames[i], aDummyElement ); + pLib->maNameContainer.insertByName(name, aDummyElement, guard); } pLib->mbPasswordProtected = rLib.bPasswordProtected; pLib->mbReadOnly = rLib.bReadOnly; pLib->mbPreload = rLib.bPreload; - pLib->implSetModified( false ); + pLib->implSetModified(false, guard); pLib->mbInitialised = true; } // Methods of new XLibraryStorage interface? void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage, - bool bComplete ) + bool bComplete, std::unique_lock<std::mutex>& guard ) { - const Sequence< OUString > aNames = maNameContainer->getElementNames(); - const sal_Int32 nNameCount = aNames.getLength(); - const OUString* pName = aNames.getConstArray(); - const OUString* pNamesEnd = aNames.getConstArray() + nNameCount; + const Sequence< OUString > aNames = maNameContainer.getElementNames(); // Don't count libs from shared index file - sal_Int32 nLibsToSave = nNameCount; - for( ; pName != pNamesEnd; ++pName ) - { - SfxLibrary* pImplLib = getImplLib( *pName ); - if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension ) - { - nLibsToSave--; - } - } + sal_Int32 nLibsToSave + = std::count_if(aNames.begin(), aNames.end(), + [this](const OUString& name) { + SfxLibrary* pImplLib = getImplLib(name); + return !pImplLib->mbSharedIndexFile && !pImplLib->mbExtension; + }); // Write to storage? bool bStorage = i_rStorage.is(); uno::Reference< embed::XStorage > xSourceLibrariesStor; @@ -1757,10 +1727,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto // Don't write if only empty standard lib exists if ( ( nLibsToSave == 1 ) && ( aNames[0] == "Standard" ) ) { - Any aLibAny = maNameContainer->getByName( aNames[0] ); - Reference< XNameAccess > xNameAccess; - aLibAny >>= xNameAccess; - if ( ! xNameAccess->hasElements() ) + if (!getImplLib(aNames[0])->hasElements()) { if ( bInplaceStorage && mxStorage->hasByName(maLibrariesDir) ) { @@ -1777,14 +1744,11 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto if ( bInplaceStorage ) { // create a temporary target storage - const OUStringBuffer aTempTargetNameBase = maLibrariesDir + "_temp_"; + const OUString aTempTargetNameBase = maLibrariesDir + "_temp_"; sal_Int32 index = 0; do { - OUStringBuffer aTempTargetName( aTempTargetNameBase ); - aTempTargetName.append( index++ ); - - sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear(); + sTargetLibrariesStoreName = aTempTargetNameBase + OUString::number( index++ ); if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) ) { break; @@ -1827,24 +1791,23 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto } int iArray = 0; - pName = aNames.getConstArray(); ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs; - auto pLibArray = std::make_unique< ::xmlscript::LibDescriptorArray > ( nLibsToSave ); - for( ; pName != pNamesEnd; ++pName ) + ::xmlscript::LibDescriptorArray aLibArray( nLibsToSave ); + for (auto& name : aNames) { - SfxLibrary* pImplLib = getImplLib( *pName ); + SfxLibrary* pImplLib = getImplLib(name); if( pImplLib->mbSharedIndexFile ) { continue; } const bool bExtensionLib = pImplLib->mbExtension; ::xmlscript::LibDescriptor& rLib = bExtensionLib ? - aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray]; + aLibDescriptorForExtensionLibs : aLibArray.mpLibs[iArray]; if( !bExtensionLib ) { iArray++; } - rLib.aName = *pName; + rLib.aName = name; rLib.bLink = pImplLib->mbLink; if( !bStorage || pImplLib->mbLink ) @@ -1928,7 +1891,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto // Maybe lib is not loaded?! if( bComplete ) { - loadLibrary( rLib.aName ); + loadLibrary_Impl(rLib.aName, guard); } if( pImplLib->mbPasswordProtected ) { @@ -1955,8 +1918,8 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto } } } - maModifiable.setModified( true ); - pImplLib->implSetModified( false ); + maModifiable.setModified(true, guard); + pImplLib->implSetModified(false, guard); } // For container info ReadOnly refers to mbReadOnlyLink @@ -2018,7 +1981,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto { return; } - maModifiable.setModified( false ); + maModifiable.setModified(false, guard); mbOldInfoFormat = false; // Write library container info @@ -2036,10 +1999,10 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto { xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE ); uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY_THROW ); - xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) ); + xProps->setPropertyValue(u"MediaType"_ustr, uno::Any( u"text/xml"_ustr ) ); // #87671 Allow encryption - xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) ); + xProps->setPropertyValue(u"UseCommonStoragePasswordEncryption"_ustr, uno::Any( true ) ); xOut = xInfoStream->getOutputStream(); } @@ -2051,7 +2014,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto else { // Create Output stream - INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, ';') ); + INetURLObject aLibInfoInetObj( o3tl::getToken(maLibraryPath, 1, ';') ); aLibInfoInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); aLibInfoInetObj.setExtension( u"xlc" ); OUString aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); @@ -2082,7 +2045,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto try { - xmlscript::exportLibraryContainer( xWriter, pLibArray.get() ); + xmlscript::exportLibraryContainer( xWriter, &aLibArray ); if ( bStorage ) { uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY_THROW ); @@ -2101,58 +2064,70 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto Type SAL_CALL SfxLibraryContainer::getElementType() { LibraryContainerMethodGuard aGuard( *this ); - return maNameContainer->getElementType(); + return maNameContainer.getElementType(); } sal_Bool SfxLibraryContainer::hasElements() { LibraryContainerMethodGuard aGuard( *this ); - bool bRet = maNameContainer->hasElements(); - return bRet; + return maNameContainer.hasElements(); } // Methods XNameAccess Any SfxLibraryContainer::getByName( const OUString& aName ) { LibraryContainerMethodGuard aGuard( *this ); - Any aRetAny = maNameContainer->getByName( aName ) ; - return aRetAny; + return maNameContainer.getByName(aName); } Sequence< OUString > SfxLibraryContainer::getElementNames() { LibraryContainerMethodGuard aGuard( *this ); - return maNameContainer->getElementNames(); + return maNameContainer.getElementNames(); } sal_Bool SfxLibraryContainer::hasByName( const OUString& aName ) { LibraryContainerMethodGuard aGuard( *this ); - return maNameContainer->hasByName( aName ) ; + return maNameContainer.hasByName( aName ) ; } // Methods XLibraryContainer Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name ) { LibraryContainerMethodGuard aGuard( *this ); + return createLibrary_Impl(Name, o3tl::temporary(std::unique_lock(m_aMutex))); +} + +css::uno::Reference<css::container::XNameContainer> +SfxLibraryContainer::createLibrary_Impl(const OUString& Name, std::unique_lock<std::mutex>& guard) +{ rtl::Reference<SfxLibrary> pNewLib = implCreateLibrary( Name ); pNewLib->maLibElementFileExtension = maLibElementFileExtension; createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true ); + // tdf#151741 - fill various storage URLs for the newly created library + checkStorageURL(pNewLib->maUnexpandedStorageURL, pNewLib->maLibInfoFileURL, + pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL); - Reference< XNameAccess > xNameAccess( pNewLib ); Any aElement; - aElement <<= xNameAccess; - maNameContainer->insertByName( Name, aElement ); - maModifiable.setModified( true ); - Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY ); - return xRet; + aElement <<= Reference< XNameAccess >( pNewLib ); + maNameContainer.insertByName(Name, aElement, guard); + maModifiable.setModified(true, guard); + return pNewLib; } Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly ) { LibraryContainerMethodGuard aGuard( *this ); + return createLibraryLink_Impl(Name, StorageURL, ReadOnly, o3tl::temporary(std::unique_lock(m_aMutex))); +} + +css::uno::Reference<css::container::XNameAccess> +SfxLibraryContainer::createLibraryLink_Impl(const OUString& Name, const OUString& StorageURL, + sal_Bool ReadOnly, std::unique_lock<std::mutex>& guard) +{ // TODO: Check other reasons to force ReadOnly status //if( !ReadOnly ) //{ @@ -2171,14 +2146,13 @@ Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink uno::Reference< embed::XStorage > xDummyStor; ::xmlscript::LibDescriptor aLibDesc; - implLoadLibraryIndexFile( pNewLib.get(), aLibDesc, xDummyStor, OUString() ); - implImportLibDescriptor( pNewLib.get(), aLibDesc ); + implLoadLibraryIndexFile(pNewLib.get(), aLibDesc, xDummyStor, OUString(), guard); + implImportLibDescriptor(pNewLib.get(), aLibDesc, guard); - Reference< XNameAccess > xRet( pNewLib ); Any aElement; - aElement <<= xRet; - maNameContainer->insertByName( Name, aElement ); - maModifiable.setModified( true ); + aElement <<= Reference< XNameAccess >( pNewLib ); + maNameContainer.insertByName(Name, aElement, guard); + maModifiable.setModified(true, guard); if( StorageURL.indexOf( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ) != -1 ) { @@ -2191,24 +2165,22 @@ Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink pNewLib->mbReadOnly = true; } - return xRet; + return pNewLib; } void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name ) { LibraryContainerMethodGuard aGuard( *this ); + std::unique_lock guard(m_aMutex); // Get and hold library before removing - Any aLibAny = maNameContainer->getByName( Name ) ; - Reference< XNameAccess > xNameAccess; - aLibAny >>= xNameAccess; - SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() ); + rtl::Reference pImplLib(getImplLib(Name)); if( pImplLib->mbReadOnly && !pImplLib->mbLink ) { - throw IllegalArgumentException("readonly && !link", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"readonly && !link"_ustr, getXWeak(), 1); } // Remove from container - maNameContainer->removeByName( Name ); - maModifiable.setModified( true ); + maNameContainer.removeByName(Name, guard); + maModifiable.setModified(true, guard); // Delete library files, but not for linked libraries if( pImplLib->mbLink ) @@ -2218,19 +2190,14 @@ void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name ) { return; } - if( xNameAccess->hasElements() ) + if (pImplLib->hasElements()) { - Sequence< OUString > aNames = pImplLib->getElementNames(); - sal_Int32 nNameCount = aNames.getLength(); - const OUString* pNames = aNames.getConstArray(); - for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames ) - { - pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() ); - } + for (auto& name : pImplLib->getElementNames()) + pImplLib->impl_removeWithoutChecks(name, guard); } // Delete index file - createAppLibraryFolder( pImplLib, Name ); + createAppLibraryFolder(pImplLib.get(), Name); OUString aLibInfoPath = pImplLib->maLibInfoFileURL; try { @@ -2242,7 +2209,7 @@ void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name ) catch(const Exception& ) {} // Delete folder if empty - INetURLObject aInetObj( maLibraryPath.getToken(1, ';') ); + INetURLObject aInetObj( o3tl::getToken(maLibraryPath, 1, ';') ); aInetObj.insertName( Name, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); @@ -2276,19 +2243,22 @@ sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name ) void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) { LibraryContainerMethodGuard aGuard( *this ); - Any aLibAny = maNameContainer->getByName( Name ) ; - Reference< XNameAccess > xNameAccess; - aLibAny >>= xNameAccess; - SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() ); + return loadLibrary_Impl(Name, o3tl::temporary(std::unique_lock(m_aMutex))); +} + +void SfxLibraryContainer::loadLibrary_Impl(const OUString& Name, + std::unique_lock<std::mutex>& guard) +{ + SfxLibrary* pImplLib = getImplLib(Name); bool bLoaded = pImplLib->mbLoaded; pImplLib->mbLoaded = true; - if( bLoaded || !xNameAccess->hasElements() ) + if (bLoaded || !pImplLib->hasElements()) return; if( pImplLib->mbPasswordProtected ) { - implLoadPasswordLibrary( pImplLib, Name ); + implLoadPasswordLibrary(pImplLib, Name, false, guard); return; } @@ -2310,7 +2280,7 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) " storage!")); if ( !xLibrariesStor.is() ) { - throw uno::RuntimeException("null returned from openStorageElement",static_cast< cppu::OWeakObject * >(this)); + throw uno::RuntimeException(u"null returned from openStorageElement"_ustr,getXWeak()); } xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ ); @@ -2320,7 +2290,7 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) " storage!")); if ( !xLibrariesStor.is() ) { - throw uno::RuntimeException("null returned from openStorageElement",static_cast< cppu::OWeakObject * >(this)); + throw uno::RuntimeException(u"null returned from openStorageElement"_ustr,getXWeak()); } #if OSL_DEBUG_LEVEL > 0 } @@ -2334,13 +2304,18 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) #endif } - Sequence< OUString > aNames = pImplLib->getElementNames(); - sal_Int32 nNameCount = aNames.getLength(); - const OUString* pNames = aNames.getConstArray(); - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + // tdf#167255 workaround: sort library elements to establish at least some predictable order. + // FIXME: the order of modules must not affect their inner names visibility. Modules must load + // their content first (and so the names of e.g. global constants / variables must be known), + // and only then their elements' values must be resolved. + auto elements = pImplLib->getElementNames(); { - OUString aElementName = pNames[ i ]; + auto range = asNonConstRange(elements); + std::sort(range.begin(), range.end()); + } + for (auto& aElementName : elements) + { OUString aFile; uno::Reference< io::XInputStream > xInStream; @@ -2379,7 +2354,7 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) "basic", "couldn't open library element stream - attempted to" " open library \"" << Name << '"'); - throw RuntimeException("couldn't open library element stream", *this); + throw RuntimeException(u"couldn't open library element stream"_ustr, *this); } } else @@ -2400,15 +2375,15 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) { if( aAny.hasValue() ) { - pImplLib->maNameContainer->replaceByName( aElementName, aAny ); + pImplLib->maNameContainer.replaceByName(aElementName, aAny, guard); } } else { - pImplLib->maNameContainer->insertNoCheck(aElementName, aAny); + pImplLib->maNameContainer.insertNoCheck(aElementName, aAny, guard); } } - pImplLib->implSetModified( false ); + pImplLib->implSetModified(false, guard); } // Methods XLibraryContainer2 @@ -2427,7 +2402,7 @@ OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name ) bool bLink = pImplLib->mbLink; if( !bLink ) { - throw IllegalArgumentException("!link", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"!link"_ustr, getXWeak(), 1); } OUString aRetStr = pImplLib->maLibInfoFileURL; return aRetStr; @@ -2444,14 +2419,15 @@ sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name ) void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly ) { LibraryContainerMethodGuard aGuard( *this ); + std::unique_lock guard(m_aMutex); SfxLibrary* pImplLib = getImplLib( Name ); if( pImplLib->mbLink ) { if( pImplLib->mbReadOnlyLink != bool(bReadOnly) ) { pImplLib->mbReadOnlyLink = bReadOnly; - pImplLib->implSetModified( true ); - maModifiable.setModified( true ); + pImplLib->implSetModified(true, guard); + maModifiable.setModified(true, guard); } } else @@ -2459,7 +2435,7 @@ void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal if( pImplLib->mbReadOnly != bool(bReadOnly) ) { pImplLib->mbReadOnly = bReadOnly; - pImplLib->implSetModified( true ); + pImplLib->implSetModified(true, guard); } } } @@ -2467,26 +2443,20 @@ void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName ) { LibraryContainerMethodGuard aGuard( *this ); - if( maNameContainer->hasByName( NewName ) ) + std::unique_lock guard(m_aMutex); + if( maNameContainer.hasByName( NewName ) ) { throw ElementExistException(); } // Get and hold library before removing - Any aLibAny = maNameContainer->getByName( Name ) ; + rtl::Reference pImplLib(getImplLib(Name)); // #i24094 Maybe lib is not loaded! - Reference< XNameAccess > xNameAccess; - aLibAny >>= xNameAccess; - SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() ); if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified ) { return; // Lib with unverified password cannot be renamed } - loadLibrary( Name ); - - // Remove from container - maNameContainer->removeByName( Name ); - maModifiable.setModified( true ); + loadLibrary_Impl(Name, guard); // Rename library folder, but not for linked libraries bool bMovedSuccessful = true; @@ -2498,15 +2468,23 @@ void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OU bMovedSuccessful = false; OUString aLibDirPath = pImplLib->maStorageURL; + // tdf#151741 - fill various storage URLs for the library + // These URLs should not be empty for newly created libraries after + // the change in SfxLibraryContainer::createLibrary_Impl. + if (aLibDirPath.isEmpty()) + { + checkStorageURL(pImplLib->maUnexpandedStorageURL, pImplLib->maLibInfoFileURL, + pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL); + } - INetURLObject aDestInetObj( maLibraryPath.getToken(1, ';')); + INetURLObject aDestInetObj( o3tl::getToken(maLibraryPath, 1, ';')); aDestInetObj.insertName( NewName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); // Store new URL OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL; - checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL, + checkStorageURL(aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL ); try @@ -2530,13 +2508,8 @@ void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OU { } - Sequence< OUString > aElementNames = xNameAccess->getElementNames(); - sal_Int32 nNameCount = aElementNames.getLength(); - const OUString* pNames = aElementNames.getConstArray(); - for( sal_Int32 i = 0 ; i < nNameCount ; i++ ) + for (auto& aElementName : pImplLib->getElementNames()) { - OUString aElementName = pNames[ i ]; - INetURLObject aElementInetObj( aLibDirPath ); aElementInetObj.insertName( aElementName, false, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All ); @@ -2573,23 +2546,24 @@ void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OU } bMovedSuccessful = true; - pImplLib->implSetModified( true ); + pImplLib->implSetModified(true, guard); } } catch(const Exception& ) { - // Restore old library - maNameContainer->insertByName( Name, aLibAny ) ; } } if( bStorage && !pImplLib->mbLink ) { - pImplLib->implSetModified( true ); + pImplLib->implSetModified(true, guard); } if( bMovedSuccessful ) { - maNameContainer->insertByName( NewName, aLibAny ) ; + // Remove the old library from the container and insert it back with the new name + maNameContainer.removeByName(Name, guard); + maNameContainer.insertByName(NewName, Any(Reference<XNameAccess>(pImplLib)), guard); + maModifiable.setModified(true, guard); } } @@ -2598,35 +2572,37 @@ void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OU void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments ) { LibraryContainerMethodGuard aGuard( *this ); + std::unique_lock guard(m_aMutex); sal_Int32 nArgCount = _rArguments.getLength(); if ( nArgCount != 1 ) - throw IllegalArgumentException("too many args", static_cast<cppu::OWeakObject*>(this), -1); + throw IllegalArgumentException(u"too many args"_ustr, getXWeak(), -1); OUString sInitialDocumentURL; Reference< XStorageBasedDocument > xDocument; if ( _rArguments[0] >>= sInitialDocumentURL ) { - init( sInitialDocumentURL, nullptr ); + init(sInitialDocumentURL, nullptr, guard); return; } if ( _rArguments[0] >>= xDocument ) { - initializeFromDocument( xDocument ); + initializeFromDocument(xDocument, guard); return; } - throw IllegalArgumentException("arg1 unknown type", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"arg1 unknown type"_ustr, getXWeak(), 1); } -void SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument ) +void SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument, + std::unique_lock<std::mutex>& guard ) { // check whether this is a valid OfficeDocument, and obtain the document's root storage Reference< XStorage > xDocStorage; try { Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW ); - if ( xSI->supportsService("com.sun.star.document.OfficeDocument")) + if ( xSI->supportsService(u"com.sun.star.document.OfficeDocument"_ustr)) { xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_SET_THROW ); } @@ -2640,9 +2616,9 @@ void SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBased if ( !xDocStorage.is() ) { - throw IllegalArgumentException("no doc storage", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"no doc storage"_ustr, getXWeak(), 1); } - init( OUString(), xDocStorage ); + init(OUString(), xDocStorage, guard); } // OEventListenerAdapter @@ -2660,11 +2636,11 @@ void SfxLibraryContainer::_disposing( const EventObject& _rSource ) } // OComponentHelper -void SAL_CALL SfxLibraryContainer::disposing() +void SfxLibraryContainer::disposing(std::unique_lock<std::mutex>& guard) { Reference< XModel > xModel = mxOwnerDocument; EventObject aEvent( xModel ); - maVBAScriptListeners.disposeAndClear( aEvent ); + maVBAScriptListeners.disposeAndClear(guard, aEvent); stopAllComponentListening(); mxOwnerDocument.clear(); } @@ -2694,14 +2670,16 @@ void SAL_CALL SfxLibraryContainer::changeLibraryPassword(const OUString&, const void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener ) { LibraryContainerMethodGuard aGuard( *this ); - maNameContainer->setEventSource( static_cast< XInterface* >( static_cast<OWeakObject*>(this) ) ); - maNameContainer->addContainerListener( xListener ); + std::unique_lock guard(m_aMutex); + maNameContainer.setEventSource( getXWeak() ); + maNameContainer.addContainerListener(xListener, guard); } void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener ) { LibraryContainerMethodGuard aGuard( *this ); - maNameContainer->removeContainerListener( xListener ); + std::unique_lock guard(m_aMutex); + maNameContainer.removeContainerListener(xListener, guard); } // Methods XLibraryContainerExport @@ -2709,6 +2687,7 @@ void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OU const Reference< XInteractionHandler >& Handler ) { LibraryContainerMethodGuard aGuard( *this ); + std::unique_lock guard(m_aMutex); SfxLibrary* pImplLib = getImplLib( Name ); Reference< XSimpleFileAccess3 > xToUseSFI; @@ -2719,7 +2698,7 @@ void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OU } // Maybe lib is not loaded?! - loadLibrary( Name ); + loadLibrary_Impl(Name, guard); uno::Reference< css::embed::XStorage > xDummyStor; if( pImplLib->mbPasswordProtected ) @@ -2766,7 +2745,7 @@ OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString bool bLink = pImplLib->mbLink; if( !bLink ) { - throw IllegalArgumentException("!link", static_cast<cppu::OWeakObject*>(this), 1); + throw IllegalArgumentException(u"!link"_ustr, getXWeak(), 1); } OUString aRetStr = pImplLib->maOriginalStorageURL; return aRetStr; @@ -2810,7 +2789,7 @@ void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( sal_Bool _vbacompatm { Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW ); - xFactory->createInstance("ooo.vba.VBAGlobals"); + xFactory->createInstance(u"ooo.vba.VBAGlobals"_ustr); } catch(const Exception& ) { @@ -2839,12 +2818,12 @@ sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) { - maVBAScriptListeners.addInterface( rxListener ); + maVBAScriptListeners.addInterface(o3tl::temporary(std::unique_lock(m_aMutex)), rxListener); } void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) { - maVBAScriptListeners.removeInterface( rxListener ); + maVBAScriptListeners.removeInterface(o3tl::temporary(std::unique_lock(m_aMutex)), rxListener); } void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const OUString& rModuleName ) @@ -2864,7 +2843,54 @@ void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifie Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref vba::VBAScriptEvent aEvent( Reference<XInterface>(xModel, UNO_QUERY), nIdentifier, rModuleName ); - maVBAScriptListeners.notifyEach( &css::script::vba::XVBAScriptListener::notifyVBAScriptEvent, aEvent ); + maVBAScriptListeners.notifyEach(o3tl::temporary(std::unique_lock(m_aMutex)), + &css::script::vba::XVBAScriptListener::notifyVBAScriptEvent, + aEvent); +} + +// Methods XPropertySet +css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SfxLibraryContainer::getPropertySetInfo() +{ + return uno::Reference<beans::XPropertySetInfo>(); +} + +void SAL_CALL SfxLibraryContainer::setPropertyValue(const OUString& aPropertyName, + const uno::Any& aValue) +{ + if (aPropertyName != sVBATextEncodingPropName) + throw UnknownPropertyException(aPropertyName, getXWeak()); + aValue >>= meVBATextEncoding; +} + +css::uno::Any SAL_CALL SfxLibraryContainer::getPropertyValue(const OUString& aPropertyName) +{ + if (aPropertyName == sVBATextEncodingPropName) + return uno::Any(meVBATextEncoding); + throw UnknownPropertyException(aPropertyName, getXWeak()); +} + +void SAL_CALL SfxLibraryContainer::addPropertyChangeListener( + const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener>& /* xListener */) +{ + throw NoSupportException(); +} + +void SAL_CALL SfxLibraryContainer::removePropertyChangeListener( + const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener>& /* aListener */) +{ + throw NoSupportException(); +} + +void SAL_CALL SfxLibraryContainer::addVetoableChangeListener( + const OUString& /* PropertyName */, const Reference<XVetoableChangeListener>& /* aListener */) +{ + throw NoSupportException(); +} + +void SAL_CALL SfxLibraryContainer::removeVetoableChangeListener( + const OUString& /* PropertyName */, const Reference<XVetoableChangeListener>& /* aListener */) +{ + throw NoSupportException(); } // Methods XServiceInfo @@ -2878,10 +2904,9 @@ sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const OUString& _rServic // Ctor SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType, const Reference< XSimpleFileAccess3 >& xSFI ) - : OComponentHelper( m_aMutex ) - , mxSFI( xSFI ) + : mxSFI( xSFI ) , mrModifiable( _rModifiable ) - , maNameContainer( new NameContainer(aType) ) + , maNameContainer( aType, *this ) , mbLoaded( true ) , mbIsModified( true ) , mbInitialised( false ) @@ -2899,16 +2924,13 @@ SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType, SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType, const Reference< XSimpleFileAccess3 >& xSFI, - const OUString& aLibInfoFileURL, const OUString& aStorageURL, bool ReadOnly ) - : OComponentHelper( m_aMutex ) - , mxSFI( xSFI ) + OUString aLibInfoFileURL, OUString aStorageURL, bool ReadOnly ) + : mxSFI( xSFI ) , mrModifiable( _rModifiable ) - , maNameContainer( new NameContainer(aType) ) + , maNameContainer( aType, *this ) , mbLoaded( false ) , mbIsModified( true ) , mbInitialised( false ) - , maLibInfoFileURL( aLibInfoFileURL ) - , maStorageURL( aStorageURL ) , mbLink( true ) , mbReadOnly( false ) , mbReadOnlyLink( ReadOnly ) @@ -2918,6 +2940,8 @@ SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType, , mbDoc50Password( false ) , mbSharedIndexFile( false ) , mbExtension( false ) + , maLibInfoFileURL(std::move( aLibInfoFileURL )) + , maStorageURL(std::move( aStorageURL )) { } @@ -2926,7 +2950,7 @@ bool SfxLibrary::isLoadedStorable() return mbLoaded && (!mbPasswordProtected || mbPasswordVerified); } -void SfxLibrary::implSetModified( bool _bIsModified ) +void SfxLibrary::implSetModified(bool _bIsModified, std::unique_lock<std::mutex>& guard) { if ( mbIsModified == _bIsModified ) { @@ -2935,38 +2959,19 @@ void SfxLibrary::implSetModified( bool _bIsModified ) mbIsModified = _bIsModified; if ( mbIsModified ) { - mrModifiable.setModified( true ); + mrModifiable.setModified(true, guard); } } -// Methods XInterface -Any SAL_CALL SfxLibrary::queryInterface( const Type& rType ) -{ - Any aRet = - ::cppu::queryInterface( - rType, - static_cast< XContainer * >( this ), - static_cast< XNameContainer * >( this ), - static_cast< XNameAccess * >( this ), - static_cast< XElementAccess * >( this ), - static_cast< XChangesNotifier * >( this ) ); - if( !aRet.hasValue() ) - { - aRet = OComponentHelper::queryInterface( rType ); - } - return aRet; -} - // Methods XElementAccess Type SfxLibrary::getElementType() { - return maNameContainer->getElementType(); + return maNameContainer.getElementType(); } sal_Bool SfxLibrary::hasElements() { - bool bRet = maNameContainer->hasElements(); - return bRet; + return maNameContainer.hasElements(); } // Methods XNameAccess @@ -2974,18 +2979,17 @@ Any SfxLibrary::getByName( const OUString& aName ) { impl_checkLoaded(); - Any aRetAny = maNameContainer->getByName( aName ) ; - return aRetAny; + return maNameContainer.getByName(aName); } Sequence< OUString > SfxLibrary::getElementNames() { - return maNameContainer->getElementNames(); + return maNameContainer.getElementNames(); } sal_Bool SfxLibrary::hasByName( const OUString& aName ) { - bool bRet = maNameContainer->hasByName( aName ); + bool bRet = maNameContainer.hasByName( aName ); return bRet; } @@ -2994,7 +2998,7 @@ void SfxLibrary::impl_checkReadOnly() if( mbReadOnly || (mbLink && mbReadOnlyLink) ) { throw IllegalArgumentException( - "Library is readonly.", + u"Library is readonly."_ustr, // TODO: resource *this, 0 ); @@ -3026,8 +3030,9 @@ void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement ) !isLibraryElementValid(aElement), "basic", "SfxLibrary::replaceByName: replacing element is invalid!"); - maNameContainer->replaceByName( aName, aElement ); - implSetModified( true ); + std::unique_lock guard(m_aMutex); + maNameContainer.replaceByName(aName, aElement, guard); + implSetModified(true, guard); } @@ -3041,14 +3046,16 @@ void SfxLibrary::insertByName( const OUString& aName, const Any& aElement ) !isLibraryElementValid(aElement), "basic", "SfxLibrary::insertByName: to-be-inserted element is invalid!"); - maNameContainer->insertByName( aName, aElement ); - implSetModified( true ); + std::unique_lock guard(m_aMutex); + maNameContainer.insertByName(aName, aElement, guard); + implSetModified(true, guard); } -void SfxLibrary::impl_removeWithoutChecks( const OUString& _rElementName ) +void SfxLibrary::impl_removeWithoutChecks(const OUString& _rElementName, + std::unique_lock<std::mutex>& guard) { - maNameContainer->removeByName( _rElementName ); - implSetModified( true ); + maNameContainer.removeByName(_rElementName, guard); + implSetModified(true, guard); // Remove element file if( maStorageURL.isEmpty() ) @@ -3078,49 +3085,31 @@ void SfxLibrary::removeByName( const OUString& Name ) { impl_checkReadOnly(); impl_checkLoaded(); - impl_removeWithoutChecks( Name ); -} - -// XTypeProvider -Sequence< Type > SfxLibrary::getTypes() -{ - static OTypeCollection ourTypes_NameContainer( - cppu::UnoType<XNameContainer>::get(), - cppu::UnoType<XContainer>::get(), - cppu::UnoType<XChangesNotifier>::get(), - OComponentHelper::getTypes() ); - - return ourTypes_NameContainer.getTypes(); -} - - -Sequence< sal_Int8 > SfxLibrary::getImplementationId() -{ - return css::uno::Sequence<sal_Int8>(); + impl_removeWithoutChecks(Name, o3tl::temporary(std::unique_lock(m_aMutex))); } // Methods XContainer void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener ) { - maNameContainer->setEventSource( static_cast< XInterface* >( static_cast<OWeakObject*>(this) ) ); - maNameContainer->addContainerListener( xListener ); + maNameContainer.setEventSource( getXWeak() ); + maNameContainer.addContainerListener(xListener, o3tl::temporary(std::unique_lock(m_aMutex))); } void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener ) { - maNameContainer->removeContainerListener( xListener ); + maNameContainer.removeContainerListener(xListener, o3tl::temporary(std::unique_lock(m_aMutex))); } // Methods XChangesNotifier void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener ) { - maNameContainer->setEventSource( static_cast< XInterface* >( static_cast<OWeakObject*>(this) ) ); - maNameContainer->addChangesListener( xListener ); + maNameContainer.setEventSource( getXWeak() ); + maNameContainer.addChangesListener(xListener, o3tl::temporary(std::unique_lock(m_aMutex))); } void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener ) { - maNameContainer->removeChangesListener( xListener ); + maNameContainer.removeChangesListener(xListener, o3tl::temporary(std::unique_lock(m_aMutex))); } @@ -3242,11 +3231,10 @@ Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPack } if( m_bIsBundle ) { - const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray(); sal_Int32 iPkg; for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg ) { - const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ]; + const Reference<deployment::XPackage> xSubPkg = m_aSubPkgSeq[iPkg]; xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib ); if( xScriptPackage.is() ) { @@ -3296,7 +3284,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScript try { Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext ); - m_aUserPackagesSeq = xManager->getDeployedExtensions("user", + m_aUserPackagesSeq = xManager->getDeployedExtensions(u"user"_ustr, Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); } @@ -3318,8 +3306,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScript { if( m_pScriptSubPackageIterator == nullptr ) { - const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray(); - Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ]; + Reference<deployment::XPackage> xPackage = m_aUserPackagesSeq[m_iUserPackage]; SAL_WARN_IF( !xPackage.is(), "basic", ("ScriptExtensionIterator::implGetNextUserScriptPackage():" @@ -3348,7 +3335,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScri try { Reference< XExtensionManager > xSharedManager = ExtensionManager::get( m_xContext ); - m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions("shared", + m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions(u"shared"_ustr, Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); } @@ -3369,8 +3356,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScri { if( m_pScriptSubPackageIterator == nullptr ) { - const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray(); - Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ]; + Reference<deployment::XPackage> xPackage = m_aSharedPackagesSeq[m_iSharedPackage]; SAL_WARN_IF( !xPackage.is(), "basic", ("ScriptExtensionIterator::implGetNextSharedScriptPackage():" @@ -3399,7 +3385,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScr try { Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext ); - m_aBundledPackagesSeq = xManager->getDeployedExtensions("bundled", + m_aBundledPackagesSeq = xManager->getDeployedExtensions(u"bundled"_ustr, Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); } @@ -3420,8 +3406,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScr { if( m_pScriptSubPackageIterator == nullptr ) { - const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray(); - Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ]; + Reference<deployment::XPackage> xPackage = m_aBundledPackagesSeq[m_iBundledPackage]; SAL_WARN_IF( !xPackage.is(), "basic", ("ScriptExtensionIterator::implGetNextBundledScriptPackage():" |