From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- .../registry/script/dp_lib_container.cxx | 64 +++ .../deployment/registry/script/dp_lib_container.h | 48 +++ .../deployment/registry/script/dp_script.cxx | 480 +++++++++++++++++++++ .../registry/script/dp_scriptbackenddb.cxx | 64 +++ .../registry/script/dp_scriptbackenddb.hxx | 55 +++ 5 files changed, 711 insertions(+) create mode 100644 desktop/source/deployment/registry/script/dp_lib_container.cxx create mode 100644 desktop/source/deployment/registry/script/dp_lib_container.h create mode 100644 desktop/source/deployment/registry/script/dp_script.cxx create mode 100644 desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx create mode 100644 desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx (limited to 'desktop/source/deployment/registry/script') diff --git a/desktop/source/deployment/registry/script/dp_lib_container.cxx b/desktop/source/deployment/registry/script/dp_lib_container.cxx new file mode 100644 index 000000000..3a6f30253 --- /dev/null +++ b/desktop/source/deployment/registry/script/dp_lib_container.cxx @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include +#include + +#include +#include +#include +#include +#include "dp_lib_container.h" + +#include +#include +#include + + +using namespace ::dp_misc; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; + +namespace dp_registry::backend::script { + +namespace { + OUString StrCannotDetermineLibName() { return DpResId(RID_STR_CANNOT_DETERMINE_LIBNAME); } +} + +OUString LibraryContainer::get_libname( + OUString const & url, + Reference const & xCmdEnv, + Reference const & xContext ) +{ + ::xmlscript::LibDescriptor import; + ::ucbhelper::Content ucb_content( url, xCmdEnv, xContext ); + xml_parse( ::xmlscript::importLibrary( import ), ucb_content, xContext ); + + if (import.aName.isEmpty()) { + throw Exception( StrCannotDetermineLibName(), + Reference() ); + } + return import.aName; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/source/deployment/registry/script/dp_lib_container.h b/desktop/source/deployment/registry/script/dp_lib_container.h new file mode 100644 index 000000000..fbbedf866 --- /dev/null +++ b/desktop/source/deployment/registry/script/dp_lib_container.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include + +namespace com::sun::star { + namespace uno { + class XComponentContext; + } + namespace ucb { + class XCommandEnvironment; + } +} + + +namespace dp_registry::backend::script { + + +class LibraryContainer +{ +public: + static OUString get_libname( + OUString const & url, + css::uno::Reference const & xCmdEnv, + css::uno::Reference const & xContext ); +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/source/deployment/registry/script/dp_script.cxx b/desktop/source/deployment/registry/script/dp_script.cxx new file mode 100644 index 000000000..47e41a364 --- /dev/null +++ b/desktop/source/deployment/registry/script/dp_script.cxx @@ -0,0 +1,480 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include +#include "dp_lib_container.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dp_scriptbackenddb.hxx" +#include + +using namespace ::dp_misc; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; + +namespace dp_registry::backend::script { +namespace { + +typedef ::cppu::ImplInheritanceHelper< + ::dp_registry::backend::PackageRegistryBackend, util::XUpdatable > t_helper; + +class BackendImpl : public t_helper +{ + class PackageImpl : public ::dp_registry::backend::Package + { + BackendImpl * getMyBackend() const; + + const OUString m_scriptURL; + const OUString m_dialogURL; + OUString m_dialogName; + + // Package + virtual beans::Optional< beans::Ambiguous > isRegistered_( + ::osl::ResettableMutexGuard & guard, + ::rtl::Reference const & abortChannel, + Reference const & xCmdEnv ) override; + virtual void processPackage_( + ::osl::ResettableMutexGuard & guard, + bool registerPackage, + bool startup, + ::rtl::Reference const & abortChannel, + Reference const & xCmdEnv ) override; + + public: + PackageImpl( + ::rtl::Reference const & myBackend, + OUString const & url, + Reference const &xCmdEnv, + OUString const & scriptURL, OUString const & dialogURL, + bool bRemoved, OUString const & identifier); + }; + friend class PackageImpl; + + // PackageRegistryBackend + virtual Reference bindPackage_( + OUString const & url, OUString const & mediaType, + bool bRemoved, OUString const & identifier, + Reference const & xCmdEnv ) override; + + void addDataToDb(OUString const & url); + bool hasActiveEntry(std::u16string_view url); + void revokeEntryFromDb(std::u16string_view url); + + const Reference m_xBasicLibTypeInfo; + const Reference m_xDialogLibTypeInfo; + Sequence< Reference > m_typeInfos; + std::unique_ptr m_backendDb; +public: + BackendImpl( Sequence const & args, + Reference const & xComponentContext ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XUpdatable + virtual void SAL_CALL update() override; + + // XPackageRegistry + virtual Sequence< Reference > SAL_CALL + getSupportedPackageTypes() override; + virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) override; + +}; + + +BackendImpl::PackageImpl::PackageImpl( + ::rtl::Reference const & myBackend, + OUString const & url, + Reference const &xCmdEnv, + OUString const & scriptURL, OUString const & dialogURL, bool bRemoved, + OUString const & identifier) + : Package( myBackend, url, + OUString(), OUString(), // will be late-initialized + !scriptURL.isEmpty() ? myBackend->m_xBasicLibTypeInfo + : myBackend->m_xDialogLibTypeInfo, bRemoved, identifier), + m_scriptURL( scriptURL ), + m_dialogURL( dialogURL ) +{ + // name, displayName: + if (!dialogURL.isEmpty()) { + m_dialogName = LibraryContainer::get_libname( + dialogURL, xCmdEnv, myBackend->getComponentContext() ); + } + if (!scriptURL.isEmpty()) { + assert(m_name.pData); + m_name = LibraryContainer::get_libname( + scriptURL, xCmdEnv, myBackend->getComponentContext() ); + } + else + m_name = m_dialogName; + m_displayName = m_name; +} + + +BackendImpl::BackendImpl( + Sequence const & args, + Reference const & xComponentContext ) + : t_helper( args, xComponentContext ), + m_xBasicLibTypeInfo( new Package::TypeInfo( + "application/vnd.sun.star.basic-library", + OUString() /* no file filter */, + DpResId(RID_STR_BASIC_LIB) + ) ), + m_xDialogLibTypeInfo( new Package::TypeInfo( + "application/vnd.sun.star.dialog-library", + OUString() /* no file filter */, + DpResId(RID_STR_DIALOG_LIB) + ) ), + m_typeInfos{ m_xBasicLibTypeInfo, m_xDialogLibTypeInfo } +{ + OSL_ASSERT( ! transientMode() ); + + if (!transientMode()) + { + OUString dbFile = makeURL(getCachePath(), "backenddb.xml"); + m_backendDb.reset( + new ScriptBackendDb(getComponentContext(), dbFile)); + } + +} + +// XServiceInfo +OUString BackendImpl::getImplementationName() +{ + return "com.sun.star.comp.deployment.script.PackageRegistryBackend"; +} + +sal_Bool BackendImpl::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +css::uno::Sequence< OUString > BackendImpl::getSupportedServiceNames() +{ + return { BACKEND_SERVICE_NAME }; +} + +void BackendImpl::addDataToDb(OUString const & url) +{ + if (m_backendDb) + m_backendDb->addEntry(url); +} + +bool BackendImpl::hasActiveEntry(std::u16string_view url) +{ + if (m_backendDb) + return m_backendDb->hasActiveEntry(url); + return false; +} + +// XUpdatable + +void BackendImpl::update() +{ + // Nothing to do here after fixing i70283!? +} + +// XPackageRegistry + +Sequence< Reference > +BackendImpl::getSupportedPackageTypes() +{ + return m_typeInfos; +} +void BackendImpl::revokeEntryFromDb(std::u16string_view url) +{ + if (m_backendDb) + m_backendDb->revokeEntry(url); +} + +void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/) +{ + if (m_backendDb) + m_backendDb->removeEntry(url); +} + +// PackageRegistryBackend + +Reference BackendImpl::bindPackage_( + OUString const & url, OUString const & mediaType_, + bool bRemoved, OUString const & identifier, + Reference const & xCmdEnv ) +{ + OUString mediaType( mediaType_ ); + if (mediaType.isEmpty()) + { + // detect media-type: + ::ucbhelper::Content ucbContent; + if (create_ucb_content( &ucbContent, url, xCmdEnv ) && + ucbContent.isFolder()) + { + // probe for script.xlb: + if (create_ucb_content( + nullptr, makeURL( url, "script.xlb" ), + xCmdEnv, false /* no throw */ )) + mediaType = "application/vnd.sun.star.basic-library"; + // probe for dialog.xlb: + else if (create_ucb_content( + nullptr, makeURL( url, "dialog.xlb" ), + xCmdEnv, false /* no throw */ )) + mediaType = "application/vnd.sun.star.dialog-library"; + } + if (mediaType.isEmpty()) + throw lang::IllegalArgumentException( + StrCannotDetectMediaType() + url, + static_cast(this), static_cast(-1) ); + } + + OUString type, subType; + INetContentTypeParameterList params; + if (INetContentTypes::parse( mediaType, type, subType, ¶ms )) + { + if (type.equalsIgnoreAsciiCase("application")) + { + OUString dialogURL( makeURL( url, "dialog.xlb" ) ); + if (! create_ucb_content( + nullptr, dialogURL, xCmdEnv, false /* no throw */ )) { + dialogURL.clear(); + } + + if (subType.equalsIgnoreAsciiCase("vnd.sun.star.basic-library")) + { + OUString scriptURL( makeURL( url, "script.xlb")); + if (! create_ucb_content( + nullptr, scriptURL, xCmdEnv, false /* no throw */ )) { + scriptURL.clear(); + } + + return new PackageImpl( + this, url, xCmdEnv, scriptURL, + dialogURL, bRemoved, identifier); + } + else if (subType.equalsIgnoreAsciiCase( + "vnd.sun.star.dialog-library")) { + return new PackageImpl( + this, url, xCmdEnv, + OUString() /* no script lib */, + dialogURL, + bRemoved, identifier); + } + } + } + throw lang::IllegalArgumentException( + StrUnsupportedMediaType() + mediaType, + static_cast(this), + static_cast(-1) ); +} + + +// Package +BackendImpl * BackendImpl::PackageImpl::getMyBackend() const +{ + BackendImpl * pBackend = static_cast(m_myBackend.get()); + if (nullptr == pBackend) + { + //May throw a DisposedException + check(); + //We should never get here... + throw RuntimeException( + "Failed to get the BackendImpl", + static_cast(const_cast(this))); + } + return pBackend; +} + +beans::Optional< beans::Ambiguous > +BackendImpl::PackageImpl::isRegistered_( + ::osl::ResettableMutexGuard & /* guard */, + ::rtl::Reference const & /* abortChannel */, + Reference const & /* xCmdEnv */ ) +{ + BackendImpl * that = getMyBackend(); + Reference< deployment::XPackage > xThisPackage( this ); + + bool registered = that->hasActiveEntry(getURL()); + return beans::Optional< beans::Ambiguous >( + true /* IsPresent */, + beans::Ambiguous( registered, false /* IsAmbiguous */ ) ); +} + +void +lcl_maybeRemoveScript( + bool const bExists, + OUString const& rName, + std::u16string_view rScriptURL, + Reference const& xScriptLibs) +{ + if (bExists && xScriptLibs.is() && xScriptLibs->hasByName(rName)) + { + const OUString sScriptUrl = xScriptLibs->getOriginalLibraryLinkURL(rName); + if (sScriptUrl == rScriptURL) + xScriptLibs->removeLibrary(rName); + } +} + +bool +lcl_maybeAddScript( + bool const bExists, + OUString const& rName, + OUString const& rScriptURL, + Reference const& xScriptLibs) +{ + if (!bExists || !xScriptLibs) + return false; + + bool bCanAdd = true; + if (xScriptLibs->hasByName(rName)) + { + const OUString sOriginalUrl = xScriptLibs->getOriginalLibraryLinkURL(rName); + //We assume here that library names in extensions are unique, which may not be the case + //ToDo: If the script exist in another extension, then both extensions must have the + //same id + if (sOriginalUrl.match("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE") + || sOriginalUrl.match("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE") + || sOriginalUrl.match("vnd.sun.star.expand:$BUNDLED_EXTENSIONS") + || sOriginalUrl.match("$(INST)/share/basic/Access2Base/")) + { + xScriptLibs->removeLibrary(rName); + bCanAdd = true; + } + else + { + bCanAdd = false; + } + } + + if (bCanAdd) + { + xScriptLibs->createLibraryLink(rName, rScriptURL, false); + return xScriptLibs->hasByName(rName); + } + + return false; +} + +void BackendImpl::PackageImpl::processPackage_( + ::osl::ResettableMutexGuard & /* guard */, + bool doRegisterPackage, + bool startup, + ::rtl::Reference const & /* abortChannel */, + Reference const & /* xCmdEnv */ ) +{ + BackendImpl * that = getMyBackend(); + + Reference< deployment::XPackage > xThisPackage( this ); + Reference const & xComponentContext = that->getComponentContext(); + + bool bScript = !m_scriptURL.isEmpty(); + Reference xScriptLibs; + + bool bDialog = !m_dialogURL.isEmpty(); + Reference xDialogLibs; + + bool bRunning = !startup && office_is_running(); + if( bRunning ) + { + if( bScript ) + { + xScriptLibs.set( + xComponentContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.script.ApplicationScriptLibraryContainer", + xComponentContext ), UNO_QUERY_THROW ); + } + + if( bDialog ) + { + xDialogLibs.set( + xComponentContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.script.ApplicationDialogLibraryContainer", + xComponentContext ), UNO_QUERY_THROW ); + } + } + bool bRegistered = getMyBackend()->hasActiveEntry(getURL()); + if( !doRegisterPackage ) + { + //We cannot just call removeLibrary(name) because this could remove a + //script which was added by an extension in a different repository. For + //example, extension foo is contained in the bundled repository and then + //the user adds it to the user repository. The extension manager will + //then register the new script and revoke the script from the bundled + //extension. removeLibrary(name) would now remove the script from the + //user repository. That is, the script of the newly added user extension does + //not work anymore. Therefore we must check if the currently active + //script comes in fact from the currently processed extension. + + if (bRegistered) + { + //we also prevent and live deployment at startup + if (!isRemoved() && !startup) + { + lcl_maybeRemoveScript(bScript, m_name, m_scriptURL, xScriptLibs); + lcl_maybeRemoveScript(bDialog, m_dialogName, m_dialogURL, xDialogLibs); + } + getMyBackend()->revokeEntryFromDb(getURL()); + return; + } + } + if (bRegistered) + return; // Already registered + + // Update LibraryContainer + bool bScriptSuccess = false; + bool bDialogSuccess = false; + if (!startup) + { + //If there is a bundled extension, and the user installs the same extension + //then the script from the bundled extension must be removed. If this does not work + //then live deployment does not work for scripts. + bScriptSuccess = lcl_maybeAddScript(bScript, m_name, m_scriptURL, xScriptLibs); + bDialogSuccess = lcl_maybeAddScript(bDialog, m_dialogName, m_dialogURL, xDialogLibs); + } + bool bSuccess = bScript || bDialog; // Something must have happened + if( bRunning ) + if( (bScript && !bScriptSuccess) || (bDialog && !bDialogSuccess) ) + bSuccess = false; + + if (bSuccess) + getMyBackend()->addDataToDb(getURL()); +} + +} // anon namespace + +} // namespace dp_registry::backend::script + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_deployment_script_PackageRegistryBackend_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence const& args) +{ + return cppu::acquire(new dp_registry::backend::script::BackendImpl(args, context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx new file mode 100644 index 000000000..476f43953 --- /dev/null +++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include +#include "dp_scriptbackenddb.hxx" + + +using namespace ::com::sun::star::uno; + +constexpr OUStringLiteral EXTENSION_REG_NS = u"http://openoffice.org/extensionmanager/script-registry/2010"; +constexpr OUStringLiteral NS_PREFIX = u"script"; +constexpr OUStringLiteral ROOT_ELEMENT_NAME = u"script-backend-db"; +constexpr OUStringLiteral KEY_ELEMENT_NAME = u"script"; + +namespace dp_registry::backend::script { + +ScriptBackendDb::ScriptBackendDb( + Reference const & xContext, + OUString const & url):RegisteredDb(xContext, url) +{ + +} + +OUString ScriptBackendDb::getDbNSName() +{ + return EXTENSION_REG_NS; +} + +OUString ScriptBackendDb::getNSPrefix() +{ + return NS_PREFIX; +} + +OUString ScriptBackendDb::getRootElementName() +{ + return ROOT_ELEMENT_NAME; +} + +OUString ScriptBackendDb::getKeyElementName() +{ + return KEY_ELEMENT_NAME; +} + + +} // namespace dp_registry::backend::script + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx new file mode 100644 index 000000000..21d4b1f6b --- /dev/null +++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include +#include +#include + +namespace com::sun::star::uno { class XComponentContext; } + +namespace dp_registry::backend::script { + +/* The XML file stores the extensions which are currently registered. + They will be removed when they are revoked. + */ +class ScriptBackendDb: public dp_registry::backend::RegisteredDb +{ +protected: + virtual OUString getDbNSName() override; + + virtual OUString getNSPrefix() override; + + virtual OUString getRootElementName() override; + + virtual OUString getKeyElementName() override; + + +public: + + ScriptBackendDb( css::uno::Reference const & xContext, + OUString const & url); +}; + + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3