diff options
author | Joachim Lingner <jl@openoffice.org> | 2010-04-19 11:33:33 +0200 |
---|---|---|
committer | Joachim Lingner <jl@openoffice.org> | 2010-04-19 11:33:33 +0200 |
commit | 3c289e248a4f7c6940bb7429ee70d17a6196016c (patch) | |
tree | a5e449c5cc48918708f7bc98dc921a49db95ca70 /desktop/source | |
parent | fb70a4cd3b77e0ea6bb5820b47bfd7ea39fa3228 (diff) |
jl152 import 263446 from native0jl:#i77196# supporting licenses, suppress license switch, subsequent accepting of licenses for bundled/shared extensions
Diffstat (limited to 'desktop/source')
39 files changed, 1402 insertions, 827 deletions
diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx index 17dc20e1a129..f487e0dfc96f 100644 --- a/desktop/source/app/check_ext_deps.cxx +++ b/desktop/source/app/check_ext_deps.cxx @@ -53,6 +53,8 @@ #include "app.hxx" +#include "../deployment/inc/dp_misc.h" + using rtl::OUString; using namespace desktop; using namespace com::sun::star; @@ -342,101 +344,6 @@ sal_Bool Desktop::CheckExtensionDependencies() return bAbort; } -//Returns true if the Folder was more recently modified then -//the lastsynchronized file. That is the repository needs to -//be synchronized. -static bool compareExtensionFolderWithLastSynchronizedFile( - OUString const & folderURL, OUString const & fileURL) -{ - bool bNeedsSync = false; - ::osl::DirectoryItem itemExtFolder; - ::osl::File::RC err1 = - ::osl::DirectoryItem::get(folderURL, itemExtFolder); - //If it does not exist, then there is nothing to be done - if (err1 == ::osl::File::E_NOENT) - { - return false; - } - else if (err1 != ::osl::File::E_None) - { - OSL_ENSURE(0, "Cannot access extension folder"); - return true; //sync just in case - } - - //If last synchronized does not exist, then OOo is started for the first time - ::osl::DirectoryItem itemFile; - ::osl::File::RC err2 = ::osl::DirectoryItem::get(fileURL, itemFile); - if (err2 == ::osl::File::E_NOENT) - { - return true; - - } - else if (err2 != ::osl::File::E_None) - { - OSL_ENSURE(0, "Cannot access file lastsynchronized"); - return true; //sync just in case - } - - //compare the modification time of the extension folder and the last - //modified file - ::osl::FileStatus statFolder(FileStatusMask_ModifyTime); - ::osl::FileStatus statFile(FileStatusMask_ModifyTime); - if (itemExtFolder.getFileStatus(statFolder) == ::osl::File::E_None) - { - if (itemFile.getFileStatus(statFile) == ::osl::File::E_None) - { - TimeValue timeFolder = statFolder.getModifyTime(); - TimeValue timeFile = statFile.getModifyTime(); - - if (timeFile.Seconds < timeFolder.Seconds) - bNeedsSync = true; - } - else - { - OSL_ASSERT(0); - bNeedsSync = true; - } - } - else - { - OSL_ASSERT(0); - bNeedsSync = true; - } - return bNeedsSync; -} - -static bool needToSyncRepostitory(OUString const & name) -{ - OUString folder; - OUString file; - if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled")))) - { - folder = OUString( - RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS")); - file = OUString ( - RTL_CONSTASCII_USTRINGPARAM( - "$BUNDLED_EXTENSIONS_USER/lastsynchronized")); - } - else if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))) - { - folder = OUString( - RTL_CONSTASCII_USTRINGPARAM( - "$UNO_SHARED_PACKAGES_CACHE/uno_packages")); - file = OUString ( - RTL_CONSTASCII_USTRINGPARAM( - "$SHARED_EXTENSIONS_USER/lastsynchronized")); - } - else - { - OSL_ASSERT(0); - return true; - } - ::rtl::Bootstrap::expandMacros(folder); - ::rtl::Bootstrap::expandMacros(file); - return compareExtensionFolderWithLastSynchronizedFile( - folder, file); -} - void Desktop::SynchronizeExtensionRepositories() { RTL_LOGFILE_CONTEXT(aLog,"desktop (jl97489) ::Desktop::SynchronizeExtensionRepositories"); @@ -447,41 +354,5 @@ void Desktop::SynchronizeExtensionRepositories() OUString(RTL_CONSTASCII_USTRINGPARAM(""))); if (sDisable.getLength() > 0) return; - Reference<deployment::XExtensionManager> xExtensionManager; - //synchronize shared before bundled otherewise there are - //more revoke and registration calls. - OUString sShared(RTL_CONSTASCII_USTRINGPARAM("shared")); - if (needToSyncRepostitory(sShared)) - { - xExtensionManager = - deployment::ExtensionManager::get( - comphelper_getProcessComponentContext()); - if (xExtensionManager.is()) - { - Reference<ucb::XCommandEnvironment> cmdEnv( - new SilentCommandEnv()); - xExtensionManager->synchronize( - sShared, Reference<task::XAbortChannel>(), cmdEnv); - } - - } - - OUString sBundled(RTL_CONSTASCII_USTRINGPARAM("bundled")); - if (needToSyncRepostitory( sBundled)) - { - if (!xExtensionManager.is()) - { - xExtensionManager = - deployment::ExtensionManager::get( - comphelper_getProcessComponentContext()); - } - if (xExtensionManager.is()) - { - Reference<ucb::XCommandEnvironment> cmdEnv( - new SilentCommandEnv()); - xExtensionManager->synchronize( - sBundled, Reference<task::XAbortChannel>(), cmdEnv); - - } - } + dp_misc::syncRepositories(new SilentCommandEnv()); } diff --git a/desktop/source/app/makefile.mk b/desktop/source/app/makefile.mk index d9db7c163481..085d8520e7ad 100644 --- a/desktop/source/app/makefile.mk +++ b/desktop/source/app/makefile.mk @@ -35,11 +35,24 @@ ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk +.INCLUDE : ../deployment/inc/dp_misc.mk .IF "$(ENABLE_GNOMEVFS)"=="TRUE" CFLAGS+=-DGNOME_VFS_ENABLED .ENDIF +# .IF "$(OS)" == "WNT" +# .IF "$(COM)" == "GCC" +# DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX) +# .ELSE +# DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib +# .ENDIF +# .ELIF "$(OS)" == "OS2" +# DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib +# .ELSE +# DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX) +# .ENDIF + SHL1TARGET = sofficeapp SHL1OBJS = \ $(SLO)$/app.obj \ @@ -67,6 +80,7 @@ SHL1STDLIBS = \ $(COMPHELPERLIB) \ $(CPPUHELPERLIB) \ $(CPPULIB) \ + $(DEPLOYMENTMISCLIB) \ $(I18NISOLANGLIB) \ $(SALLIB) \ $(SFXLIB) \ diff --git a/desktop/source/deployment/gui/dp_gui.hrc b/desktop/source/deployment/gui/dp_gui.hrc index 1d2f4869cc7f..022141976f55 100644 --- a/desktop/source/deployment/gui/dp_gui.hrc +++ b/desktop/source/deployment/gui/dp_gui.hrc @@ -172,7 +172,6 @@ #define RID_WARNINGBOX_DISABLE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+106) #define RID_DLG_LICENSE RID_DEPLOYMENT_LICENSE_START -#define WARNINGBOX_NOSHAREDALLOWED (RID_DEPLOYMENT_LICENSE_START+1) diff --git a/desktop/source/deployment/gui/dp_gui_dialog.src b/desktop/source/deployment/gui/dp_gui_dialog.src index 79c0c5172030..f9d9c0e011c6 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog.src +++ b/desktop/source/deployment/gui/dp_gui_dialog.src @@ -131,7 +131,7 @@ String RID_STR_ERROR_MISSING_DEPENDENCIES #define ROW1_Y RSC_SP_DLG_INNERBORDER_TOP #define ROW1_HEIGHT 16*RSC_CD_FIXEDTEXT_HEIGHT #define ROW2_Y ROW1_Y+ROW1_HEIGHT+RSC_SP_CTRL_GROUP_Y -#define ROW2_HEIGHT 2*RSC_CD_FIXEDTEXT_HEIGHT +#define ROW2_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT #define ROW3_Y ROW2_Y+ROW2_HEIGHT+RSC_SP_CTRL_GROUP_Y #define ROW3_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT #define ROW4_Y ROW3_Y+ROW3_HEIGHT+RSC_SP_CTRL_GROUP_Y @@ -282,14 +282,6 @@ ModalDialog RID_DLG_LICENSE -WarningBox WARNINGBOX_NOSHAREDALLOWED -{ - Buttons = WB_OK ; - DefButton = WB_DEF_OK; - Message[ en-US ] ="The extension \'%NAME\' cannot be installed under \"%PRODUCTNAME Extensions\", because " - "every user has to agree to the license agreement of the extension. The extension will not be installed."; -}; - WarningBox RID_WARNINGBOX_INSTALL_EXTENSION { Buttons = WB_OK_CANCEL; DefButton = WB_DEF_OK; diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx index a617e07758c7..4b55a93d3f84 100644 --- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx +++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx @@ -36,10 +36,10 @@ #include <cstddef> #include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/beans/NamedValue.hpp" #include "com/sun/star/deployment/DependencyException.hpp" #include "com/sun/star/deployment/LicenseException.hpp" -#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp" #include "com/sun/star/deployment/VersionException.hpp" #include "com/sun/star/deployment/InstallException.hpp" #include "com/sun/star/deployment/PlatformException.hpp" @@ -379,7 +379,6 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & lang::WrappedTargetException wtExc; deployment::DependencyException depExc; deployment::LicenseException licExc; - deployment::LicenseIndividualAgreementException licAgreementExc; deployment::VersionException verExc; deployment::InstallException instExc; deployment::PlatformException platExc; @@ -441,23 +440,12 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & || (n == RET_CANCEL && !Application::IsDialogCancelEnabled()); } } - else if (request >>= licAgreementExc) - { - vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ResId warnId(WARNINGBOX_NOSHAREDALLOWED, *DeploymentGuiResMgr::get()); - WarningBox warn( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, warnId); - String msgText = warn.GetMessText(); - msgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); - msgText.SearchAndReplaceAllAscii("%NAME", licAgreementExc.ExtensionName); - warn.SetMessText(msgText); - warn.Execute(); - abort = true; - } else if (request >>= licExc) { uno::Reference< ui::dialogs::XExecutableDialog > xDialog( deployment::ui::LicenseDialog::create( - m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ), licExc.Text ) ); + m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ), + licExc.ExtensionName, licExc.Text ) ); sal_Int16 res = xDialog->execute(); if ( res == ui::dialogs::ExecutableDialogResults::CANCEL ) abort = true; @@ -948,8 +936,9 @@ void ExtensionCmdQueue::Thread::_addExtension( ::rtl::Reference< ProgressCmdEnv { OUString sPackageManager = xPackageManager->getContext(); uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager(); - uno::Reference< deployment::XPackage > xPackage( xExtMgr->addExtension( rPackageURL, sPackageManager, - xAbortChannel, rCmdEnv.get() ) ); + uno::Reference< deployment::XPackage > xPackage( + xExtMgr->addExtension(rPackageURL, uno::Sequence<beans::NamedValue>(), + sPackageManager, xAbortChannel, rCmdEnv.get() ) ); OSL_ASSERT( xPackage.is() ); } catch ( ucb::CommandFailedException & ) diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx index 113e6d2069ac..f607713118f0 100644 --- a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx +++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx @@ -46,6 +46,7 @@ #include "cppuhelper/implbase3.hxx" #include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/beans/NamedValue.hpp" #include "com/sun/star/xml/dom/XElement.hpp" #include "com/sun/star/xml/dom/XNode.hpp" #include "com/sun/star/xml/dom/XNodeList.hpp" @@ -504,7 +505,8 @@ void UpdateInstallDialog::Thread::installExtensions() m_abort = xAbortChannel; } xPackage = curData.aPackageManager->addPackage( - curData.sLocalURL, OUString(), xAbortChannel, m_updateCmdEnv.get()); + curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(), + OUString(), xAbortChannel, m_updateCmdEnv.get()); } catch (css::deployment::DeploymentException & de) { diff --git a/desktop/source/deployment/gui/license_dialog.cxx b/desktop/source/deployment/gui/license_dialog.cxx index 50992eb07a97..9698e257b953 100644 --- a/desktop/source/deployment/gui/license_dialog.cxx +++ b/desktop/source/deployment/gui/license_dialog.cxx @@ -116,6 +116,7 @@ struct LicenseDialogImpl : public ModalDialog LicenseDialogImpl( Window * pParent, css::uno::Reference< css::uno::XComponentContext > const & xContext, + const ::rtl::OUString & sExtensionName, const ::rtl::OUString & sLicenseText); virtual void Activate(); @@ -193,6 +194,7 @@ void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint ) LicenseDialogImpl::LicenseDialogImpl( Window * pParent, cssu::Reference< cssu::XComponentContext > const & xContext, + const ::rtl::OUString & sExtensionName, const ::rtl::OUString & sLicenseText): ModalDialog(pParent, DpGuiResId(RID_DLG_LICENSE)) ,m_xComponentContext(xContext) @@ -225,6 +227,7 @@ LicenseDialogImpl::LicenseDialogImpl( m_fiArrow1.Show(true); m_fiArrow2.Show(false); m_mlLicense.SetText(sLicenseText); + m_ftHead.SetText(m_ftHead.GetText() + OUString('\n') + sExtensionName); m_mlLicense.SetEndReachedHdl( LINK(this, LicenseDialogImpl, EndReachedHdl) ); m_mlLicense.SetScrolledHdl( LINK(this, LicenseDialogImpl, ScrolledHdl) ); @@ -296,7 +299,7 @@ LicenseDialog::LicenseDialog( Sequence<Any> const& args, Reference<XComponentContext> const& xComponentContext) : m_xComponentContext(xComponentContext) { - comphelper::unwrapArgs( args, m_parent, m_sLicenseText ); + comphelper::unwrapArgs( args, m_parent, m_sExtensionName, m_sLicenseText ); } // XExecutableDialog @@ -315,8 +318,10 @@ sal_Int16 LicenseDialog::execute() throw (RuntimeException) sal_Int16 LicenseDialog::solar_execute() { - std::auto_ptr<LicenseDialogImpl> dlg(new LicenseDialogImpl( - VCLUnoHelper::GetWindow(m_parent), m_xComponentContext, m_sLicenseText)); + std::auto_ptr<LicenseDialogImpl> dlg( + new LicenseDialogImpl( + VCLUnoHelper::GetWindow(m_parent), + m_xComponentContext, m_sExtensionName, m_sLicenseText)); return dlg->Execute(); } diff --git a/desktop/source/deployment/gui/license_dialog.hxx b/desktop/source/deployment/gui/license_dialog.hxx index 4733922dc607..bb4a6b6646c8 100644 --- a/desktop/source/deployment/gui/license_dialog.hxx +++ b/desktop/source/deployment/gui/license_dialog.hxx @@ -48,6 +48,7 @@ class LicenseDialog { Reference<XComponentContext> const m_xComponentContext; Reference<awt::XWindow> /* const */ m_parent; + OUString m_sExtensionName; OUString /* const */ m_sLicenseText; OUString m_initialTitle; diff --git a/desktop/source/deployment/inc/dp_misc.h b/desktop/source/deployment/inc/dp_misc.h index ee5867a655d3..3283d20718be 100644 --- a/desktop/source/deployment/inc/dp_misc.h +++ b/desktop/source/deployment/inc/dp_misc.h @@ -36,6 +36,7 @@ #include "com/sun/star/lang/XComponent.hpp" #include "com/sun/star/lang/DisposedException.hpp" #include "com/sun/star/deployment/XPackageRegistry.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" #include "com/sun/star/awt/XWindow.hpp" #include "dp_misc_api.hxx" @@ -168,8 +169,12 @@ void TRACE(::rtl::OUString const & sText); DESKTOP_DEPLOYMENTMISC_DLLPUBLIC void TRACE(::rtl::OString const & sText); +/** registers or revokes shared or bundled extensions which have been + recently added or removed. +*/ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC -bool hasExtensionRepositoryChanged(::rtl::OUString const & repository); +void syncRepositories(::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XCommandEnvironment> const & xCmdEnv); } diff --git a/desktop/source/deployment/inc/dp_ucb.h b/desktop/source/deployment/inc/dp_ucb.h index 6f9127504860..03144388e8a8 100644 --- a/desktop/source/deployment/inc/dp_ucb.h +++ b/desktop/source/deployment/inc/dp_ucb.h @@ -28,6 +28,7 @@ #if ! defined INCLUDED_DP_UCB_H #define INCLUDED_DP_UCB_H +#include <list> #include "rtl/byteseq.hxx" #include "rtl/instance.hxx" #include "com/sun/star/ucb/XCommandEnvironment.hpp" @@ -79,6 +80,12 @@ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool readLine( ::rtl::OUString * res, ::rtl::OUString const & startingWith, ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc ); +DESKTOP_DEPLOYMENTMISC_DLLPUBLIC +bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result, + ::ucbhelper::Content & ucb_content); + + + } #endif diff --git a/desktop/source/deployment/manager/dp_activepackages.cxx b/desktop/source/deployment/manager/dp_activepackages.cxx index bf9071682b2e..8f6b6b82c0b7 100644 --- a/desktop/source/deployment/manager/dp_activepackages.cxx +++ b/desktop/source/deployment/manager/dp_activepackages.cxx @@ -107,10 +107,14 @@ static char const legacyPrefix[] = "org.openoffice.legacy."; } else { + sal_Int32 i4 = value.indexOf(separator, i3 + 1); d.mediaType = ::rtl::OUString( value.getStr() + i2 + 1, i3 - i2 -1, RTL_TEXTENCODING_UTF8); d.version = ::rtl::OUString( - value.getStr() + i3 + 1, value.getLength() - i3 - 1, + value.getStr() + i3 + 1, i4 - i3 - 1, + RTL_TEXTENCODING_UTF8); + d.failedPrerequisites = ::rtl::OUString( + value.getStr() + i4 + 1, value.getLength() - i4 - 1, RTL_TEXTENCODING_UTF8); } return d; @@ -188,6 +192,8 @@ void ActivePackages::put(::rtl::OUString const & id, Data const & data) { b.append(::rtl::OUStringToOString(data.mediaType, RTL_TEXTENCODING_UTF8)); b.append(separator); b.append(::rtl::OUStringToOString(data.version, RTL_TEXTENCODING_UTF8)); + b.append(separator); + b.append(::rtl::OUStringToOString(data.failedPrerequisites, RTL_TEXTENCODING_UTF8)); m_map.put(newKey(id), b.makeStringAndClear()); } diff --git a/desktop/source/deployment/manager/dp_activepackages.hxx b/desktop/source/deployment/manager/dp_activepackages.hxx index 36060d26bd02..7d9c7e32cfb4 100644 --- a/desktop/source/deployment/manager/dp_activepackages.hxx +++ b/desktop/source/deployment/manager/dp_activepackages.hxx @@ -42,6 +42,8 @@ namespace dp_manager { class ActivePackages { public: struct Data { + Data(): failedPrerequisites(::rtl::OUString::valueOf((sal_Int32)0)) + {} /* name of the temporary file (shared, user extension) or the name of the folder of the bundled extension. It does not contain the trailing '_' of the folder. @@ -55,6 +57,13 @@ public: ::rtl::OUString fileName; ::rtl::OUString mediaType; ::rtl::OUString version; + /* If this string contains the value according to + com::sun::star::deployment::Prerequisites or "0". That is, if + the value is > 0 then + the call to XPackage::checkPrerequisites failed. + In this case the extension must not be registered. + */ + ::rtl::OUString failedPrerequisites; }; typedef ::std::vector< ::std::pair< ::rtl::OUString, Data > > Entries; diff --git a/desktop/source/deployment/manager/dp_tmprepocmdenv.cxx b/desktop/source/deployment/manager/dp_commandenvironments.cxx index 3a4a6f1d2b72..814dc818b2a6 100644 --- a/desktop/source/deployment/manager/dp_tmprepocmdenv.cxx +++ b/desktop/source/deployment/manager/dp_commandenvironments.cxx @@ -29,14 +29,14 @@ #include "precompiled_desktop.hxx" #include "com/sun/star/deployment/VersionException.hpp" -#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp" #include "com/sun/star/deployment/LicenseException.hpp" #include "com/sun/star/deployment/InstallException.hpp" #include "com/sun/star/task/XInteractionApprove.hpp" #include "com/sun/star/task/XInteractionAbort.hpp" +#include "com/sun/star/task/XInteractionHandler.hpp" #include "com/sun/star/ucb/XCommandEnvironment.hpp" #include "com/sun/star/uno/XComponentContext.hpp" -#include "dp_tmprepocmdenv.hxx" +#include "dp_commandenvironments.hxx" namespace deployment = com::sun::star::deployment; namespace lang = com::sun::star::lang; @@ -52,65 +52,50 @@ using ::rtl::OUString; namespace dp_manager { -TmpRepositoryCommandEnv::TmpRepositoryCommandEnv() +BaseCommandEnv::BaseCommandEnv() { } -TmpRepositoryCommandEnv::TmpRepositoryCommandEnv( - Reference< css::task::XInteractionHandler> const & handler) +BaseCommandEnv::BaseCommandEnv( + Reference< task::XInteractionHandler> const & handler) : m_forwardHandler(handler) { } -TmpRepositoryCommandEnv::~TmpRepositoryCommandEnv() +BaseCommandEnv::~BaseCommandEnv() { } // XCommandEnvironment //______________________________________________________________________________ -Reference<task::XInteractionHandler> TmpRepositoryCommandEnv::getInteractionHandler() +Reference<task::XInteractionHandler> BaseCommandEnv::getInteractionHandler() throw (uno::RuntimeException) { return this; } //______________________________________________________________________________ -Reference<ucb::XProgressHandler> TmpRepositoryCommandEnv::getProgressHandler() +Reference<ucb::XProgressHandler> BaseCommandEnv::getProgressHandler() throw (uno::RuntimeException) { return this; } -// XInteractionHandler -void TmpRepositoryCommandEnv::handle( - Reference< task::XInteractionRequest> const & xRequest ) +void BaseCommandEnv::handle( + Reference< task::XInteractionRequest> const & /*xRequest*/ ) throw (uno::RuntimeException) { - uno::Any request( xRequest->getRequest() ); - OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION ); - - deployment::VersionException verExc; - deployment::LicenseException licExc; - deployment::InstallException instExc; - deployment::LicenseIndividualAgreementException licAgreementExc; - - - bool approve = false; - bool abort = false; - - if ((request >>= verExc) - || (request >>= licExc) - || (request >>= instExc) - || (request >>= licAgreementExc)) - { - approve = true; - } +} +void BaseCommandEnv::handle_(bool approve, bool abort, + Reference< task::XInteractionRequest> const & xRequest ) +{ if (approve == false && abort == false) { + //not handled so far -> forwarding if (m_forwardHandler.is()) m_forwardHandler->handle(xRequest); else - approve = true; + return; //cannot handle } else { @@ -142,24 +127,128 @@ void TmpRepositoryCommandEnv::handle( } } } + } // XProgressHandler -void TmpRepositoryCommandEnv::push( uno::Any const & /*Status*/ ) +void BaseCommandEnv::push( uno::Any const & /*Status*/ ) throw (uno::RuntimeException) { } -void TmpRepositoryCommandEnv::update( uno::Any const & /*Status */) +void BaseCommandEnv::update( uno::Any const & /*Status */) throw (uno::RuntimeException) { } -void TmpRepositoryCommandEnv::pop() throw (uno::RuntimeException) +void BaseCommandEnv::pop() throw (uno::RuntimeException) { } +//============================================================================== +TmpRepositoryCommandEnv::TmpRepositoryCommandEnv() +{ +} + +TmpRepositoryCommandEnv::TmpRepositoryCommandEnv( + css::uno::Reference< css::task::XInteractionHandler> const & handler): + BaseCommandEnv(handler) +{ +} +// XInteractionHandler +void TmpRepositoryCommandEnv::handle( + Reference< task::XInteractionRequest> const & xRequest ) + throw (uno::RuntimeException) +{ + uno::Any request( xRequest->getRequest() ); + OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION ); + + deployment::VersionException verExc; + deployment::LicenseException licExc; + deployment::InstallException instExc; + + bool approve = false; + bool abort = false; + + if ((request >>= verExc) + || (request >>= licExc) + || (request >>= instExc)) + { + approve = true; + } + + handle_(approve, abort, xRequest); +} +//================================================================================ + +LicenseCommandEnv::LicenseCommandEnv( + css::uno::Reference< css::task::XInteractionHandler> const & handler, + bool bSuppressLicense, + OUString const & repository): + BaseCommandEnv(handler), m_repository(repository), + m_bSuppressLicense(bSuppressLicense) +{ +} +// XInteractionHandler +void LicenseCommandEnv::handle( + Reference< task::XInteractionRequest> const & xRequest ) + throw (uno::RuntimeException) +{ + uno::Any request( xRequest->getRequest() ); + OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION ); + + + deployment::LicenseException licExc; + + bool approve = false; + bool abort = false; + + if (request >>= licExc) + { + if (m_bSuppressLicense + || m_repository.equals(OUSTR("bundled")) + || licExc.AcceptBy.equals(OUSTR("admin"))) + { + //always approve in bundled case, because we do not support + //showing licenses anyway. + //The "admin" already accepted the license when installing the + // shared extension + approve = true; + } + } + + handle_(approve, abort, xRequest); +} + +//================================================================================ +//================================================================================ + +NoLicenseCommandEnv::NoLicenseCommandEnv( + css::uno::Reference< css::task::XInteractionHandler> const & handler): + BaseCommandEnv(handler) +{ +} +// XInteractionHandler +void NoLicenseCommandEnv::handle( + Reference< task::XInteractionRequest> const & xRequest ) + throw (uno::RuntimeException) +{ + uno::Any request( xRequest->getRequest() ); + OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION ); + + + deployment::LicenseException licExc; + + bool approve = false; + bool abort = false; + + if (request >>= licExc) + { + approve = true; + } + handle_(approve, abort, xRequest); +} } // namespace dp_manager diff --git a/desktop/source/deployment/manager/dp_tmprepocmdenv.hxx b/desktop/source/deployment/manager/dp_commandenvironments.hxx index 22111bc1e081..ad47fd2af549 100644 --- a/desktop/source/deployment/manager/dp_tmprepocmdenv.hxx +++ b/desktop/source/deployment/manager/dp_commandenvironments.hxx @@ -25,8 +25,8 @@ * ************************************************************************/ -#if ! defined INCLUDED_DP_TMPREPOSITORYCOMMANDENVIRONMENT_HXX -#define INCLUDED_DP_TMPREPOSITORYCOMMANDENVIRONMENT_HXX +#if ! defined INCLUDED_DP_COMMANDENVIRONMENTS_HXX +#define INCLUDED_DP_COMMANDENVIRONMENTS_HXX #include "cppuhelper/compbase3.hxx" @@ -39,21 +39,27 @@ namespace css = ::com::sun::star; namespace dp_manager { + + /** This command environment is to be used when an extension is temporarily stored in the "tmp" repository. It prevents all kind of user interaction. */ -class TmpRepositoryCommandEnv +class BaseCommandEnv : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment, css::task::XInteractionHandler, css::ucb::XProgressHandler > { +protected: css::uno::Reference< css::uno::XComponentContext > m_xContext; css::uno::Reference< css::task::XInteractionHandler> m_forwardHandler; + + void handle_(bool approve, bool abort, + css::uno::Reference< css::task::XInteractionRequest> const & xRequest ); public: - virtual ~TmpRepositoryCommandEnv(); - TmpRepositoryCommandEnv(); - TmpRepositoryCommandEnv( + virtual ~BaseCommandEnv(); + BaseCommandEnv(); + BaseCommandEnv( css::uno::Reference< css::task::XInteractionHandler> const & handler); // XCommandEnvironment @@ -75,6 +81,62 @@ public: virtual void SAL_CALL pop() throw (css::uno::RuntimeException); }; +class TmpRepositoryCommandEnv : public BaseCommandEnv +{ +public: + TmpRepositoryCommandEnv::TmpRepositoryCommandEnv(); + TmpRepositoryCommandEnv::TmpRepositoryCommandEnv( + css::uno::Reference< css::task::XInteractionHandler> const & handler); + +// XInteractionHandler + virtual void SAL_CALL handle( + css::uno::Reference<css::task::XInteractionRequest > const & xRequest ) + throw (css::uno::RuntimeException); + +}; + +/** this class is for use in XPackageManager::synchronize. + + It handles particular license cases. + */ +class LicenseCommandEnv : public BaseCommandEnv +{ +private: + ::rtl::OUString m_repository; + bool m_bSuppressLicense; +public: + LicenseCommandEnv::LicenseCommandEnv(){}; + LicenseCommandEnv::LicenseCommandEnv( + css::uno::Reference< css::task::XInteractionHandler> const & handler, + bool bSuppressLicense, + ::rtl::OUString const & repository); + +// XInteractionHandler + virtual void SAL_CALL handle( + css::uno::Reference<css::task::XInteractionRequest > const & xRequest ) + throw (css::uno::RuntimeException); + +}; + +/** this class is for use in XPackageManager::checkPrerequisites + + It always prohibits a license interaction + */ +class NoLicenseCommandEnv : public BaseCommandEnv +{ + +public: + NoLicenseCommandEnv::NoLicenseCommandEnv(){}; + NoLicenseCommandEnv::NoLicenseCommandEnv( + css::uno::Reference< css::task::XInteractionHandler> const & handler); + +// XInteractionHandler + virtual void SAL_CALL handle( + css::uno::Reference<css::task::XInteractionRequest > const & xRequest ) + throw (css::uno::RuntimeException); + +}; + } diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx index 6e76cfb574bd..15bd9a581611 100644 --- a/desktop/source/deployment/manager/dp_extensionmanager.cxx +++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx @@ -56,9 +56,10 @@ #include "dp_resource.h" #include "dp_ucb.h" #include "dp_identifier.hxx" - +#include "dp_descriptioninfoset.hxx" #include "dp_extensionmanager.hxx" -#include "dp_tmprepocmdenv.hxx" +#include "dp_commandenvironments.hxx" +#include "dp_properties.hxx" #include <list> #include <hash_map> #include <algorithm> @@ -146,6 +147,25 @@ Reference<task::XAbortChannel> ExtensionManager::createAbortChannel() return new dp_misc::AbortChannel; } +css::uno::Reference<css::deployment::XPackageManager> +ExtensionManager::getPackageManager(::rtl::OUString const & repository) + throw (css::lang::IllegalArgumentException) +{ + Reference<deploy::XPackageManager> xPackageManager; + if (repository.equals(OUSTR("user"))) + xPackageManager = m_userRepository; + else if (repository.equals(OUSTR("shared"))) + xPackageManager = m_sharedRepository; + else if (repository.equals(OUSTR("bundled"))) + xPackageManager = m_bundledRepository; + else + throw lang::IllegalArgumentException( + OUSTR("No valid repository name provided."), + static_cast<cppu::OWeakObject*>(this), 0); + return xPackageManager; +} + + /* Enters the XPackage objects into a map. They must be all from the same repository. The value type of the map is a vector, where each vector @@ -279,37 +299,6 @@ Reference<deploy::XPackage> ExtensionManager::getExtensionAndStatus( } /* - Determines if the user extension was disabled by the user. Currently a user - cannot disable extensions from other repositories. If an extension does not - contain any items which need to be registered then the extension cannot - actually be disabled (because it cannot be registered). In this case false is - returned. If there is no user extension then also false is returned. - */ -bool ExtensionManager::isUserExtensionDisabled( - OUString const & identifier, OUString const & fileName, - css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, - css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) - -{ - bool bDisabled = false; - Reference<deploy::XPackage> xExtension; - try - { //will throw an exception if the extension does not exist - xExtension = m_userRepository->getDeployedPackage( - identifier, fileName, Reference<ucb::XCommandEnvironment>()); - } catch(lang::IllegalArgumentException &) - { - } - if (xExtension.is()) - { - beans::Optional<beans::Ambiguous<sal_Bool> > reg = - xExtension->isRegistered(xAbortChannel, xCmdEnv); - if (reg.IsPresent && ! reg.Value.Value) - bDisabled = true; - } - return bDisabled; -} -/* This method determines the active extension (XPackage.registerPackage) with a particular identifier. @@ -326,36 +315,50 @@ bool ExtensionManager::isUserExtensionDisabled( */ void ExtensionManager::activateExtension( OUString const & identifier, OUString const & fileName, - bool bUserDisabled, Reference<task::XAbortChannel> const & xAbortChannel, Reference<ucb::XCommandEnvironment> const & xCmdEnv ) { ::std::list<Reference<deploy::XPackage> > listExtensions = getExtensionsWithSameId(identifier, fileName); OSL_ASSERT(listExtensions.size() == 3); - ::std::list<Reference<deploy::XPackage> >::const_iterator - iext = listExtensions.begin(); - //skip disabled user extension - if (listExtensions.front().is() && bUserDisabled) - iext++; + + activateExtension( + ::comphelper::containerToSequence< + Reference<deploy::XPackage>, + ::std::list<Reference<deploy::XPackage> > + > (listExtensions), + xAbortChannel, xCmdEnv); +} + +void ExtensionManager::activateExtension( + uno::Sequence<Reference<deploy::XPackage> > const & seqExt, + Reference<task::XAbortChannel> const & xAbortChannel, + Reference<ucb::XCommandEnvironment> const & xCmdEnv ) +{ bool bActive = false; - for (; iext != listExtensions.end(); iext++) + sal_Int32 len = seqExt.getLength(); + for (sal_Int32 i = 0; i < len; i++) { - if (iext->is()) + Reference<deploy::XPackage> const & aExt = seqExt[i]; + if (aExt.is()) { //get the registration value of the current iteration beans::Optional<beans::Ambiguous<sal_Bool> > optReg = - (*iext)->isRegistered(xAbortChannel, xCmdEnv); + aExt->isRegistered(xAbortChannel, xCmdEnv); //If nothing can be registered then break if (!optReg.IsPresent) break; + //Check if this is a disabled user extension, if so then skip + if (!optReg.Value.Value && i == 0) //e.g. not registered + continue; + //If we have already determined an active extension then we must //make sure to unregister all extensions with the same id in //repositories with a lower priority if (bActive) { - (*iext)->revokePackage(xAbortChannel, xCmdEnv); + aExt->revokePackage(xAbortChannel, xCmdEnv); } else { @@ -365,7 +368,7 @@ void ExtensionManager::activateExtension( //Register if not already done. //reregister if the value is ambiguous, which indicates that //something went wrong during last registration. - (*iext)->registerPackage(xAbortChannel, xCmdEnv); + aExt->registerPackage(xAbortChannel, xCmdEnv); } } } @@ -386,8 +389,8 @@ Reference<deploy::XPackage> ExtensionManager::backupExtension( if (xOldExtension.is()) { xBackup = m_tmpRepository->addPackage( - xOldExtension->getURL(), OUString(), - Reference<task::XAbortChannel>(), tmpCmdEnv); + xOldExtension->getURL(), uno::Sequence<beans::NamedValue>(), + OUString(), Reference<task::XAbortChannel>(), tmpCmdEnv); OSL_ENSURE(xBackup.is(), "Failed to backup extension"); } @@ -408,7 +411,8 @@ ExtensionManager::getSupportedPackageTypes(OUString const & repository) // Only add to shared and user repository Reference<deploy::XPackage> ExtensionManager::addExtension( - OUString const & url, OUString const & repository, + OUString const & url, uno::Sequence<beans::NamedValue> const & properties, + OUString const & repository, Reference<task::XAbortChannel> const & xAbortChannel, Reference<ucb::XCommandEnvironment> const & xCmdEnv ) throw (deploy::DeploymentException, @@ -436,9 +440,11 @@ Reference<deploy::XPackage> ExtensionManager::addExtension( const OUString sFileName = xTmpExtension->getName(); const OUString sDisplayName = xTmpExtension->getDisplayName(); const OUString sVersion = xTmpExtension->getVersion(); + dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL())); + const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes = + info.getSimpleLicenseAttributes(); Reference<deploy::XPackage> xOldExtension; - bool bUserDisabled = false; Reference<deploy::XPackage> xExtensionBackup; uno::Any excOccurred1; @@ -450,10 +456,6 @@ Reference<deploy::XPackage> ExtensionManager::addExtension( //disabled by a user, then the newly installed one is enabled. If we //add to another repository then the user extension remains //disabled. - if (! repository.equals(OUSTR("user"))) - bUserDisabled = isUserExtensionDisabled( - sIdentifier, sFileName, xAbortChannel, xCmdEnv); - bool bWasRegistered = false; xOldExtension = getExtensionAndStatus( sIdentifier, sFileName, repository, xAbortChannel, @@ -474,8 +476,15 @@ Reference<deploy::XPackage> ExtensionManager::addExtension( checkInstall(sDisplayName, xCmdEnv); } + //Prevent showing the license if requested. + Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv); + ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>()); + if (licenseAttributes && licenseAttributes->suppressIfRequired + && props.isSuppressedLicense()) + _xCmdEnv = Reference<ucb::XCommandEnvironment>(new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler())); + bCanInstall = xTmpExtension->checkPrerequisites( - xAbortChannel, xCmdEnv, xOldExtension.is(), repository); + xAbortChannel, _xCmdEnv, xOldExtension.is()) == 0 ? true : false; } catch (deploy::DeploymentException& ) { excOccurred1 = ::cppu::getCaughtException(); @@ -516,11 +525,10 @@ Reference<deploy::XPackage> ExtensionManager::addExtension( } xNewExtension = xPackageManager->addPackage( - url, OUString(), xAbortChannel, xCmdEnv); + url, properties, OUString(), xAbortChannel, xCmdEnv); activateExtension( dp_misc::getIdentifier(xNewExtension), - xNewExtension->getName(), bUserDisabled, - xAbortChannel, xCmdEnv); + xNewExtension->getName(), xAbortChannel, xCmdEnv); } } catch (deploy::DeploymentException& ) { @@ -560,7 +568,7 @@ Reference<deploy::XPackage> ExtensionManager::addExtension( tmpCmdEnv); } activateExtension( - sIdentifier, sFileName, bUserDisabled, + sIdentifier, sFileName, Reference<task::XAbortChannel>(), tmpCmdEnv); if (xTmpExtension.is() || xExtensionBackup.is()) m_tmpRepository->removePackage( @@ -595,7 +603,7 @@ void ExtensionManager::removeExtension( uno::Any excOccurred1; Reference<deploy::XPackage> xExtensionBackup; Reference<deploy::XPackageManager> xPackageManager; - bool bUserDisabled = false; + try { //Determine the repository to use @@ -610,10 +618,6 @@ void ExtensionManager::removeExtension( ::osl::MutexGuard guard(m_mutex); //Backup the extension, in case the user cancels the action - - bUserDisabled = isUserExtensionDisabled( - identifier, fileName, xAbortChannel, xCmdEnv); - //Backup the extension, in case the user cancels the action xExtensionBackup = backupExtension( identifier, fileName, xPackageManager, xCmdEnv); @@ -625,8 +629,7 @@ void ExtensionManager::removeExtension( xPackageManager->removePackage( identifier, fileName, xAbortChannel, xCmdEnv); - activateExtension(identifier, fileName, bUserDisabled, - xAbortChannel, xCmdEnv); + activateExtension(identifier, fileName, xAbortChannel, xCmdEnv); } catch (deploy::DeploymentException& ) { excOccurred1 = ::cppu::getCaughtException(); @@ -661,7 +664,7 @@ void ExtensionManager::removeExtension( xExtensionBackup, Reference<task::XAbortChannel>(), tmpCmdEnv); activateExtension( - identifier, fileName, bUserDisabled, Reference<task::XAbortChannel>(), + identifier, fileName, Reference<task::XAbortChannel>(), tmpCmdEnv); m_tmpRepository->removePackage( @@ -735,7 +738,7 @@ void ExtensionManager::enableExtension( { activateExtension(dp_misc::getIdentifier(extension), extension->getName(), - false, xAbortChannel, xCmdEnv); + xAbortChannel, xCmdEnv); } catch (deploy::DeploymentException& ) { excOccurred = ::cppu::getCaughtException(); @@ -762,7 +765,7 @@ void ExtensionManager::enableExtension( extension->revokePackage(Reference<task::XAbortChannel>(), xCmdEnv); activateExtension(dp_misc::getIdentifier(extension), extension->getName(), - true, xAbortChannel, xCmdEnv); + xAbortChannel, xCmdEnv); } catch (...) { @@ -771,6 +774,56 @@ void ExtensionManager::enableExtension( } } +/** + */ +long ExtensionManager::checkPrerequisitesAndEnable( + Reference<deploy::XPackage> const & extension, + Reference<task::XAbortChannel> const & xAbortChannel, + Reference<ucb::XCommandEnvironment> const & xCmdEnv) + throw (deploy::DeploymentException, + ucb::CommandFailedException, + ucb::CommandAbortedException, + lang::IllegalArgumentException, + uno::RuntimeException) +{ + try + { + if (!extension.is()) + return 0; + ::osl::MutexGuard guard(m_mutex); + sal_Int32 ret = 0; + Reference<deploy::XPackageManager> mgr = + getPackageManager(extension->getRepositoryName()); + ret = mgr->checkPrerequisites(extension, xAbortChannel, xCmdEnv); + if (ret) + { + //There are some unfulfilled prerequisites, try to revoke + extension->revokePackage(xAbortChannel, xCmdEnv); + } + activateExtension(dp_misc::getIdentifier(extension), + extension->getName(), xAbortChannel, xCmdEnv); + return ret; + } + catch (deploy::DeploymentException& ) { + throw; + } catch (ucb::CommandFailedException & ) { + throw; + } catch (ucb::CommandAbortedException & ) { + throw; + } catch (lang::IllegalArgumentException &) { + throw; + } catch (uno::RuntimeException &) { + throw; + } catch (...) { + uno::Any excOccurred = ::cppu::getCaughtException(); + deploy::DeploymentException exc( + OUSTR("Extension Manager: exception during disableExtension"), + static_cast<OWeakObject*>(this), excOccurred); + throw exc; + } +} + + void ExtensionManager::disableExtension( Reference<deploy::XPackage> const & extension, Reference<task::XAbortChannel> const & xAbortChannel, @@ -806,7 +859,7 @@ void ExtensionManager::disableExtension( extension->revokePackage(xAbortChannel, xCmdEnv); activateExtension(dp_misc::getIdentifier(extension), extension->getName(), - true, xAbortChannel, xCmdEnv); + xAbortChannel, xCmdEnv); } catch (deploy::DeploymentException& ) { excOccurred = ::cppu::getCaughtException(); @@ -832,7 +885,7 @@ void ExtensionManager::disableExtension( { activateExtension(dp_misc::getIdentifier(extension), extension->getName(), - false, xAbortChannel, xCmdEnv); + xAbortChannel, xCmdEnv); } catch (...) { @@ -852,26 +905,8 @@ uno::Sequence< Reference<deploy::XPackage> > lang::IllegalArgumentException, uno::RuntimeException) { - if (repository.equals(OUSTR("user"))) - { - return m_userRepository->getDeployedPackages( - xAbort, xCmdEnv); - } - else if (repository.equals(OUSTR("shared"))) - { - return m_sharedRepository->getDeployedPackages( - xAbort, xCmdEnv); - } - else if (repository.equals(OUSTR("bundled"))) - { - return m_bundledRepository->getDeployedPackages( - xAbort, xCmdEnv); - } - else - throw lang::IllegalArgumentException( - OUSTR("No valid repository name provided."), - static_cast<cppu::OWeakObject*>(this), 0); - + return getPackageManager(repository)->getDeployedPackages( + xAbort, xCmdEnv); } Reference<deploy::XPackage> @@ -885,25 +920,8 @@ Reference<deploy::XPackage> lang::IllegalArgumentException, uno::RuntimeException) { - if (repository.equals(OUSTR("user"))) - { - return m_userRepository->getDeployedPackage( - identifier, filename, xCmdEnv); - } - else if (repository.equals(OUSTR("shared"))) - { - return m_sharedRepository->getDeployedPackage( - identifier, filename, xCmdEnv); - } - else if (repository.equals(OUSTR("bundled"))) - { - return m_bundledRepository->getDeployedPackage( - identifier, filename, xCmdEnv); - } - else - throw lang::IllegalArgumentException( - OUSTR("No valid repository name provided."), - static_cast<cppu::OWeakObject*>(this), 0); + return getPackageManager(repository)->getDeployedPackage( + identifier, filename, xCmdEnv); } uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > > @@ -978,17 +996,8 @@ void ExtensionManager::reinstallDeployedExtensions( { try { - Reference<deploy::XPackageManager> xPackageManager; - if (repository.equals(OUSTR("user"))) - xPackageManager = m_userRepository; - else if (repository.equals(OUSTR("shared"))) - xPackageManager = m_sharedRepository; - else if (repository.equals(OUSTR("bundled"))) - xPackageManager = m_bundledRepository; - else - throw lang::IllegalArgumentException( - OUSTR("No valid repository name provided."), - static_cast<cppu::OWeakObject*>(this), 0); + Reference<deploy::XPackageManager> + xPackageManager = getPackageManager(repository); ::osl::MutexGuard guard(m_mutex); xPackageManager->reinstallDeployedPackages(xAbortChannel, xCmdEnv); @@ -1002,10 +1011,7 @@ void ExtensionManager::reinstallDeployedExtensions( const OUString id = dp_misc::getIdentifier(extensions[ pos ]); const OUString fileName = extensions[ pos ]->getName(); OSL_ASSERT(id.getLength()); - activateExtension( - id, fileName, - isUserExtensionDisabled(id, fileName, xAbortChannel, xCmdEnv), - xAbortChannel, xCmdEnv ); + activateExtension(id, fileName, xAbortChannel, xCmdEnv ); } catch (lang::DisposedException &) { @@ -1067,57 +1073,34 @@ void ExtensionManager::synchronize( static_cast<cppu::OWeakObject*>(this), 0); ::osl::MutexGuard guard(m_mutex); - uno::Sequence<Reference<deploy::XPackage> > seqAddedExtensions; - uno::Sequence<Reference<deploy::XPackage> > seqRemovedExtensions; - xPackageManager->synchronize(seqAddedExtensions, seqRemovedExtensions, - xAbortChannel, xCmdEnv); - - //ToDo: optimize, only call activateExtension once per id. - //Determine which of the extensions was disabled by the user - //iterate of both sequences and add the ids of the user disabled - //to a map - for (sal_Int32 i = 0; i < seqRemovedExtensions.getLength(); i++) + + dp_misc::ProgressLevel progress( + xCmdEnv, OUSTR("Synchronizing ") + repository + OUSTR(" repository\n")); + xPackageManager->synchronize(xAbortChannel, xCmdEnv); + + + try { - try - { - Reference<deploy::XPackage> const & xExtension = seqRemovedExtensions[i]; - OSL_ASSERT(xExtension.is()); - const OUString id = dp_misc::getIdentifier(xExtension); - const OUString fileName = xExtension->getName(); - - bool bUserDisabled = isUserExtensionDisabled( - id, xExtension->getName(), xAbortChannel, xCmdEnv); - xExtension->revokePackage(xAbortChannel, xCmdEnv); - xPackageManager->removePackage( - id, fileName, xAbortChannel, xCmdEnv); - activateExtension( - id, fileName, /*bUserDisabled*/ false, xAbortChannel, xCmdEnv); - } - catch (...) + const uno::Sequence<uno::Sequence<Reference<deploy::XPackage> > > + seqSeqExt = getAllExtensions(xAbortChannel, xCmdEnv); + for (sal_Int32 i = 0; i < seqSeqExt.getLength(); i++) { - OSL_ENSURE(0, "Extensions Manager: synchronize"); + uno::Sequence<Reference<deploy::XPackage> > const & seqExt = + seqSeqExt[i]; + + activateExtension(seqExt, xAbortChannel, xCmdEnv); } } - - for (sal_Int32 i = 0; i < seqAddedExtensions.getLength(); i++) + catch (...) { - try - { - Reference<deploy::XPackage> const & xExtension = seqAddedExtensions[i]; - OSL_ASSERT(xExtension.is()); - const OUString id = dp_misc::getIdentifier(xExtension); - const OUString fileName = xExtension->getName(); - bool bUserDisabled = isUserExtensionDisabled( - id, fileName, xAbortChannel, xCmdEnv); - activateExtension( - id, fileName, bUserDisabled, xAbortChannel, xCmdEnv); - } - catch (...) - { - OSL_ENSURE(0, "Extensions Manager: synchronize"); - } + //We catch the exception, so we can write the lastmodified file + //so we will no repeat this everytime OOo starts. + OSL_ENSURE(0, "Extensions Manager: synchronize"); } + + progress.update(OUSTR("\n\n")); + //Write the lastmodified file try { ::rtl::Bootstrap::expandMacros(file); @@ -1231,7 +1214,7 @@ Reference<deploy::XPackage> ExtensionManager::getTempExtension( { Reference<ucb::XCommandEnvironment> tmpCmdEnvA(new TmpRepositoryCommandEnv()); Reference<deploy::XPackage> xTmpPackage = m_tmpRepository->addPackage( - url, OUString(), xAbortChannel, tmpCmdEnvA); + url, uno::Sequence<beans::NamedValue>(),OUString(), xAbortChannel, tmpCmdEnvA); if (!xTmpPackage.is()) { @@ -1242,6 +1225,20 @@ Reference<deploy::XPackage> ExtensionManager::getTempExtension( } return xTmpPackage; } + +uno::Sequence<Reference<deploy::XPackage> > SAL_CALL +ExtensionManager::getExtensionsWithUnacceptedLicenses( + OUString const & repository, + Reference<ucb::XCommandEnvironment> const & xCmdEnv) + throw (deploy::DeploymentException, + uno::RuntimeException) +{ + Reference<deploy::XPackageManager> + xPackageManager = getPackageManager(repository); + ::osl::MutexGuard guard(m_mutex); + return xPackageManager->getExtensionsWithUnacceptedLicenses(xCmdEnv); +} + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx index 386e2a7ceffd..bafa97c24944 100644 --- a/desktop/source/deployment/manager/dp_extensionmanager.hxx +++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx @@ -106,7 +106,9 @@ public: createAbortChannel() throw (css::uno::RuntimeException); virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL addExtension( - ::rtl::OUString const & url, ::rtl::OUString const & repository, + ::rtl::OUString const & url, + css::uno::Sequence<css::beans::NamedValue> const & properties, + ::rtl::OUString const & repository, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) throw (css::deployment::DeploymentException, @@ -147,6 +149,18 @@ public: css::lang::IllegalArgumentException, css::uno::RuntimeException); + + virtual long SAL_CALL checkPrerequisitesAndEnable( + css::uno::Reference<css::deployment::XPackage> const & extension, + css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::ucb::CommandAbortedException, + css::lang::IllegalArgumentException, + css::uno::RuntimeException); + + virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> > SAL_CALL getDeployedExtensions( ::rtl::OUString const & repository, @@ -202,6 +216,13 @@ public: css::lang::IllegalArgumentException, css::uno::RuntimeException); + virtual css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > SAL_CALL + getExtensionsWithUnacceptedLicenses( + ::rtl::OUString const & repository, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) + throw (css::deployment::DeploymentException, + css::uno::RuntimeException); + private: struct ExtensionInfos @@ -233,18 +254,16 @@ private: css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv, bool & out_bWasRegistered); - bool isUserExtensionDisabled( + void activateExtension( ::rtl::OUString const & identifier, ::rtl::OUString const & fileName, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); void activateExtension( - ::rtl::OUString const & identifier, - ::rtl::OUString const & fileName, - bool bUserDisabled, - css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, - css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); + css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt, + css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ); ::std::list<css::uno::Reference<css::deployment::XPackage> > @@ -276,6 +295,10 @@ private: id2extensions & mapExt, css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt, ::rtl::OUString const & repository); + + css::uno::Reference<css::deployment::XPackageManager> + getPackageManager(::rtl::OUString const & repository) + throw (css::lang::IllegalArgumentException); }; } diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx index e2580e7b955b..0464d0de62d5 100644 --- a/desktop/source/deployment/manager/dp_manager.cxx +++ b/desktop/source/deployment/manager/dp_manager.cxx @@ -58,6 +58,7 @@ #include "com/sun/star/ucb/NameClash.hpp" #include "com/sun/star/deployment/VersionException.hpp" #include "com/sun/star/deployment/InstallException.hpp" +#include "com/sun/star/deployment/Prerequisites.hpp" #include "com/sun/star/task/XInteractionApprove.hpp" #include "com/sun/star/ucb/UnsupportedCommandException.hpp" #include "boost/bind.hpp" @@ -67,7 +68,8 @@ #include <vector> #include <list> #include "dp_descriptioninfoset.hxx" - +#include "dp_commandenvironments.hxx" +#include "dp_properties.hxx" using namespace ::dp_misc; using namespace ::com::sun::star; @@ -97,19 +99,6 @@ struct MatchTempDir } }; -struct MatchExtension -{ - const ActivePackages::Data m_data; - MatchExtension(ActivePackages::Data const & data ) : m_data(data) {} - bool operator () ( OUString const & temporaryName ) const; -}; - -bool MatchExtension::operator () (OUString const & temporaryName) const -{ - //case 1: The temporary file and thus the extension folder are already - //removed. - return m_data.temporaryName.equals(temporaryName); -} namespace { OUString getExtensionFolder(OUString const & parentFolder, @@ -131,23 +120,6 @@ OUString getExtensionFolder(OUString const & parentFolder, } return title; } -/* adds an unencoded segment to the URL. - - Throws an com.sun.star.uno.Exception if this failed. -*/ -OUString appendURLSegement(OUString const & baseURL, OUString const & segment) -{ - OUString url; - INetURLObject inet(baseURL); - if (inet.insertName( - segment, false, INetURLObject::LAST_SEGMENT, true, - INetURLObject::ENCODE_ALL)) - url = inet.GetMainURL(INetURLObject::NO_DECODE); - else - throw Exception( - OUSTR("ExtensionManager: failed to add segment to URL"), 0); - return url; -} } //______________________________________________________________________________ void PackageManagerImpl::initActivationLayer( @@ -193,7 +165,8 @@ void PackageManagerImpl::initActivationLayer( { ActivePackages::Data dbData; insertToActivationLayer( - mediaType, sourceContent, title, &dbData ); + Sequence<css::beans::NamedValue>(),mediaType, sourceContent, + title, &dbData ); insertToActivationLayerDB( title, dbData ); //TODO #i73136#: insertToActivationLayerDB needs id not @@ -293,7 +266,7 @@ void PackageManagerImpl::initActivationLayer( //Make sure only the same user removes the extension, who //previously unregistered it. This is avoid races if multiple instances //of OOo are running which all have write access to the shared installation. - //For example, user a uses extension a, removes the extension, but keeps OOo + //For example, a user removes the extension, but keeps OOo //running. Parts of the extension may still be loaded and used by OOo. //Therefore the extension is only deleted the next time the extension manager is //run after restarting OOo. While OOo is still running, another user starts OOo @@ -637,6 +610,7 @@ OUString PackageManagerImpl::detectMediaType( //______________________________________________________________________________ OUString PackageManagerImpl::insertToActivationLayer( + Sequence<beans::NamedValue> const & properties, OUString const & mediaType, ::ucbhelper::Content const & sourceContent_, OUString const & title, ActivePackages::Data * dbData ) { @@ -702,13 +676,17 @@ OUString PackageManagerImpl::insertToActivationLayer( //bundled extensions should only be added by the synchronizeAddedExtensions //functions. Moreover, there is no "temporary folder" for bundled extensions. OSL_ASSERT(!m_context.equals(OUSTR("bundled"))); + OUString sFolderUrl = makeURLAppendSysPathSegment(destFolderContent.getURL(), title); DescriptionInfoset info = - dp_misc::getDescriptionInfoset( - appendURLSegement(destFolderContent.getURL(), title)); + dp_misc::getDescriptionInfoset(sFolderUrl); dbData->temporaryName = tempEntry; dbData->fileName = title; dbData->mediaType = mediaType; dbData->version = info.getVersion(); + + //No write the properties file next to the extension + ExtensionProperties props(sFolderUrl, properties, xCmdEnv); + props.write(); return destFolder; } @@ -716,6 +694,8 @@ OUString PackageManagerImpl::insertToActivationLayer( void PackageManagerImpl::insertToActivationLayerDB( OUString const & id, ActivePackages::Data const & dbData ) { + //access to the database must be guarded. See removePackage + const ::osl::MutexGuard guard( getMutex() ); m_activePackagesDB->put( id, dbData ); } @@ -746,14 +726,17 @@ Reference<deployment::XPackage> PackageManagerImpl::importExtension( CommandAbortedException, lang::IllegalArgumentException, RuntimeException) { - return addPackage(extension->getURL(), OUString(), xAbortChannel, xCmdEnv_); + return addPackage(extension->getURL(), Sequence<beans::NamedValue>(), + OUString(), xAbortChannel, xCmdEnv_); } /* The function adds an extension but does not register it!!! It may not do any user interaction. This is done in XExtensionManager::addExtension */ Reference<deployment::XPackage> PackageManagerImpl::addPackage( - OUString const & url, OUString const & mediaType_, + OUString const & url, + css::uno::Sequence<css::beans::NamedValue> const & properties, + OUString const & mediaType_, Reference<task::XAbortChannel> const & xAbortChannel, Reference<XCommandEnvironment> const & xCmdEnv_ ) throw (deployment::DeploymentException, CommandFailedException, @@ -826,7 +809,7 @@ Reference<deployment::XPackage> PackageManagerImpl::addPackage( } ActivePackages::Data dbData; destFolder = insertToActivationLayer( - mediaType, sourceContent, title, &dbData ); + properties, mediaType, sourceContent, title, &dbData ); // bind activation package: @@ -859,10 +842,7 @@ Reference<deployment::XPackage> PackageManagerImpl::addPackage( xCmdEnv); } install = true; - const ::osl::MutexGuard guard( getMutex() ); - //access to the database must be guarded. See removePackage_ insertToActivationLayerDB(id, dbData); - } catch (...) { @@ -1062,8 +1042,13 @@ Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_( Reference<deployment::XPackage> xExtension; try { - xExtension = m_xRegistry->bindPackage( - getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv ); + //Ignore extensions where XPackage::checkPrerequisites failed. + //They must not be usable for this user. + if (data.failedPrerequisites.equals(OUSTR("0"))) + { + xExtension = m_xRegistry->bindPackage( + getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv ); + } } catch (deployment::InvalidRemovedParameterException& e) { @@ -1083,6 +1068,8 @@ PackageManagerImpl::getDeployedPackages_( ActivePackages::Entries::const_iterator const iEnd( id2temp.end() ); for ( ; iPos != iEnd; ++iPos ) { + if (! iPos->second.failedPrerequisites.equals(OUSTR("0"))) + continue; try { packages.push_back( getDeployedPackage_( @@ -1265,8 +1252,7 @@ void PackageManagerImpl::reinstallDeployedPackages( return m_readOnly; } void PackageManagerImpl::synchronizeRemovedExtensions( - Sequence<Reference<deployment::XPackage> > & out_removedExtensions, - Reference<task::XAbortChannel> const & /*xAbortChannel*/, + Reference<task::XAbortChannel> const & xAbortChannel, Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) { @@ -1275,64 +1261,38 @@ void PackageManagerImpl::synchronizeRemovedExtensions( OSL_ASSERT(!m_context.equals(OUSTR("user"))); ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() ); - //Iterate over the contents of the extension folder and gather the - //temp file names (shared) or the folder names of the bundled extension. - ::ucbhelper::ResultSetInclude includeType = ::ucbhelper::INCLUDE_DOCUMENTS_ONLY; - if (m_context.equals(OUSTR("bundled"))) - includeType = ::ucbhelper::INCLUDE_FOLDERS_ONLY; - ::ucbhelper::Content tempFolder( - m_activePackages_expanded, xCmdEnv ); - Reference<sdbc::XResultSet> xResultSet( - tempFolder.createCursor( - Sequence<OUString>( &StrTitle::get(), 1 ), includeType) ); - // get all temp directories: - ::std::vector<OUString> tempEntries; - while (xResultSet->next()) { - OUString title( - Reference<sdbc::XRow>( - xResultSet, UNO_QUERY_THROW )->getString( - 1 /* Title */ ) ); - //also add the xxx.tmpremoved files for remove shared extensions - //this does not matter - tempEntries.push_back( ::rtl::Uri::encode( - title, rtl_UriCharClassPchar, - rtl_UriEncodeIgnoreEscapes, - RTL_TEXTENCODING_UTF8 ) ); - } - typedef ActivePackages::Entries::const_iterator ITActive; bool bShared = m_context.equals(OUSTR("shared")); - ::std::vector<Reference<deployment::XPackage> > removedExtensions; + for (ITActive i = id2temp.begin(); i != id2temp.end(); i++) { - //Get the URL to the extensions folder, first make the url for the - //shared repository including the temporary name -// OUString url(m_activePackages_expanded + OUSTR("/") -// + i->second.temporaryName); -// if (bShared) -// url = appendURLSegement(m_activePackages_expanded + OUSTR("/") -// + i->second.temporaryName + OUSTR("_"), -// i->second.fileName); - OUString url = makeURL(m_activePackages, i->second.temporaryName); - if (bShared) - url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName); - - const MatchExtension match(i->second); - bool bRemoved = false; - if (::std::find_if(tempEntries.begin(), tempEntries.end(), match) == - tempEntries.end()) - { - //The the URL from the data base entry does not exist anymore. That is the - //folder was removed. - bRemoved = true; - } - else + try { + //Get the URL to the extensions folder, first make the url for the + //shared repository including the temporary name + OUString url = makeURL(m_activePackages, i->second.temporaryName); + if (bShared) + url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName); + + bool bRemoved = false; + //Check if the URL to the extension is still the same + ::ucbhelper::Content contentExtension; + + if (!create_ucb_content( + &contentExtension, url, + Reference<XCommandEnvironment>(), false)) + { + bRemoved = true; + } + //The folder is in the extension database, but it can still be deleted. //look for the xxx.tmpremoved file - if (bShared) + //There can also be the case that a different extension was installed + //in a "temp" folder with name that is already used. + if (!bRemoved && bShared) { ::ucbhelper::Content contentRemoved; + if (create_ucb_content( &contentRemoved, m_activePackages_expanded + OUSTR("/") + @@ -1342,6 +1302,7 @@ void PackageManagerImpl::synchronizeRemovedExtensions( bRemoved = true; } } + if (!bRemoved) { //There may be another extensions at the same place @@ -1353,26 +1314,32 @@ void PackageManagerImpl::synchronizeRemovedExtensions( if (infoset.hasDescription() && infoset.getIdentifier() && (! i->first.equals(*(infoset.getIdentifier())) - || ! i->second.version.equals(infoset.getVersion()))) + || ! i->second.version.equals(infoset.getVersion()))) { bRemoved = true; } + + } + if (bRemoved) + { + Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage( + url, i->second.mediaType, true, i->first, xCmdEnv ); + OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object. + xPackage->revokePackage(xAbortChannel, xCmdEnv); + removePackage(xPackage->getIdentifier().Value, xPackage->getName(), + xAbortChannel, xCmdEnv); } } - if (bRemoved) + catch( uno::Exception & ) { - Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage( - url, i->second.mediaType, true, i->first, xCmdEnv ); - OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object. - removedExtensions.push_back(xPackage); + OSL_ASSERT(0); } } - out_removedExtensions = ::comphelper::containerToSequence(removedExtensions); } + void PackageManagerImpl::synchronizeAddedExtensions( - Sequence<Reference<deployment::XPackage> > & out_addedExtensions, - Reference<task::XAbortChannel> const & xAbortChannel, + Reference<task::XAbortChannel> const & xAbortChannel, Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) { // clean up activation layer, scan for zombie temp dirs: @@ -1385,65 +1352,58 @@ void PackageManagerImpl::synchronizeAddedExtensions( Sequence<OUString>( &StrTitle::get(), 1 ), ::ucbhelper::INCLUDE_FOLDERS_ONLY ) ); - - ::std::vector<Reference<deployment::XPackage> > addedExtensions; while (xResultSet->next()) { - OUString title( - Reference<sdbc::XRow>( - xResultSet, UNO_QUERY_THROW )->getString( - 1 /* Title */ ) ); - //The temporary folders of user and shared have an '_' at then end. - //But the name in ActivePackages.temporaryName is saved without. - OUString title2 = title; - bool bNotBundled = !m_context.equals(OUSTR("bundled")); - if (bNotBundled) + try { - OSL_ASSERT(title2[title2.getLength() -1] == '_'); - title2 = title2.copy(0, title2.getLength() -1); - } - OUString titleEncoded = ::rtl::Uri::encode( + OUString title( + Reference<sdbc::XRow>( + xResultSet, UNO_QUERY_THROW )->getString( + 1 /* Title */ ) ); + //The temporary folders of user and shared have an '_' at then end. + //But the name in ActivePackages.temporaryName is saved without. + OUString title2 = title; + bool bNotBundled = !m_context.equals(OUSTR("bundled")); + if (bNotBundled) + { + OSL_ASSERT(title2[title2.getLength() -1] == '_'); + title2 = title2.copy(0, title2.getLength() -1); + } + OUString titleEncoded = ::rtl::Uri::encode( title2, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8); - const MatchTempDir match(titleEncoded); - if (::std::find_if( id2temp.begin(), id2temp.end(), match ) == - id2temp.end()) - { - - // The folder was not found in the data base, so it must be - // an added extension - OUString url(m_activePackages_expanded + OUSTR("/") + titleEncoded); - OUString sExtFolder; - if (bNotBundled) //that is, shared + const MatchTempDir match(titleEncoded); + if (::std::find_if( id2temp.begin(), id2temp.end(), match ) == + id2temp.end()) { - //Check if the extension was not "deleted" already which is indicated - //by a xxx.tmpremoved file - ::ucbhelper::Content contentRemoved; - if (create_ucb_content(&contentRemoved, url + OUSTR("removed"), - Reference<XCommandEnvironment>(), false)) - continue; - sExtFolder = getExtensionFolder( - m_activePackages_expanded + + + // The folder was not found in the data base, so it must be + // an added extension + OUString url(m_activePackages_expanded + OUSTR("/") + titleEncoded); + OUString sExtFolder; + if (bNotBundled) //that is, shared + { + //Check if the extension was not "deleted" already which is indicated + //by a xxx.tmpremoved file + ::ucbhelper::Content contentRemoved; + if (create_ucb_content(&contentRemoved, url + OUSTR("removed"), + Reference<XCommandEnvironment>(), false)) + continue; + sExtFolder = getExtensionFolder( + m_activePackages_expanded + OUString(OUSTR("/")) + titleEncoded + OUSTR("_"), xCmdEnv); - url = appendURLSegement(m_activePackages_expanded, title); - url = appendURLSegement(url, sExtFolder); - } - Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage( - url, OUString(), false, OUString(), xCmdEnv ); - if (xPackage.is()) - { - try + url = makeURLAppendSysPathSegment(m_activePackages_expanded, title); + url = makeURLAppendSysPathSegment(url, sExtFolder); + } + Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage( + url, OUString(), false, OUString(), xCmdEnv ); + if (xPackage.is()) { - //ToDo: We need to prevent that removed shared extensions are - //added again. This can happen if there is still the folder of the - //extension. However, there is the "removed" flag file which indicates - //that the extension was removed. //Prepare the database entry ActivePackages::Data dbData; - //There is no temporary folder for bundled extensions. It is therefore - //an empty string. + dbData.temporaryName = titleEncoded; if (bNotBundled) dbData.fileName = sExtFolder; @@ -1456,35 +1416,45 @@ void PackageManagerImpl::synchronizeAddedExtensions( "an identifier and a version"); OUString id = dp_misc::getIdentifier( xPackage ); - sal_Bool bAlreadyInstalled = sal_False; - if (xPackage->checkPrerequisites( - xAbortChannel, xCmdEnv, bAlreadyInstalled, m_context)) - { - const ::osl::MutexGuard guard( getMutex() ); - //access to the database must be guarded. See removePackage_ - insertToActivationLayerDB(id, dbData); - } - else - { - //ToDo: Remember that this failed. For example, the user - //could have declined the license. Then the next time the - //extension folder is investigated we do not want to - //try to install the extension again. - } - addedExtensions.push_back(xPackage); - } - catch (...) - { + + //We provide a special command environment that will prevent + //showing a license if simple-licens/@accept-by = "admin" + //It will also prevent showing the license for bundled extensions + //which is not supported. + OSL_ASSERT(!m_context.equals(OUSTR("user"))); + + // shall the license be suppressed? + DescriptionInfoset info = + dp_misc::getDescriptionInfoset(url); + ::boost::optional<dp_misc::SimpleLicenseAttributes> + attr = info.getSimpleLicenseAttributes(); + ExtensionProperties props(url,xCmdEnv); + bool bNoLicense = false; + if (attr && attr->suppressIfRequired && props.isSuppressedLicense()) + bNoLicense = true; + + Reference<ucb::XCommandEnvironment> licCmdEnv( + new LicenseCommandEnv(xCmdEnv->getInteractionHandler(), + bNoLicense, m_context)); + sal_Int32 failedPrereq = xPackage->checkPrerequisites( + xAbortChannel, licCmdEnv, false); + //Remember that this failed. For example, the user + //could have declined the license. Then the next time the + //extension folder is investigated we do not want to + //try to install the extension again. + dbData.failedPrerequisites = OUString::valueOf(failedPrereq); + insertToActivationLayerDB(id, dbData); } } } + catch (uno::Exception &) + { + OSL_ASSERT(0); + } } - out_addedExtensions = ::comphelper::containerToSequence(addedExtensions); } void PackageManagerImpl::synchronize( - Sequence<Reference<deployment::XPackage> > & out_addedExtensions, - Sequence<Reference<deployment::XPackage> > & out_removedExtensions, Reference<task::XAbortChannel> const & xAbortChannel, Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) throw (css::deployment::DeploymentException, @@ -1496,12 +1466,129 @@ void PackageManagerImpl::synchronize( check(); if (m_context.equals(OUSTR("user"))) return; - synchronizeRemovedExtensions( - out_removedExtensions, xAbortChannel, xCmdEnv); - synchronizeAddedExtensions( - out_addedExtensions, xAbortChannel, xCmdEnv); + synchronizeRemovedExtensions(xAbortChannel, xCmdEnv); + synchronizeAddedExtensions(xAbortChannel, xCmdEnv); +} + +Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWithUnacceptedLicenses( + Reference<ucb::XCommandEnvironment> const & xCmdEnv) + throw (deployment::DeploymentException, RuntimeException) +{ + try + { + const ::osl::MutexGuard guard( getMutex() ); + // clean up activation layer, scan for zombie temp dirs: + ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() ); + + ActivePackages::Entries::const_iterator i = id2temp.begin(); + bool bShared = m_context.equals(OUSTR("shared")); + ::std::vector<Reference<deployment::XPackage> > vec; + + + for (; i != id2temp.end(); i++ ) + { + //Get the database entry + ActivePackages::Data const & dbData = i->second; + sal_Int32 failedPrereq = dbData.failedPrerequisites.toInt32(); + //If the installation failed for other reason then the license then we + //ignore it. + if (failedPrereq ^= deployment::Prerequisites::LICENSE) + continue; + + //Prepare the URL to the extension + OUString url = makeURL(m_activePackages, i->second.temporaryName); + if (bShared) + url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName); + + Reference<deployment::XPackage> p = m_xRegistry->bindPackage( + url, OUString(), false, OUString(), xCmdEnv ); + + if (p.is()) + vec.push_back(p); + + } + return ::comphelper::containerToSequence(vec); + } + catch (deployment::DeploymentException &) + { + throw; + } + catch (RuntimeException&) + { + throw; + } + catch (...) + { + Any exc = ::cppu::getCaughtException(); + deployment::DeploymentException de( + OUSTR("PackageManagerImpl::getExtensionsWithUnacceptedLicenses"), + static_cast<OWeakObject*>(this), exc); + exc <<= de; + ::cppu::throwException(exc); + } } +sal_Int32 PackageManagerImpl::checkPrerequisites( + css::uno::Reference<css::deployment::XPackage> const & extension, + css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::ucb::CommandAbortedException, + css::lang::IllegalArgumentException, + css::uno::RuntimeException) +{ + try + { + if (!extension.is()) + return 0; + if (!m_context.equals(extension->getRepositoryName())) + throw lang::IllegalArgumentException( + OUSTR("PackageManagerImpl::checkPrerequisites: extension is not" + " from this repository."), 0, 0); + + ActivePackages::Data dbData; + OUString id = dp_misc::getIdentifier(extension); + if (m_activePackagesDB->get( &dbData, id, OUString())) + { + //If the license was already displayed, then do not show it again + Reference<ucb::XCommandEnvironment> _xCmdEnv = xCmdEnv; + sal_Int32 prereq = dbData.failedPrerequisites.toInt32(); + if ( !(prereq & deployment::Prerequisites::LICENSE)) + _xCmdEnv = new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()); + + sal_Int32 failedPrereq = extension->checkPrerequisites( + xAbortChannel, _xCmdEnv, false); + dbData.failedPrerequisites = OUString::valueOf(failedPrereq); + insertToActivationLayerDB(id, dbData); + } + else + { + throw lang::IllegalArgumentException( + OUSTR("PackageManagerImpl::checkPrerequisites: unknown extension"), + 0, 0); + + } + return 0; + } + catch (deployment::DeploymentException& ) { + throw; + } catch (ucb::CommandFailedException & ) { + throw; + } catch (ucb::CommandAbortedException & ) { + throw; + } catch (lang::IllegalArgumentException &) { + throw; + } catch (uno::RuntimeException &) { + throw; + } catch (...) { + uno::Any excOccurred = ::cppu::getCaughtException(); + deployment::DeploymentException exc( + OUSTR("PackageManagerImpl::checkPrerequisites: exception "), + static_cast<OWeakObject*>(this), excOccurred); + throw exc; + } +} //############################################################################## diff --git a/desktop/source/deployment/manager/dp_manager.h b/desktop/source/deployment/manager/dp_manager.h index 1249fe7e29d4..2e13c56ae968 100644 --- a/desktop/source/deployment/manager/dp_manager.h +++ b/desktop/source/deployment/manager/dp_manager.h @@ -75,6 +75,7 @@ class PackageManagerImpl : private ::dp_misc::MutexHolder, public t_pm_helper ::rtl::OUString detectMediaType( ::ucbhelper::Content const & ucbContent, bool throw_exc = true ); ::rtl::OUString insertToActivationLayer( + css::uno::Sequence<css::beans::NamedValue> const & properties, ::rtl::OUString const & mediaType, ::ucbhelper::Content const & sourceContent, ::rtl::OUString const & title, ActivePackages::Data * dbData ); @@ -89,14 +90,10 @@ class PackageManagerImpl : private ::dp_misc::MutexHolder, public t_pm_helper css::uno::Reference<css::deployment::XPackage> const & package); void synchronizeRemovedExtensions( - css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > & - out_removedExtensions, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); void synchronizeAddedExtensions( - css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > & - out_AddedExtensions, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); @@ -177,7 +174,9 @@ public: createAbortChannel() throw (css::uno::RuntimeException); virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL addPackage( - ::rtl::OUString const & url, ::rtl::OUString const & mediaType, + ::rtl::OUString const & url, + css::uno::Sequence<css::beans::NamedValue> const & properties, + ::rtl::OUString const & mediaType, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) throw (css::deployment::DeploymentException, @@ -248,8 +247,6 @@ public: throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL synchronize( - css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > & out_xAddedExtensions, - css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > & out_xRemovedExtensions, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) throw (css::deployment::DeploymentException, @@ -257,7 +254,22 @@ public: css::ucb::CommandAbortedException, css::uno::RuntimeException); -}; + virtual css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > SAL_CALL + getExtensionsWithUnacceptedLicenses( + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) + throw (css::deployment::DeploymentException, + css::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL checkPrerequisites( + css::uno::Reference<css::deployment::XPackage> const & extension, + css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::ucb::CommandAbortedException, + css::lang::IllegalArgumentException, + css::uno::RuntimeException); + }; //______________________________________________________________________________ inline void PackageManagerImpl::check() diff --git a/desktop/source/deployment/manager/dp_properties.cxx b/desktop/source/deployment/manager/dp_properties.cxx new file mode 100644 index 000000000000..b04e8131ee15 --- /dev/null +++ b/desktop/source/deployment/manager/dp_properties.cxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "com/sun/star/lang/IllegalArgumentException.hpp" +#include "xmlscript/xml_helper.hxx" +#include "ucbhelper/content.hxx" +#include <list> + +#include "dp_ucb.h" +#include "rtl/ustrbuf.hxx" +#include "dp_properties.hxx" + +namespace lang = com::sun::star::lang; +namespace task = com::sun::star::task; +namespace ucb = com::sun::star::ucb; +namespace uno = com::sun::star::uno; +namespace css = com::sun::star; + +#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) + +using ::com::sun::star::uno::Reference; +using ::rtl::OUString; + +#define PROP_SUPPRESS_LICENSE "SUPPRESS_LICENSE" +namespace dp_manager { + +//Reading the file +ExtensionProperties::ExtensionProperties( + OUString const & urlExtension, + Reference<ucb::XCommandEnvironment> const & xCmdEnv) : + m_xCmdEnv(xCmdEnv) +{ + m_propFileUrl = urlExtension + OUSTR("properties"); + + ::std::list< ::std::pair< OUString, OUString> > props; + if (! dp_misc::create_ucb_content(NULL, m_propFileUrl, 0, false)) + return; + + ::ucbhelper::Content contentProps(m_propFileUrl, m_xCmdEnv); + dp_misc::readProperties(props, contentProps); + + typedef ::std::list< ::std::pair< OUString, OUString> >::const_iterator CI; + for (CI i = props.begin(); i != props.end(); i++) + { + if (i->first.equals(OUSTR(PROP_SUPPRESS_LICENSE))) + m_prop_suppress_license = i->second; + } +} + +//Writing the file +ExtensionProperties::ExtensionProperties( + OUString const & urlExtension, + uno::Sequence<css::beans::NamedValue> const & properties, + Reference<ucb::XCommandEnvironment> const & xCmdEnv) : + m_xCmdEnv(xCmdEnv) +{ + m_propFileUrl = urlExtension + OUSTR("properties"); + + for (sal_Int32 i = 0; i < properties.getLength(); i++) + { + css::beans::NamedValue const & v = properties[i]; + if (v.Name.equals(OUSTR(PROP_SUPPRESS_LICENSE))) + { + OUString value; + if (v.Value >>= value) + { + if (value.equals(OUSTR("1"))) + m_prop_suppress_license = OUSTR("1"); + } + else + { + throw lang::IllegalArgumentException( + OUSTR("Extension Manager: wrong property value"), 0, -1); + } + } + else + { + throw lang::IllegalArgumentException( + OUSTR("Extension Manager: unknown property"), 0, -1); + } + } +} + +void ExtensionProperties::write() +{ + ::ucbhelper::Content contentProps(m_propFileUrl, m_xCmdEnv); + ::rtl::OUStringBuffer buf; + + if (m_prop_suppress_license) + { + buf.append(OUSTR(PROP_SUPPRESS_LICENSE)); + buf.append(OUSTR("=")); + buf.append(*m_prop_suppress_license); + } + + ::rtl::OString stamp = ::rtl::OUStringToOString( + buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8); + Reference<css::io::XInputStream> xData( + ::xmlscript::createInputStream( + ::rtl::ByteSequence( + reinterpret_cast<sal_Int8 const *>(stamp.getStr()), + stamp.getLength() ) ) ); + contentProps.writeStream( xData, true /* replace existing */ ); +} + +bool ExtensionProperties::isSuppressedLicense() +{ + bool ret = false; + if (m_prop_suppress_license) + { + if (m_prop_suppress_license->equals(OUSTR("1"))) + ret = true; + } + return ret; +} + +} // namespace dp_manager + + diff --git a/desktop/source/deployment/manager/dp_properties.hxx b/desktop/source/deployment/manager/dp_properties.hxx new file mode 100644 index 000000000000..197155653de1 --- /dev/null +++ b/desktop/source/deployment/manager/dp_properties.hxx @@ -0,0 +1,76 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dp_manager.h,v $ + * $Revision: 1.17 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if ! defined INCLUDED_DP_PROPERTIES_HXX +#define INCLUDED_DP_PROPERTIES_HXX + + + +#include "com/sun/star/beans/NamedValue.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "boost/optional.hpp" + + +namespace css = ::com::sun::star; + +namespace dp_manager { + + + +/** + + */ +class ExtensionProperties +{ +protected: + ::rtl::OUString m_propFileUrl; + const css::uno::Reference<css::ucb::XCommandEnvironment> m_xCmdEnv; + ::boost::optional< ::rtl::OUString> m_prop_suppress_license; +public: + + virtual ~ExtensionProperties() {}; + ExtensionProperties(::rtl::OUString const & urlExtension, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); + + ExtensionProperties(::rtl::OUString const & urlExtension, + css::uno::Sequence<css::beans::NamedValue> const & properties, + css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); + + void write(); + + bool isSuppressedLicense(); +}; +} + + + + +#endif + diff --git a/desktop/source/deployment/manager/makefile.mk b/desktop/source/deployment/manager/makefile.mk index cb99325bde52..4dc6405e34bf 100644 --- a/desktop/source/deployment/manager/makefile.mk +++ b/desktop/source/deployment/manager/makefile.mk @@ -47,7 +47,8 @@ SLOFILES = \ $(SLO)$/dp_managerfac.obj \ $(SLO)$/dp_informationprovider.obj \ $(SLO)$/dp_extensionmanager.obj \ - $(SLO)$/dp_tmprepocmdenv.obj + $(SLO)$/dp_commandenvironments.obj \ + $(SLO)$/dp_properties.obj .INCLUDE : ..$/target.pmk .INCLUDE : target.mk diff --git a/desktop/source/deployment/migration/dp_migration.cxx b/desktop/source/deployment/migration/dp_migration.cxx index 49362f7e2f5f..c2d0b0dc6bb8 100644 --- a/desktop/source/deployment/migration/dp_migration.cxx +++ b/desktop/source/deployment/migration/dp_migration.cxx @@ -136,7 +136,7 @@ Any MigrationImpl::execute( Sequence<beans::NamedValue> const & ) ->queryContentIdentifierString() ); try { xManager->addPackage( - sourceURL, OUString() /* detect media-type */, + sourceURL, uno::Sequence<beans::NamedValue>(),OUString() /* detect media-type */, Reference<task::XAbortChannel>(), xCmdEnv ); } catch (RuntimeException &) { diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx index 1f1fde7ca7bf..919f134b3fb9 100644 --- a/desktop/source/deployment/misc/dp_misc.cxx +++ b/desktop/source/deployment/misc/dp_misc.cxx @@ -44,8 +44,10 @@ #include "com/sun/star/ucb/CommandAbortedException.hpp" #include "com/sun/star/bridge/UnoUrlResolver.hpp" #include "com/sun/star/bridge/XUnoUrlResolver.hpp" +#include "com/sun/star/deployment/ExtensionManager.hpp" #include "boost/scoped_array.hpp" #include "boost/shared_ptr.hpp" +#include <comphelper/processfactory.hxx> #ifdef WNT //#include "tools/prewin.h" @@ -138,6 +140,103 @@ bool existsOfficePipe() return pipe.is(); } + +//Returns true if the Folder was more recently modified then +//the lastsynchronized file. That is the repository needs to +//be synchronized. +bool compareExtensionFolderWithLastSynchronizedFile( + OUString const & folderURL, OUString const & fileURL) +{ + bool bNeedsSync = false; + ::osl::DirectoryItem itemExtFolder; + ::osl::File::RC err1 = + ::osl::DirectoryItem::get(folderURL, itemExtFolder); + //If it does not exist, then there is nothing to be done + if (err1 == ::osl::File::E_NOENT) + { + return false; + } + else if (err1 != ::osl::File::E_None) + { + OSL_ENSURE(0, "Cannot access extension folder"); + return true; //sync just in case + } + + //If last synchronized does not exist, then OOo is started for the first time + ::osl::DirectoryItem itemFile; + ::osl::File::RC err2 = ::osl::DirectoryItem::get(fileURL, itemFile); + if (err2 == ::osl::File::E_NOENT) + { + return true; + + } + else if (err2 != ::osl::File::E_None) + { + OSL_ENSURE(0, "Cannot access file lastsynchronized"); + return true; //sync just in case + } + + //compare the modification time of the extension folder and the last + //modified file + ::osl::FileStatus statFolder(FileStatusMask_ModifyTime); + ::osl::FileStatus statFile(FileStatusMask_ModifyTime); + if (itemExtFolder.getFileStatus(statFolder) == ::osl::File::E_None) + { + if (itemFile.getFileStatus(statFile) == ::osl::File::E_None) + { + TimeValue timeFolder = statFolder.getModifyTime(); + TimeValue timeFile = statFile.getModifyTime(); + + if (timeFile.Seconds < timeFolder.Seconds) + bNeedsSync = true; + } + else + { + OSL_ASSERT(0); + bNeedsSync = true; + } + } + else + { + OSL_ASSERT(0); + bNeedsSync = true; + } + return bNeedsSync; +} + +bool needToSyncRepostitory(OUString const & name) +{ + OUString folder; + OUString file; + if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled")))) + { + folder = OUString( + RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS")); + file = OUString ( + RTL_CONSTASCII_USTRINGPARAM( + "$BUNDLED_EXTENSIONS_USER/lastsynchronized")); + } + else if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))) + { + folder = OUString( + RTL_CONSTASCII_USTRINGPARAM( + "$UNO_SHARED_PACKAGES_CACHE/uno_packages")); + file = OUString ( + RTL_CONSTASCII_USTRINGPARAM( + "$SHARED_EXTENSIONS_USER/lastsynchronized")); + } + else + { + OSL_ASSERT(0); + return true; + } + ::rtl::Bootstrap::expandMacros(folder); + ::rtl::Bootstrap::expandMacros(file); + return compareExtensionFolderWithLastSynchronizedFile( + folder, file); +} + + } // anon namespace //============================================================================== @@ -480,22 +579,43 @@ void TRACE(::rtl::OString const & sText) #endif } -bool hasExtensionRepositoryChanged(::rtl::OUString const & repository) +void syncRepositories(Reference<ucb::XCommandEnvironment> const & xCmdEnv) { - if (repository.equals(OUSTR("shared"))) + Reference<deployment::XExtensionManager> xExtensionManager; + //synchronize shared before bundled otherewise there are + //more revoke and registration calls. + OUString sShared(RTL_CONSTASCII_USTRINGPARAM("shared")); + if (needToSyncRepostitory(sShared)) { - //get the extensions folder - OUString folder(RTL_CONSTASCII_USTRINGPARAM("BUNDLED_EXTENSIONS")); - ::rtl::Bootstrap::expandMacros(folder); + xExtensionManager = + deployment::ExtensionManager::get( + comphelper_getProcessComponentContext()); + + if (xExtensionManager.is()) + { + xExtensionManager->synchronize( + sShared, Reference<task::XAbortChannel>(), xCmdEnv); + } } - else if (repository.equals(OUSTR("bundled"))) + + OUString sBundled(RTL_CONSTASCII_USTRINGPARAM("bundled")); + if (needToSyncRepostitory( sBundled)) { - } - else - throw lang::IllegalArgumentException( - OUSTR("Invalid repository name."), 0, 0); + if (!xExtensionManager.is()) + { + xExtensionManager = + deployment::ExtensionManager::get( + comphelper_getProcessComponentContext()); + } + if (xExtensionManager.is()) + { + xExtensionManager->synchronize( + sBundled, Reference<task::XAbortChannel>(), xCmdEnv); - return false; + } + } } + + } diff --git a/desktop/source/deployment/misc/dp_ucb.cxx b/desktop/source/deployment/misc/dp_ucb.cxx index 571aef9c1b95..795a492aa0d5 100644 --- a/desktop/source/deployment/misc/dp_ucb.cxx +++ b/desktop/source/deployment/misc/dp_ucb.cxx @@ -271,4 +271,50 @@ bool readLine( OUString * res, OUString const & startingWith, return false; } +bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result, + ::ucbhelper::Content & ucb_content ) +{ + // read whole file: + ::rtl::ByteSequence bytes( readFile( ucb_content ) ); + OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()), + bytes.getLength(), RTL_TEXTENCODING_UTF8); + sal_Int32 pos = 0; + + for (;;) + { + + ::rtl::OUStringBuffer buf; + sal_Int32 start = pos; + + bool bEOF = false; + pos = file.indexOf( LF, pos ); + if (pos < 0) { // EOF + buf.append( file.copy( start ) ); + bEOF = true; + } + else + { + if (pos > 0 && file[ pos - 1 ] == CR) + // consume extra CR + buf.append( file.copy( start, pos - start - 1 ) ); + else + buf.append( file.copy( start, pos - start ) ); + pos++; + } + OUString aLine = buf.makeStringAndClear(); + + sal_Int32 posEqual = aLine.indexOf('='); + if (posEqual > 0 && (posEqual + 1) < aLine.getLength()) + { + OUString name = aLine.copy(0, posEqual); + OUString value = aLine.copy(posEqual + 1); + out_result.push_back(::std::make_pair(name, value)); + } + + if (bEOF) + break; + } + return false; +} + } diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx index 667f1588e247..17444eb0828e 100644 --- a/desktop/source/deployment/registry/component/dp_component.cxx +++ b/desktop/source/deployment/registry/component/dp_component.cxx @@ -157,7 +157,8 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend ::rtl::Reference<PackageRegistryBackend> const & myBackend, OUString const & url, OUString const & name, Reference<deployment::XPackageTypeInfo> const & xPackageType, - OUString const & loader, bool bRemoved, OUString const & identifier); + OUString const & loader, bool bRemoved, + OUString const & identifier); }; friend class ComponentPackageImpl; @@ -186,7 +187,8 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend ::rtl::Reference<PackageRegistryBackend> const & myBackend, OUString const & url, OUString const & name, Reference<deployment::XPackageTypeInfo> const & xPackageType, - bool jarFile, bool bRemoved, OUString const & identifier); + bool jarFile, bool bRemoved, + OUString const & identifier); }; friend class TypelibraryPackageImpl; @@ -207,7 +209,7 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend // PackageRegistryBackend virtual Reference<deployment::XPackage> bindPackage_( OUString const & url, OUString const & mediaType, - sal_Bool bNoFileAccess, OUString const & identifier, + sal_Bool bRemoved, OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ); virtual void SAL_CALL disposing(); @@ -283,7 +285,8 @@ BackendImpl::ComponentPackageImpl::ComponentPackageImpl( ::rtl::Reference<PackageRegistryBackend> const & myBackend, OUString const & url, OUString const & name, Reference<deployment::XPackageTypeInfo> const & xPackageType, - OUString const & loader, bool bRemoved, OUString const & identifier) + OUString const & loader, bool bRemoved, + OUString const & identifier) : Package( myBackend, url, name, name /* display-name */, xPackageType, bRemoved, identifier), m_loader( loader ), diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.cxx b/desktop/source/deployment/registry/configuration/dp_configuration.cxx index 354676fd56ff..fefa6794342a 100644 --- a/desktop/source/deployment/registry/configuration/dp_configuration.cxx +++ b/desktop/source/deployment/registry/configuration/dp_configuration.cxx @@ -114,7 +114,8 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend // PackageRegistryBackend virtual Reference<deployment::XPackage> bindPackage_( OUString const & url, OUString const & mediaType, sal_Bool bRemoved, - OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ); + OUString const & identifier, + Reference<XCommandEnvironment> const & xCmdEnv ); ::std::auto_ptr<PersistentMap> m_registeredPackages; // for backwards compatibility diff --git a/desktop/source/deployment/registry/dp_backend.cxx b/desktop/source/deployment/registry/dp_backend.cxx index be752bcf0733..1cebd20c297a 100644 --- a/desktop/source/deployment/registry/dp_backend.cxx +++ b/desktop/source/deployment/registry/dp_backend.cxx @@ -31,6 +31,7 @@ #include "dp_backend.h" #include "dp_ucb.h" #include "rtl/uri.hxx" +#include "rtl/bootstrap.hxx" #include "osl/file.hxx" #include "cppuhelper/exc_hlp.hxx" #include "comphelper/servicedecl.hxx" @@ -170,7 +171,8 @@ Reference<deployment::XPackage> PackageRegistryBackend::bindPackage( Reference<deployment::XPackage> xNewPackage; try { - xNewPackage = bindPackage_( url, mediaType, bRemoved, identifier, xCmdEnv ); + xNewPackage = bindPackage_( url, mediaType, bRemoved, + identifier, xCmdEnv ); } catch (RuntimeException &) { throw; @@ -318,6 +320,16 @@ Package::Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend, m_bRemoved(bRemoved), m_identifier(identifier) { + if (m_bRemoved) + { + //We use the last segment of the URL + OSL_ASSERT(m_name.getLength() == 0); + OUString name = m_url; + rtl::Bootstrap::expandMacros(name); + sal_Int32 index = name.lastIndexOf('/'); + if (index != -1 && index < name.getLength()) + m_name = name.copy(index + 1); + } } //______________________________________________________________________________ @@ -407,10 +419,10 @@ sal_Bool Package::isBundle() throw (RuntimeException) } //______________________________________________________________________________ -::sal_Bool Package::checkPrerequisites( +::sal_Int32 Package::checkPrerequisites( const css::uno::Reference< css::task::XAbortChannel >&, const css::uno::Reference< css::ucb::XCommandEnvironment >&, - sal_Bool, ::rtl::OUString const &) + sal_Bool) throw (css::deployment::DeploymentException, css::deployment::ExtensionRemovedException, css::ucb::CommandFailedException, @@ -419,7 +431,7 @@ sal_Bool Package::isBundle() throw (RuntimeException) { if (m_bRemoved) throw deployment::ExtensionRemovedException(); - return true; + return 0; } //______________________________________________________________________________ diff --git a/desktop/source/deployment/registry/dp_registry.cxx b/desktop/source/deployment/registry/dp_registry.cxx index e35b37bdeb07..c5e440a2a825 100644 --- a/desktop/source/deployment/registry/dp_registry.cxx +++ b/desktop/source/deployment/registry/dp_registry.cxx @@ -127,7 +127,7 @@ public: // XPackageRegistry virtual Reference<deployment::XPackage> SAL_CALL bindPackage( - OUString const & url, OUString const & mediaType, sal_Bool bNoFileAccess, + OUString const & url, OUString const & mediaType, sal_Bool bRemoved, OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ) throw (deployment::DeploymentException, CommandFailedException, lang::IllegalArgumentException, RuntimeException); @@ -498,7 +498,8 @@ Reference<deployment::XPackage> PackageRegistryImpl::bindPackage( for ( ; iPos != iEnd; ++iPos ) { try { - return (*iPos)->bindPackage( url, mediaType, bRemoved, identifier, xCmdEnv ); + return (*iPos)->bindPackage( url, mediaType, bRemoved, + identifier, xCmdEnv ); } catch (lang::IllegalArgumentException &) { } @@ -527,7 +528,8 @@ Reference<deployment::XPackage> PackageRegistryImpl::bindPackage( getResourceString(RID_STR_UNSUPPORTED_MEDIA_TYPE) + mediaType, static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) ); } - return iFind->second->bindPackage( url, mediaType, bRemoved, identifier, xCmdEnv ); + return iFind->second->bindPackage( url, mediaType, bRemoved, + identifier, xCmdEnv ); } } diff --git a/desktop/source/deployment/registry/executable/dp_executable.cxx b/desktop/source/deployment/registry/executable/dp_executable.cxx index 39fd3cdc892e..1dc4cdde64ea 100644 --- a/desktop/source/deployment/registry/executable/dp_executable.cxx +++ b/desktop/source/deployment/registry/executable/dp_executable.cxx @@ -152,7 +152,8 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.executable")) { return new BackendImpl::ExecutablePackageImpl( - this, url, name, m_xExecutableTypeInfo, bRemoved, identifier); + this, url, name, m_xExecutableTypeInfo, bRemoved, + identifier); } } } diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx index aeeec94981e6..a523a1aa20a5 100644 --- a/desktop/source/deployment/registry/help/dp_help.cxx +++ b/desktop/source/deployment/registry/help/dp_help.cxx @@ -102,10 +102,6 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend Reference<ucb::XCommandEnvironment> const & xCmdEnv); void implCollectXhpFiles( const rtl::OUString& aDir, std::vector< rtl::OUString >& o_rXhpFileVector ); -// rtl::OUString getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr ); -// rtl::OUString getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage ); -// rtl::OUString getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage ); -// rtl::OUString expandURL( const rtl::OUString& aURL ); void addDataToDb(OUString const & url, HelpBackendDb::Data const & data); ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url); @@ -195,7 +191,8 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( "vnd.sun.star.help")) { return new PackageImpl( - this, url, name, m_xHelpTypeInfo, bRemoved, identifier); + this, url, name, m_xHelpTypeInfo, bRemoved, + identifier); } } } @@ -233,7 +230,8 @@ BackendImpl::PackageImpl::PackageImpl( OUString const & url, OUString const & name, Reference<deployment::XPackageTypeInfo> const & xPackageType, bool bRemoved, OUString const & identifier) - : Package( myBackend, url, name, name, xPackageType, bRemoved, identifier) + : Package( myBackend, url, name, name, xPackageType, bRemoved, + identifier) { if (bRemoved) { @@ -290,13 +288,6 @@ void BackendImpl::PackageImpl::processPackage_( BackendImpl* that = getMyBackend(); Reference< deployment::XPackage > xThisPackage( this ); that->implProcessHelp( xThisPackage, doRegisterPackage, xCmdEnv); - -// HelpBackendDb::Data data; -// getMyBackend()->addDataToDb(getURL(), data); - -// } -// else -// getMyBackend()->deleteDataFromDb(getURL()); } beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL() @@ -373,23 +364,6 @@ void BackendImpl::implProcessHelp { std::vector< rtl::OUString > aXhpFileVector; - // Delete (old) files in any case to allow compiler to be started every time -// rtl::OUString aLangWithPureNameURL( aLangURL ); -// aLangWithPureNameURL += aSlash; -// aLangWithPureNameURL += aHelpStr; -// rtl::OUString aDbFile( aLangWithPureNameURL ); -// aDbFile += rtl::OUString::createFromAscii( ".db" ); -// if( xSFA->exists( aDbFile ) ) -// xSFA->kill( aDbFile ); -// rtl::OUString aHtFile( aLangWithPureNameURL ); -// aHtFile += rtl::OUString::createFromAscii( ".ht" ); -// if( xSFA->exists( aHtFile ) ) -// xSFA->kill( aHtFile ); -// rtl::OUString aKeyFile( aLangWithPureNameURL ); -// aKeyFile += rtl::OUString::createFromAscii( ".key" ); -// if( xSFA->exists( aKeyFile ) ) -// xSFA->kill( aKeyFile ); - // calculate jar file URL sal_Int32 indexStartSegment = aLangURL.lastIndexOf('/'); // for example "/en" @@ -408,12 +382,6 @@ void BackendImpl::implProcessHelp rtl::OUString aJarFile( makeURL(sHelpFolder, langFolderURLSegment + aSlash + aHelpStr + OUSTR(".jar"))); -// aJarFile += aSlash; -// aJarFile += aHelpStr; -// aJarFile += rtl::OUString::createFromAscii( ".jar" ); - // remove in any case to clean up -// if( xSFA->exists( aJarFile ) ) -// xSFA->kill( aJarFile ); aJarFile = ::dp_misc::expandUnoRcUrl(aJarFile); rtl::OUString aEncodedJarFilePath = rtl::Uri::encode( @@ -443,8 +411,6 @@ void BackendImpl::implProcessHelp aDestPath += aPureFolderName; xSFA->copy( aSubFolderURL, aDestPath ); } - //Copy help.tree to the temp folder in the help backend folder -// xSFA->copy(aLangURL + OUSTR("/help.tree"), langFolderDestExpanded + OUSTR("/help.tree")); // Call compiler sal_Int32 nXhpFileCount = aXhpFileVector.size(); @@ -485,7 +451,6 @@ void BackendImpl::implProcessHelp aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); rtl::OUString aSystemPath; -// osl::FileBase::getSystemPathFromFileURL( aLangURL, aSystemPath ); osl::FileBase::getSystemPathFromFileURL( langFolderDestExpanded, aSystemPath ); aParamsSeq[5] = uno::makeAny( aSystemPath ); @@ -562,75 +527,6 @@ void BackendImpl::implProcessHelp } } -// rtl::OUString BackendImpl::getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr ) -// { -// rtl::OUString aRetURL; -// if( !xPackage.is() ) -// return aRetURL; -// rtl::OUString aHelpURL = xPackage->getURL(); -// aRetURL = expandURL( aHelpURL ); -// aRetURL += rtl::OUString::createFromAscii( pFlagStr ); -// return aRetURL; -// } - -// rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage ) -// { -// return getFlagFileURL( xPackage, "/RegisteredFlag" ); -// } - -// rtl::OUString BackendImpl::getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage ) -// { -// return getFlagFileURL( xPackage, "/CompiledFlag" ); -// } - -// rtl::OUString BackendImpl::expandURL( const rtl::OUString& aURL ) -// { -// static Reference< util::XMacroExpander > xMacroExpander; -// static Reference< uri::XUriReferenceFactory > xFac; - -// if( !xMacroExpander.is() || !xFac.is() ) -// { -// Reference<XComponentContext> const & xContext = getComponentContext(); -// if( xContext.is() ) -// { -// xFac = Reference< uri::XUriReferenceFactory >( -// xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( -// "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY ); -// } -// if( !xFac.is() ) -// { -// throw RuntimeException( -// ::rtl::OUString::createFromAscii( -// "dp_registry::backend::help::BackendImpl::expandURL(), " -// "could not instatiate UriReferenceFactory." ), -// Reference< XInterface >() ); -// } - -// xMacroExpander = Reference< util::XMacroExpander >( -// xContext->getValueByName( -// ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), -// UNO_QUERY_THROW ); -// } - -// rtl::OUString aRetURL = aURL; -// if( xMacroExpander.is() ) -// { -// Reference< uri::XUriReference > uriRef; -// for (;;) -// { -// uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY ); -// if ( uriRef.is() ) -// { -// Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); -// if( !sxUri.is() ) -// break; - -// aRetURL = sxUri->expand( xMacroExpander ); -// } -// } -// } -// return aRetURL; -// } void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir, std::vector< rtl::OUString >& o_rXhpFileVector ) diff --git a/desktop/source/deployment/registry/inc/dp_backend.h b/desktop/source/deployment/registry/inc/dp_backend.h index 179420b16ef6..7ad55d29ba2f 100644 --- a/desktop/source/deployment/registry/inc/dp_backend.h +++ b/desktop/source/deployment/registry/inc/dp_backend.h @@ -175,10 +175,10 @@ public: css::ucb::CommandAbortedException, css::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL checkPrerequisites( + virtual ::sal_Int32 SAL_CALL checkPrerequisites( const css::uno::Reference< css::task::XAbortChannel >& xAbortChannel, const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv, - sal_Bool bInstalled, ::rtl::OUString const & aContextName) + sal_Bool noLicenseChecking) throw (css::deployment::DeploymentException, css::deployment::ExtensionRemovedException, css::ucb::CommandFailedException, diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx index 467ff5ca89fa..822e744b8fc2 100644 --- a/desktop/source/deployment/registry/package/dp_package.cxx +++ b/desktop/source/deployment/registry/package/dp_package.cxx @@ -64,8 +64,8 @@ #include "com/sun/star/packages/manifest/XManifestWriter.hpp" #include "com/sun/star/deployment/DependencyException.hpp" #include "com/sun/star/deployment/LicenseException.hpp" -#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp" #include "com/sun/star/deployment/PlatformException.hpp" +#include "com/sun/star/deployment/Prerequisites.hpp" #include "com/sun/star/xml/dom/XDocumentBuilder.hpp" #include "com/sun/star/xml/xpath/XXPathAPI.hpp" #include "com/sun/star/deployment/XPackageManager.hpp" @@ -139,8 +139,7 @@ class BackendImpl : public ImplBaseT ::sal_Bool checkLicense( Reference< ucb::XCommandEnvironment > const & xCmdEnv, - DescriptionInfoset const & description, bool bInstalled, - OUString const & aContextName ) + DescriptionInfoset const & description, bool bNoLicenseChecking) throw (deployment::DeploymentException, ucb::CommandFailedException, ucb::CommandAbortedException, @@ -199,10 +198,10 @@ class BackendImpl : public ImplBaseT ucb::CommandAbortedException, RuntimeException); - virtual ::sal_Bool SAL_CALL checkPrerequisites( + virtual ::sal_Int32 SAL_CALL checkPrerequisites( const Reference< task::XAbortChannel >& xAbortChannel, const Reference< ucb::XCommandEnvironment >& xCmdEnv, - ::sal_Bool bInstalled, OUString const & aContextName) + ::sal_Bool noLicenseChecking) throw (deployment::ExtensionRemovedException, deployment::DeploymentException, ucb::CommandFailedException, @@ -423,12 +422,14 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( } if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) { return new PackageImpl( - this, url, name, m_xBundleTypeInfo, false, bRemoved, identifier); + this, url, name, m_xBundleTypeInfo, false, bRemoved, + identifier); } else if (subType.EqualsIgnoreCaseAscii( "vnd.sun.star.legacy-package-bundle")) { return new PackageImpl( - this, url, name, m_xLegacyBundleTypeInfo, true, bRemoved, identifier); + this, url, name, m_xLegacyBundleTypeInfo, true, bRemoved, + identifier); } } } @@ -652,7 +653,7 @@ bool BackendImpl::PackageImpl::checkDependencies( ::sal_Bool BackendImpl::PackageImpl::checkLicense( css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv, - DescriptionInfoset const & info, bool bInstalled, OUString const & aContextName) + DescriptionInfoset const & info, bool alreadyInstalled) throw (css::deployment::DeploymentException, css::ucb::CommandFailedException, css::ucb::CommandAbortedException, @@ -679,41 +680,21 @@ bool BackendImpl::PackageImpl::checkDependencies( throw css::deployment::DeploymentException( OUSTR("Could not obtain attribute simple-lincense@accept-by or it has no valid value"), 0, Any()); - //If if @accept-by="user" then every user needs to accept the license before it can be installed. - //Therefore we must prevent the installation as shared extension unless suppress-if-required="true" - OSL_ASSERT(aContextName.getLength()); - if (simplLicAttr->acceptBy.equals(OUSTR("user")) && aContextName.equals(OUSTR("shared"))) - { - css::deployment::LicenseIndividualAgreementException - exc = css::deployment::LicenseIndividualAgreementException( - OUString(), 0, m_name, simplLicAttr->suppressIfRequired); - - bool approve = false; - bool abort = false; - if (! interactContinuation( - Any(exc), task::XInteractionApprove::static_type(), xCmdEnv, &approve, &abort )) - throw css::deployment::DeploymentException( - OUSTR("Could not interact with user."), 0, Any()); - if (abort == true) - return false; - - //If the unopkg --suppress-license was used and simplLicAttr->suppressIfRequired == true, - //then the user implicitely accepts the license - } //Only use interaction if there is no version of this extension already installed //and the suppress-on-update flag is not set for the new extension - // bInstalled | bSuppressOnUpdate | show license + // alreadyInstalled | bSuppressOnUpdate | show license //---------------------------------------- // 0 | 0 | 1 // 0 | 1 | 1 // 1 | 0 | 1 // 1 | 1 | 0 - if ( !(bInstalled && simplLicAttr->suppressOnUpdate)) + if ( !(alreadyInstalled && simplLicAttr->suppressOnUpdate)) { css::deployment::LicenseException licExc( - OUString(), 0, m_name, sLicense, simplLicAttr->suppressIfRequired); + OUString(), 0, getDisplayName(), sLicense, + simplLicAttr->acceptBy); bool approve = false; bool abort = false; if (! interactContinuation( @@ -745,10 +726,10 @@ bool BackendImpl::PackageImpl::checkDependencies( } } -::sal_Bool BackendImpl::PackageImpl::checkPrerequisites( +::sal_Int32 BackendImpl::PackageImpl::checkPrerequisites( const css::uno::Reference< css::task::XAbortChannel >&, const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv, - sal_Bool bInstalled, OUString const & aContextName) + sal_Bool alreadyInstalled) throw (css::deployment::DeploymentException, css::deployment::ExtensionRemovedException, css::ucb::CommandFailedException, @@ -759,11 +740,21 @@ bool BackendImpl::PackageImpl::checkDependencies( throw deployment::ExtensionRemovedException(); DescriptionInfoset info = getDescriptionInfoset(); if (!info.hasDescription()) - return sal_True; - - return checkPlatform(xCmdEnv) - && checkDependencies(xCmdEnv, info) - && checkLicense(xCmdEnv, info, bInstalled, aContextName); + return 0; + + //always return LICENSE as long as the user did not accept the license + //so that XExtensonManager::checkPrerequisitesAndEnable will again + //check the license + if (!checkPlatform(xCmdEnv)) + return deployment::Prerequisites::PLATFORM | + deployment::Prerequisites::LICENSE; + else if(!checkDependencies(xCmdEnv, info)) + return deployment::Prerequisites::DEPENDENCIES | + deployment::Prerequisites::LICENSE; + else if(!checkLicense(xCmdEnv, info, alreadyInstalled)) + return deployment::Prerequisites::LICENSE; + else + return 0; } ::sal_Bool BackendImpl::PackageImpl::checkDependencies( diff --git a/desktop/source/deployment/registry/script/dp_script.cxx b/desktop/source/deployment/registry/script/dp_script.cxx index b645c9b2af7a..5023a501c67e 100644 --- a/desktop/source/deployment/registry/script/dp_script.cxx +++ b/desktop/source/deployment/registry/script/dp_script.cxx @@ -233,9 +233,9 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( 0, dialogURL, xCmdEnv, false /* no throw */ )) { dialogURL = OUString(); } - return new PackageImpl( this, url, xCmdEnv, - makeURL( url, OUSTR("script.xlb") ), - dialogURL, bRemoved, identifier); + return new PackageImpl( + this, url, xCmdEnv, makeURL( url, OUSTR("script.xlb") ), + dialogURL, bRemoved, identifier); } else if (subType.EqualsIgnoreCaseAscii( "vnd.sun.star.dialog-library")) { diff --git a/desktop/source/deployment/unopkg/unopkg.src b/desktop/source/deployment/unopkg/unopkg.src index 79c578628676..dc204e265ec6 100644 --- a/desktop/source/deployment/unopkg/unopkg.src +++ b/desktop/source/deployment/unopkg/unopkg.src @@ -27,15 +27,10 @@ #include "deployment.hrc" -String RID_STR_UNOPKG_NO_SHARED_ALLOWED -{ - Text [ en-US ] = "The option \"--shared\" cannot be used to install the extension \'%NAME\', " - "because every user has to agree to the license agreement of the extension. The extension will not be installed."; -}; String RID_STR_UNOPKG_ACCEPT_LIC_1 { - Text [ en-US ] = "Extension License Agreement:"; + Text [ en-US ] = "Extension Software License Agreement of $NAME:"; }; String RID_STR_UNOPKG_ACCEPT_LIC_2 diff --git a/desktop/source/migration/services/oo3extensionmigration.cxx b/desktop/source/migration/services/oo3extensionmigration.cxx index 11bf8129cc04..a077eaddb911 100755 --- a/desktop/source/migration/services/oo3extensionmigration.cxx +++ b/desktop/source/migration/services/oo3extensionmigration.cxx @@ -52,6 +52,7 @@ #include <com/sun/star/ucb/NameClash.hpp> #include <com/sun/star/ucb/XCommandEnvironment.hpp> #include <com/sun/star/xml/xpath/XXPathAPI.hpp> +#include <com/sun/star/beans/NamedValue.hpp> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -363,7 +364,8 @@ bool OO3ExtensionMigration::migrateExtension( const ::rtl::OUString& sSourceDir static_cast< cppu::OWeakObject* >( pCmdEnv ), uno::UNO_QUERY ); uno::Reference< task::XAbortChannel > xAbortChannel; uno::Reference< deployment::XPackage > xPackage = - m_xPackageManager->addPackage( sSourceDir, ::rtl::OUString(), xAbortChannel, xCmdEnv ); + m_xPackageManager->addPackage( + sSourceDir, uno::Sequence<beans::NamedValue>(),::rtl::OUString(), xAbortChannel, xCmdEnv ); if ( xPackage.is() ) return true; diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx index 807260fe4663..ba8cd56085f8 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_app.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx @@ -41,6 +41,7 @@ #include "cppuhelper/implbase1.hxx" #include "cppuhelper/exc_hlp.hxx" #include "comphelper/anytostring.hxx" +#include "comphelper/sequence.hxx" #include "com/sun/star/deployment/ExtensionManager.hpp" #include "com/sun/star/deployment/ui/PackageManagerDialog.hpp" @@ -60,10 +61,24 @@ using ::rtl::OUString; namespace css = ::com::sun::star; namespace { +struct ExtensionName +{ + OUString m_str; + ExtensionName( OUString const & str ) : m_str( str ) {} + bool operator () ( Reference<deployment::XPackage> const & e ) const + { + if (m_str.equals(dp_misc::getIdentifier(e)) + || m_str.equals(e->getName())) + return true; + return false; + } +}; + //------------------------------------------------------------------------------ const char s_usingText [] = "\n" "using: " APP_NAME " add <options> extension-path...\n" +" " APP_NAME " validate <options> extension-identifier...\n" " " APP_NAME " remove <options> extension-identifier...\n" " " APP_NAME " list <options> extension-identifier...\n" " " APP_NAME " reinstall <options>\n" @@ -73,6 +88,8 @@ const char s_usingText [] = "\n" "sub-commands:\n" " add add extension\n" +" validate checks the prerequisites of an installed extension and" +" registers it if possible\n" " remove remove extensions by identifier\n" " reinstall expert feature: reinstall all deployed extensions\n" " list list information about deployed extensions\n" @@ -252,7 +269,7 @@ extern "C" int unopkg_main() return 0; } else if (isOption( info_version, &nPos )) { - dp_misc::writeConsole("\n"APP_NAME" Version 3.0\n"); + dp_misc::writeConsole("\n"APP_NAME" Version 3.3\n"); return 0; } //consume all bootstrap variables which may occur before the subcommannd @@ -314,15 +331,6 @@ extern "C" int unopkg_main() } } - //make sure the bundled option was provided together with shared -// if (option_bundled && !option_shared) -// { -// dp_misc::writeConsoleError( -// "\nERROR: option --bundled can only be used together with --shared!"); -// return 1; -// } - - xComponentContext = getUNO( disposeGuard, option_verbose, option_shared, subcmd_gui, xLocalComponentContext ); @@ -357,8 +365,11 @@ extern "C" int unopkg_main() Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv( createCmdEnv( xComponentContext, logFile, - option_force, option_verbose, option_bundled, - option_suppressLicense) ); + option_force, option_verbose) ); + + //synchronize bundled/shared extensions + if (!subcmd_gui && ! dp_misc::office_is_running()) + dp_misc::syncRepositories(xCmdEnv); if (subcmd_add || subCommand.equalsAsciiL( @@ -369,9 +380,12 @@ extern "C" int unopkg_main() OUString const & cmdPackage = cmdPackages[ pos ]; if (subcmd_add) { + beans::NamedValue nvSuppress( + OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ? + makeAny(OUSTR("1")):makeAny(OUSTR("0"))); xExtensionManager->addExtension( - cmdPackage, repository, - Reference<task::XAbortChannel>(), xCmdEnv); + cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1), + repository, Reference<task::XAbortChannel>(), xCmdEnv); } else { @@ -410,32 +424,131 @@ extern "C" int unopkg_main() } else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") )) { - Sequence< Reference<deployment::XPackage> > packages; + ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted; + ::comphelper::sequenceToContainer(vecExtUnaccepted, + xExtensionManager->getExtensionsWithUnacceptedLicenses( + repository, xCmdEnv)); + + //This vector tells what XPackage in allExtensions has an + //unaccepted license. + std::vector<bool> vecUnaccepted; + std::vector<Reference<deployment::XPackage> > allExtensions; if (cmdPackages.empty()) { - packages = xExtensionManager->getDeployedExtensions( - repository, Reference<task::XAbortChannel>(), xCmdEnv ); + Sequence< Reference<deployment::XPackage> > + packages = xExtensionManager->getDeployedExtensions( + repository, Reference<task::XAbortChannel>(), xCmdEnv ); + + ::std::vector<Reference<deployment::XPackage> > vec_packages; + ::comphelper::sequenceToContainer(vec_packages, packages); + + //First copy the extensions with the unaccepted license + //to vector allExtensions. + allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size()); + + ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext = + ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(), + allExtensions.begin()); + //Now copy those we got from getDeployedExtensions + ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext); + + //Now prepare the vector which tells what extension has an + //unaccepted license + vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size()); + ::std::vector<bool>::iterator i_unaccepted = + ::std::fill_n(vecUnaccepted.begin(), + vecExtUnaccepted.size(), true); + ::std::fill_n(i_unaccepted, vec_packages.size(), false); + dp_misc::writeConsole( - OUSTR("all deployed ") + repository + OUSTR(" packages:\n")); + OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n")); } else { - packages.realloc( cmdPackages.size() ); + //The user provided the names (ids or file names) of the extensions + //which shall be listed for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) + { + Reference<deployment::XPackage> extension; try { - packages[ pos ] = xExtensionManager->getDeployedExtension( + extension = xExtensionManager->getDeployedExtension( repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv ); } catch (lang::IllegalArgumentException &) { - packages[ pos ] = findPackage(repository, + extension = findPackage(repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] ); - if ( !packages[ pos ].is() ) - throw; } + + //Now look if the requested extension has an unaccepted license + bool bUnacceptedLic = false; + if (!extension.is()) + { + ::std::vector<Reference<deployment::XPackage> >::const_iterator + i = ::std::find_if( + vecExtUnaccepted.begin(), + vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos])); + if (i != vecExtUnaccepted.end()) + { + extension = *i; + bUnacceptedLic = true; + } + } + + if (extension.is()) + { + allExtensions.push_back(extension); + vecUnaccepted.push_back(bUnacceptedLic); + } + + else + throw lang::IllegalArgumentException( + OUSTR("There is no such extension deployed: ") + + cmdPackages[pos],0,-1); + } + + } + + printf_packages(allExtensions, vecUnaccepted, xCmdEnv ); + } + else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") )) + { + ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted; + ::comphelper::sequenceToContainer( + vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses( + repository, xCmdEnv)); + + for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) + { + Reference<deployment::XPackage> extension; + try + { + extension = xExtensionManager->getDeployedExtension( + repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv ); + } + catch (lang::IllegalArgumentException &) + { + extension = findPackage( + repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] ); + } + + if (!extension.is()) + { + ::std::vector<Reference<deployment::XPackage> >::const_iterator + i = ::std::find_if( + vecExtUnaccepted.begin(), + vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos])); + if (i != vecExtUnaccepted.end()) + { + extension = *i; + } + } + + if (extension.is()) + xExtensionManager->checkPrerequisitesAndEnable( + extension, Reference<task::XAbortChannel>(), xCmdEnv); } - printf_packages( packages, xCmdEnv ); } else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") )) { diff --git a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx index d23dcbf9577d..69a973b90a42 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx @@ -49,7 +49,7 @@ #include "com/sun/star/deployment/PlatformException.hpp" #include "com/sun/star/i18n/XCollator.hpp" #include "com/sun/star/i18n/CollatorOptions.hpp" -#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp" + #include <stdio.h> #include "deployment.hrc" #include "dp_version.hxx" @@ -85,13 +85,12 @@ class CommandEnvironmentImpl sal_Int32 m_logLevel; bool m_option_force_overwrite; bool m_option_verbose; - bool m_option_bundled; - bool m_option_suppressLicense; Reference< XComponentContext > m_xComponentContext; Reference< XProgressHandler > m_xLogFile; void update_( Any const & Status ) throw (RuntimeException); - void printLicense(const OUString& sLicense, bool & accept, bool & decline); + void printLicense(const OUString & sName,const OUString& sLicense, + bool & accept, bool & decline); public: virtual ~CommandEnvironmentImpl(); @@ -99,9 +98,7 @@ public: Reference<XComponentContext> const & xComponentContext, OUString const & log_file, bool option_force_overwrite, - bool option_verbose, - bool option_bundled, - bool option_suppressLicense); + bool option_verbose); // XCommandEnvironment virtual Reference< task::XInteractionHandler > SAL_CALL @@ -120,19 +117,16 @@ public: virtual void SAL_CALL pop() throw (RuntimeException); }; + //______________________________________________________________________________ CommandEnvironmentImpl::CommandEnvironmentImpl( Reference<XComponentContext> const & xComponentContext, OUString const & log_file, bool option_force_overwrite, - bool option_verbose, - bool option_bundled, - bool option_suppressLicense) + bool option_verbose) : m_logLevel(0), m_option_force_overwrite( option_force_overwrite ), m_option_verbose( option_verbose ), - m_option_bundled( option_bundled), - m_option_suppressLicense( option_suppressLicense), m_xComponentContext(xComponentContext) { if (log_file.getLength() > 0) { @@ -162,10 +156,13 @@ CommandEnvironmentImpl::~CommandEnvironmentImpl() } //May throw exceptions -void CommandEnvironmentImpl::printLicense(const OUString& sLicense, bool & accept, bool &decline) +void CommandEnvironmentImpl::printLicense( + const OUString & sName, const OUString& sLicense, bool & accept, bool &decline) { ResMgr * pResMgr = DeploymentResMgr::get(); - OUString s1 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr)); + String s1tmp(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr)); + s1tmp.SearchAndReplaceAllAscii( "$NAME", sName ); + OUString s1(s1tmp); OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr)); OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr)); OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr)); @@ -246,7 +243,6 @@ void CommandEnvironmentImpl::handle( lang::WrappedTargetException wtExc; deployment::LicenseException licExc; deployment::InstallException instExc; - deployment::LicenseIndividualAgreementException licAgreementExc; deployment::PlatformException platExc; deployment::VersionException verExc; @@ -281,27 +277,9 @@ void CommandEnvironmentImpl::handle( update_( wtExc.TargetException ); } } - else if (request >>= licAgreementExc) - { - if (m_option_suppressLicense && licAgreementExc.SuppressIfRequired) - { - approve = true; - } - else - { - String sResMsg( ResId( RID_STR_UNOPKG_NO_SHARED_ALLOWED, *DeploymentResMgr::get() ) ); - sResMsg.SearchAndReplaceAllAscii( "%NAME", licAgreementExc.ExtensionName ); - dp_misc::writeConsole(OUSTR("\n") + sResMsg + OUSTR("\n\n")); - abort = true; - } - } else if (request >>= licExc) { - bLicenseException = true; - if (m_option_suppressLicense && licExc.SuppressIfRequired) - approve = true; - else - printLicense(licExc.Text, approve, abort); + printLicense(licExc.ExtensionName, licExc.Text, approve, abort); } else if (request >>= instExc) { @@ -436,6 +414,7 @@ void CommandEnvironmentImpl::pop() throw (RuntimeException) m_xLogFile->pop(); } + } // anon namespace namespace unopkg { @@ -445,14 +424,10 @@ Reference< XCommandEnvironment > createCmdEnv( Reference< XComponentContext > const & xContext, OUString const & logFile, bool option_force_overwrite, - bool option_verbose, - bool option_bundled, - bool option_suppressLicense) + bool option_verbose) { return new CommandEnvironmentImpl( - xContext, logFile, option_force_overwrite, option_verbose, option_bundled, - option_suppressLicense); + xContext, logFile, option_force_overwrite, option_verbose); } - } // unopkg diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx index b25176e1dcee..3272810afee2 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx @@ -48,6 +48,7 @@ #include "unotools/configmgr.hxx" #include "com/sun/star/lang/XMultiServiceFactory.hpp" #include "cppuhelper/bootstrap.hxx" +#include "comphelper/sequence.hxx" #include <stdio.h> using ::rtl::OUString; @@ -317,7 +318,10 @@ void printf_package( xPackage->getBundle( Reference<task::XAbortChannel>(), xCmdEnv ) ); printf_space( level + 1 ); dp_misc::writeConsole("bundled Packages: {\n"); - printf_packages( seq, xCmdEnv, level + 2 ); + ::std::vector<Reference<deployment::XPackage> >vec_bundle; + ::comphelper::sequenceToContainer(vec_bundle, seq); + printf_packages( vec_bundle, ::std::vector<bool>(vec_bundle.size()), + xCmdEnv, level + 2 ); printf_space( level + 1 ); dp_misc::writeConsole("}\n"); } @@ -325,23 +329,45 @@ void printf_package( } // anon namespace +void printf_unaccepted_licenses( + Reference<deployment::XPackage> const & ext) +{ + OUString id( + dp_misc::getIdentifier(ext) ); + printf_line( OUSTR("Identifier"), id, 0 ); + printf_space(1); + dp_misc::writeConsole(OUSTR("License not accepted\n\n")); +} + //============================================================================== void printf_packages( - Sequence< Reference<deployment::XPackage> > const & seq, + ::std::vector< Reference<deployment::XPackage> > const & allExtensions, + ::std::vector<bool> const & vecUnaccepted, Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level ) { - sal_Int32 len = seq.getLength(); - Reference< deployment::XPackage > const * p = seq.getConstArray(); - if (len == 0) { + OSL_ASSERT(allExtensions.size() == vecUnaccepted.size()); + + if (allExtensions.size() == 0) + { printf_space( level ); dp_misc::writeConsole("<none>\n"); } - else { - for ( sal_Int32 pos = 0; pos < len; ++pos ) - printf_package( p[ pos ], xCmdEnv, level ); + else + { + typedef ::std::vector< Reference<deployment::XPackage> >::const_iterator I_EXT; + int index = 0; + for (I_EXT i = allExtensions.begin(); i != allExtensions.end(); i++, index++) + { + if (vecUnaccepted[index]) + printf_unaccepted_licenses(*i); + else + printf_package( *i, xCmdEnv, level ); + dp_misc::writeConsole(OUSTR("\n")); + } } } + //############################################################################## namespace { diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h index 6e9d30cf0d42..43f77513b10c 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_shared.h +++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h @@ -162,14 +162,12 @@ css::uno::Reference<css::ucb::XCommandEnvironment> createCmdEnv( css::uno::Reference<css::uno::XComponentContext> const & xContext, ::rtl::OUString const & logFile, bool option_force_overwrite, - bool option_verbose, - bool option_bundled, - bool option_suppressLicense); - + bool option_verbose); //============================================================================== void printf_packages( - css::uno::Sequence< - css::uno::Reference<css::deployment::XPackage> > const & seq, + ::std::vector< + css::uno::Reference<css::deployment::XPackage> > const & allExtensions, + ::std::vector<bool> const & vecUnaccepted, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv, sal_Int32 level = 0 ); |