LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/desktop/source/deployment/gui - dp_gui_updateinstalldialog.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 279 0.0 %
Date: 2013-07-09 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "dp_gui_updatedata.hxx"
      22             : 
      23             : #include "sal/config.h"
      24             : #include "osl/file.hxx"
      25             : #include "osl/conditn.hxx"
      26             : #include "cppuhelper/exc_hlp.hxx"
      27             : #include "tools/resid.hxx"
      28             : #include "tools/solar.h"
      29             : #include "tools/string.hxx"
      30             : #include "vcl/dialog.hxx"
      31             : #include "vcl/msgbox.hxx"
      32             : #include "vcl/svapp.hxx"
      33             : #include "osl/mutex.hxx"
      34             : #include "cppuhelper/implbase3.hxx"
      35             : 
      36             : #include "com/sun/star/beans/PropertyValue.hpp"
      37             : #include "com/sun/star/beans/NamedValue.hpp"
      38             : #include "com/sun/star/xml/dom/XElement.hpp"
      39             : #include "com/sun/star/xml/dom/XNode.hpp"
      40             : #include "com/sun/star/xml/dom/XNodeList.hpp"
      41             : #include "com/sun/star/ucb/NameClash.hpp"
      42             : #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
      43             : #include "com/sun/star/ucb/XCommandEnvironment.hpp"
      44             : #include "com/sun/star/ucb/XProgressHandler.hpp"
      45             : #include "com/sun/star/deployment/XExtensionManager.hpp"
      46             : #include "com/sun/star/deployment/ExtensionManager.hpp"
      47             : #include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
      48             : #include "com/sun/star/deployment/DependencyException.hpp"
      49             : #include "com/sun/star/deployment/LicenseException.hpp"
      50             : #include "com/sun/star/deployment/VersionException.hpp"
      51             : #include "com/sun/star/deployment/ui/LicenseDialog.hpp"
      52             : #include "com/sun/star/task/XInteractionHandler.hpp"
      53             : #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
      54             : #include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
      55             : #include "com/sun/star/task/XInteractionAbort.hpp"
      56             : #include "com/sun/star/task/XInteractionApprove.hpp"
      57             : 
      58             : #include "dp_descriptioninfoset.hxx"
      59             : #include "dp_gui.hrc"
      60             : #include "dp_gui_updateinstalldialog.hxx"
      61             : #include "dp_gui_shared.hxx"
      62             : #include "dp_ucb.h"
      63             : #include "dp_misc.h"
      64             : #include "dp_version.hxx"
      65             : #include "dp_gui_extensioncmdqueue.hxx"
      66             : #include "ucbhelper/content.hxx"
      67             : #include "rtl/ref.hxx"
      68             : #include "salhelper/thread.hxx"
      69             : #include "com/sun/star/uno/Sequence.h"
      70             : #include "comphelper/anytostring.hxx"
      71             : #include "toolkit/helper/vclunohelper.hxx"
      72             : 
      73             : #include <vector>
      74             : 
      75             : class Window;
      76             : 
      77             : namespace cssu = ::com::sun::star::uno;
      78             : 
      79             : using dp_misc::StrTitle;
      80             : 
      81             : namespace dp_gui {
      82             : 
      83             : class UpdateInstallDialog::Thread: public salhelper::Thread {
      84             :     friend class UpdateCommandEnv;
      85             : public:
      86             :     Thread(cssu::Reference< cssu::XComponentContext > ctx,
      87             :         UpdateInstallDialog & dialog, std::vector< dp_gui::UpdateData > & aVecUpdateData);
      88             : 
      89             :     void stop();
      90             : 
      91             : 
      92             : 
      93             : private:
      94             :     virtual ~Thread();
      95             : 
      96             :     virtual void execute();
      97             :     void downloadExtensions();
      98             :     void download(OUString const & aUrls, UpdateData & aUpdatData);
      99             :     void installExtensions();
     100             :     void removeTempDownloads();
     101             : 
     102             :     UpdateInstallDialog & m_dialog;
     103             :     cssu::Reference< css::deployment::XUpdateInformationProvider >
     104             :         m_updateInformation;
     105             : 
     106             :     // guarded by Application::GetSolarMutex():
     107             :     cssu::Reference< css::task::XAbortChannel > m_abort;
     108             :     cssu::Reference< cssu::XComponentContext > m_xComponentContext;
     109             :     std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
     110             :     ::rtl::Reference<UpdateCommandEnv> m_updateCmdEnv;
     111             : 
     112             :     //A folder which is created in the temp directory in which then the updates are downloaded
     113             :     OUString m_sDownloadFolder;
     114             : 
     115             :     bool m_stop;
     116             : 
     117             : };
     118             : 
     119             : class UpdateCommandEnv
     120             :     : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
     121             :                                       css::task::XInteractionHandler,
     122             :                                       css::ucb::XProgressHandler >
     123             : {
     124             :     friend class UpdateInstallDialog::Thread;
     125             : 
     126             :     ::rtl::Reference<UpdateInstallDialog::Thread> m_installThread;
     127             :     cssu::Reference< cssu::XComponentContext > m_xContext;
     128             : 
     129             : public:
     130             :     virtual ~UpdateCommandEnv();
     131             :     UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
     132             :         ::rtl::Reference<UpdateInstallDialog::Thread>const & thread);
     133             : 
     134             :     // XCommandEnvironment
     135             :     virtual cssu::Reference<css::task::XInteractionHandler > SAL_CALL
     136             :     getInteractionHandler() throw (cssu::RuntimeException);
     137             :     virtual cssu::Reference<css::ucb::XProgressHandler >
     138             :     SAL_CALL getProgressHandler() throw (cssu::RuntimeException);
     139             : 
     140             :     // XInteractionHandler
     141             :     virtual void SAL_CALL handle(
     142             :         cssu::Reference<css::task::XInteractionRequest > const & xRequest )
     143             :         throw (cssu::RuntimeException);
     144             : 
     145             :     // XProgressHandler
     146             :     virtual void SAL_CALL push( cssu::Any const & Status )
     147             :         throw (cssu::RuntimeException);
     148             :     virtual void SAL_CALL update( cssu::Any const & Status )
     149             :         throw (cssu::RuntimeException);
     150             :     virtual void SAL_CALL pop() throw (cssu::RuntimeException);
     151             : };
     152             : 
     153             : 
     154           0 : UpdateInstallDialog::Thread::Thread(
     155             :     cssu::Reference< cssu::XComponentContext> xCtx,
     156             :     UpdateInstallDialog & dialog,
     157             :     std::vector< dp_gui::UpdateData > & aVecUpdateData):
     158             :     salhelper::Thread("dp_gui_updateinstalldialog"),
     159             :     m_dialog(dialog),
     160             :     m_xComponentContext(xCtx),
     161             :     m_aVecUpdateData(aVecUpdateData),
     162           0 :     m_updateCmdEnv(new UpdateCommandEnv(xCtx, this)),
     163           0 :     m_stop(false)
     164           0 : {}
     165             : 
     166           0 : void UpdateInstallDialog::Thread::stop() {
     167           0 :     cssu::Reference< css::task::XAbortChannel > abort;
     168             :     {
     169           0 :         SolarMutexGuard g;
     170           0 :         abort = m_abort;
     171           0 :         m_stop = true;
     172             :     }
     173           0 :     if (abort.is()) {
     174           0 :         abort->sendAbort();
     175           0 :     }
     176           0 : }
     177             : 
     178           0 : UpdateInstallDialog::Thread::~Thread() {}
     179             : 
     180           0 : void UpdateInstallDialog::Thread::execute()
     181             : {
     182             :     try {
     183           0 :         downloadExtensions();
     184           0 :         installExtensions();
     185             :     }
     186           0 :     catch (...)
     187             :     {
     188             :     }
     189             : 
     190             :     //clean up the temp directories
     191             :     try {
     192           0 :         removeTempDownloads();
     193           0 :     } catch( ... ) {
     194             :     }
     195             : 
     196             :     {
     197             :         //make sure m_dialog is still alive
     198           0 :         SolarMutexGuard g;
     199           0 :         if (! m_stop)
     200           0 :              m_dialog.updateDone();
     201             :     }
     202             :     //UpdateCommandEnv keeps a reference to Thread and prevents destruction. Therefore remove it.
     203           0 :     m_updateCmdEnv->m_installThread.clear();
     204           0 : }
     205             : 
     206             : 
     207           0 : UpdateInstallDialog::UpdateInstallDialog(
     208             :     Window * parent,
     209             :     std::vector<dp_gui::UpdateData> & aVecUpdateData,
     210             :     cssu::Reference< cssu::XComponentContext > const & xCtx):
     211             :     ModalDialog(
     212             :         parent,
     213             :         DpGuiResId(RID_DLG_UPDATEINSTALL)),
     214             : 
     215           0 :         m_thread(new Thread(xCtx, *this, aVecUpdateData)),
     216             :         m_xComponentContext(xCtx),
     217             :         m_bError(false),
     218             :         m_bNoEntry(true),
     219             :         m_bActivated(false),
     220             :         m_sInstalling(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_INSTALLING))),
     221             :         m_sFinished(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_FINISHED))),
     222             :         m_sNoErrors(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_NO_ERRORS))),
     223             :         m_sErrorDownload(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD))),
     224             :         m_sErrorInstallation(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION))),
     225             :         m_sErrorLicenseDeclined(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED))),
     226             :         m_sNoInstall(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL))),
     227             :         m_sThisErrorOccurred(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED))),
     228             :         m_ft_action(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_DOWNLOADING)),
     229             :         m_statusbar(this,DpGuiResId(RID_DLG_UPDATE_INSTALL_STATUSBAR)),
     230             :         m_ft_extension_name(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NAME)),
     231             :         m_ft_results(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_RESULTS)),
     232             :         m_mle_info(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_INFO)),
     233             :         m_line(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_LINE)),
     234             :         m_help(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_HELP)),
     235             :         m_ok(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_OK)),
     236           0 :         m_cancel(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_ABORT))
     237             : {
     238           0 :     FreeResource();
     239             : 
     240           0 :     m_xExtensionManager = css::deployment::ExtensionManager::get( xCtx );
     241             : 
     242           0 :     m_cancel.SetClickHdl(LINK(this, UpdateInstallDialog, cancelHandler));
     243           0 :     m_mle_info.EnableCursor(sal_False);
     244           0 :     if ( ! dp_misc::office_is_running())
     245           0 :         m_help.Disable();
     246           0 : }
     247             : 
     248           0 : UpdateInstallDialog::~UpdateInstallDialog() {}
     249             : 
     250           0 : sal_Bool UpdateInstallDialog::Close()
     251             : {
     252           0 :     m_thread->stop();
     253           0 :     return ModalDialog::Close();
     254             : }
     255             : 
     256           0 : short UpdateInstallDialog::Execute()
     257             : {
     258           0 :     m_thread->launch();
     259           0 :     return ModalDialog::Execute();
     260             : }
     261             : 
     262             : 
     263             : // make sure the solar mutex is locked before calling
     264           0 : void UpdateInstallDialog::updateDone()
     265             : {
     266           0 :     if (!m_bError)
     267           0 :         m_mle_info.InsertText(m_sNoErrors);
     268           0 :     m_ok.Enable();
     269           0 :     m_ok.GrabFocus();
     270           0 :     m_cancel.Disable();
     271           0 : }
     272             : // make sure the solar mutex is locked before calling
     273             : //sets an error message in the text area
     274           0 : void UpdateInstallDialog::setError(INSTALL_ERROR err, OUString const & sExtension,
     275             :     OUString const & exceptionMessage)
     276             : {
     277           0 :     String sError;
     278           0 :     m_bError = true;
     279             : 
     280           0 :     switch (err)
     281             :     {
     282             :     case ERROR_DOWNLOAD:
     283           0 :         sError = m_sErrorDownload;
     284           0 :         break;
     285             :     case ERROR_INSTALLATION:
     286           0 :         sError = m_sErrorInstallation;
     287           0 :         break;
     288             :     case ERROR_LICENSE_DECLINED:
     289           0 :         sError = m_sErrorLicenseDeclined;
     290           0 :         break;
     291             : 
     292             :     default:
     293             :         OSL_ASSERT(0);
     294             :     }
     295             : 
     296           0 :     sError.SearchAndReplace(String("%NAME"), String(sExtension), 0);
     297             :     //We want to have an empty line between the error messages. However,
     298             :     //there shall be no empty line after the last entry.
     299           0 :     if (m_bNoEntry)
     300           0 :         m_bNoEntry = false;
     301             :     else
     302           0 :         m_mle_info.InsertText(OUString("\n"));
     303           0 :     m_mle_info.InsertText(sError);
     304             :     //Insert more information about the error
     305           0 :     if (!exceptionMessage.isEmpty())
     306           0 :         m_mle_info.InsertText(m_sThisErrorOccurred + exceptionMessage + "\n");
     307             : 
     308           0 :     m_mle_info.InsertText(m_sNoInstall);
     309           0 :     m_mle_info.InsertText(OUString("\n"));
     310           0 : }
     311             : 
     312           0 : void UpdateInstallDialog::setError(OUString const & exceptionMessage)
     313             : {
     314           0 :     m_bError = true;
     315           0 :     m_mle_info.InsertText(exceptionMessage + "\n");
     316           0 : }
     317             : 
     318           0 : IMPL_LINK_NOARG(UpdateInstallDialog, cancelHandler)
     319             : {
     320           0 :     m_thread->stop();
     321           0 :     EndDialog(RET_CANCEL);
     322           0 :     return 0;
     323             : }
     324             : 
     325             : //------------------------------------------------------------------------------------------------
     326             : 
     327           0 : void UpdateInstallDialog::Thread::downloadExtensions()
     328             : {
     329             :     try
     330             :     {
     331             :         //create the download directory in the temp folder
     332           0 :         OUString sTempDir;
     333           0 :         if (::osl::FileBase::getTempDirURL(sTempDir) != ::osl::FileBase::E_None)
     334           0 :             throw cssu::Exception("Could not get URL for the temp directory. No extensions will be installed.", 0);
     335             : 
     336             :         //create a unique name for the directory
     337           0 :         OUString tempEntry, destFolder;
     338           0 :         if (::osl::File::createTempFile(&sTempDir, 0, &tempEntry ) != ::osl::File::E_None)
     339           0 :             throw cssu::Exception("Could not create a temporary file in " + sTempDir +
     340           0 :              ". No extensions will be installed", 0 );
     341             : 
     342           0 :         tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
     343             : 
     344           0 :         destFolder = dp_misc::makeURL( sTempDir, tempEntry );
     345           0 :         destFolder += "_";
     346           0 :         m_sDownloadFolder = destFolder;
     347             :         try
     348             :         {
     349           0 :             dp_misc::create_folder(0, destFolder, m_updateCmdEnv.get(), true );
     350           0 :         } catch (const cssu::Exception & e)
     351             :         {
     352           0 :             throw cssu::Exception(e.Message + " No extensions will be installed.", 0);
     353             :         }
     354             : 
     355             : 
     356           0 :         sal_uInt16 count = 0;
     357             :         typedef std::vector<UpdateData>::iterator It;
     358           0 :         for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); ++i)
     359             :         {
     360           0 :             UpdateData & curData = *i;
     361             : 
     362           0 :             if (!curData.aUpdateInfo.is() || curData.aUpdateSource.is())
     363           0 :                 continue;
     364             :             //We assume that m_aVecUpdateData contains only information about extensions which
     365             :             //can be downloaded directly.
     366             :             OSL_ASSERT(curData.sWebsiteURL.isEmpty());
     367             : 
     368             :             //update the name of the extension which is to be downloaded
     369             :             {
     370           0 :                 SolarMutexGuard g;
     371           0 :                 if (m_stop) {
     372           0 :                     return;
     373             :                 }
     374           0 :                 m_dialog.m_ft_extension_name.SetText(curData.aInstalledPackage->getDisplayName());
     375           0 :                 sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
     376           0 :                     sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
     377           0 :                 m_dialog.m_statusbar.SetValue(prog);
     378             :             }
     379           0 :             dp_misc::DescriptionInfoset info(m_xComponentContext, curData.aUpdateInfo);
     380             :             //remember occurring exceptions in case we need to print out error information
     381           0 :             ::std::vector< ::std::pair<OUString, cssu::Exception> > vecExceptions;
     382           0 :             cssu::Sequence<OUString> seqDownloadURLs = info.getUpdateDownloadUrls();
     383             :             OSL_ENSURE(seqDownloadURLs.getLength() > 0, "No download URL provided!");
     384           0 :             for (sal_Int32 j = 0; j < seqDownloadURLs.getLength(); j++)
     385             :             {
     386             :                 try
     387             :                 {
     388             :                     OSL_ENSURE(!seqDownloadURLs[j].isEmpty(), "Download URL is empty!");
     389           0 :                     download(seqDownloadURLs[j], curData);
     390           0 :                     if (!curData.sLocalURL.isEmpty())
     391           0 :                         break;
     392             :                 }
     393           0 :                 catch ( cssu::Exception & e )
     394             :                 {
     395           0 :                     vecExceptions.push_back( ::std::make_pair(seqDownloadURLs[j], e));
     396             :                     //There can be several different errors, for example, the URL is wrong, webserver cannot be reached,
     397             :                     //name cannot be resolved. The UCB helper API does not specify different special exceptions for these
     398             :                     //cases. Therefore ignore and continue.
     399           0 :                     continue;
     400             :                 }
     401             :             }
     402             :             //update the progress and display download error
     403             :             {
     404           0 :                 SolarMutexGuard g;
     405           0 :                 if (m_stop) {
     406           0 :                     return;
     407             :                 }
     408           0 :                 if (curData.sLocalURL.isEmpty())
     409             :                 {
     410             :                     //Construct a string of all messages contained in the exceptions plus the respective download URLs
     411           0 :                     OUStringBuffer buf(256);
     412             :                     typedef ::std::vector< ::std::pair<OUString, cssu::Exception > >::const_iterator CIT;
     413           0 :                     for (CIT j = vecExceptions.begin(); j != vecExceptions.end(); ++j)
     414             :                     {
     415           0 :                         if (j != vecExceptions.begin())
     416           0 :                             buf.appendAscii("\n");
     417           0 :                         buf.append("Could not download ");
     418           0 :                         buf.append(j->first);
     419           0 :                         buf.appendAscii(". ");
     420           0 :                         buf.append(j->second.Message);
     421             :                     }
     422           0 :                     m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.aInstalledPackage->getDisplayName(),
     423           0 :                         buf.makeStringAndClear());
     424           0 :                 }
     425             :             }
     426             : 
     427           0 :         }
     428             :     }
     429           0 :     catch (const cssu::Exception & e)
     430             :     {
     431           0 :         SolarMutexGuard g;
     432           0 :         if (m_stop) {
     433           0 :             return;
     434             :         }
     435           0 :         m_dialog.setError(e.Message);
     436           0 :     }
     437             : }
     438           0 : void UpdateInstallDialog::Thread::installExtensions()
     439             : {
     440             :     //Update the fix text in the dialog to "Installing extensions..."
     441             :     {
     442           0 :         SolarMutexGuard g;
     443           0 :         if (m_stop) {
     444           0 :             return;
     445             :         }
     446           0 :         m_dialog.m_ft_action.SetText(m_dialog.m_sInstalling);
     447           0 :         m_dialog.m_statusbar.SetValue(0);
     448             :     }
     449             : 
     450           0 :     sal_uInt16 count = 0;
     451             :     typedef std::vector<UpdateData>::iterator It;
     452           0 :     for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); ++i, ++count)
     453             :     {
     454             :         //update the name of the extension which is to be installed
     455             :         {
     456           0 :             SolarMutexGuard g;
     457           0 :             if (m_stop) {
     458           0 :                 return;
     459             :             }
     460             :             //we only show progress after an extension has been installed.
     461           0 :             if (count > 0) {
     462             :                 m_dialog.m_statusbar.SetValue(
     463           0 :                 (sal::static_int_cast<sal_uInt16>(100) * count) /
     464           0 :                 sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
     465             :              }
     466           0 :             m_dialog.m_ft_extension_name.SetText(i->aInstalledPackage->getDisplayName());
     467             :         }
     468           0 :         bool bError = false;
     469           0 :         bool bLicenseDeclined = false;
     470           0 :         cssu::Reference<css::deployment::XPackage> xExtension;
     471           0 :         UpdateData & curData = *i;
     472           0 :         cssu::Exception exc;
     473             :         try
     474             :         {
     475             :             cssu::Reference< css::task::XAbortChannel > xAbortChannel(
     476           0 :                 curData.aInstalledPackage->createAbortChannel() );
     477             :             {
     478           0 :                 SolarMutexGuard g;
     479           0 :                 if (m_stop) {
     480           0 :                     return;
     481             :                 }
     482           0 :                 m_abort = xAbortChannel;
     483             :             }
     484           0 :             if (!curData.aUpdateSource.is() && !curData.sLocalURL.isEmpty())
     485             :             {
     486           0 :                 css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::makeAny(OUString("1")));
     487           0 :                 if (!curData.bIsShared)
     488           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     489             :                         curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     490           0 :                         "user", xAbortChannel, m_updateCmdEnv.get());
     491             :                 else
     492           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     493             :                         curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     494           0 :                         "shared", xAbortChannel, m_updateCmdEnv.get());
     495             :             }
     496           0 :             else if (curData.aUpdateSource.is())
     497             :             {
     498             :                 OSL_ASSERT(curData.aUpdateSource.is());
     499             :                 //I am not sure if we should obtain the install properties and pass them into
     500             :                 //add extension. Currently it contains only "SUPPRESS_LICENSE". So it it could happen
     501             :                 //that a license is displayed when updating from the shared repository, although the
     502             :                 //shared extension was installed using "SUPPRESS_LICENSE".
     503           0 :                 css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::makeAny(OUString("1")));
     504           0 :                 if (!curData.bIsShared)
     505           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     506           0 :                         curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     507           0 :                         "user", xAbortChannel, m_updateCmdEnv.get());
     508             :                 else
     509           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     510           0 :                         curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     511           0 :                         "shared", xAbortChannel, m_updateCmdEnv.get());
     512           0 :             }
     513             :         }
     514           0 :         catch (css::deployment::DeploymentException & de)
     515             :         {
     516           0 :             if (de.Cause.has<css::deployment::LicenseException>())
     517             :             {
     518           0 :                 bLicenseDeclined = true;
     519             :             }
     520             :             else
     521             :             {
     522           0 :                 exc = de.Cause.get<cssu::Exception>();
     523           0 :                 bError = true;
     524             :             }
     525             :         }
     526           0 :         catch (cssu::Exception& e)
     527             :         {
     528           0 :             exc = e;
     529           0 :             bError = true;
     530             :         }
     531             : 
     532           0 :         if (bLicenseDeclined)
     533             :         {
     534           0 :             SolarMutexGuard g;
     535           0 :             if (m_stop) {
     536           0 :                 return;
     537             :             }
     538             :             m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED,
     539           0 :                 curData.aInstalledPackage->getDisplayName(), OUString());
     540             :         }
     541           0 :         else if (!xExtension.is() || bError)
     542             :         {
     543           0 :             SolarMutexGuard g;
     544           0 :             if (m_stop) {
     545           0 :                 return;
     546             :             }
     547             :             m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION,
     548           0 :                 curData.aInstalledPackage->getDisplayName(), exc.Message);
     549             :         }
     550           0 :     }
     551             :     {
     552           0 :         SolarMutexGuard g;
     553           0 :         if (m_stop) {
     554           0 :             return;
     555             :         }
     556           0 :         m_dialog.m_statusbar.SetValue(100);
     557           0 :         m_dialog.m_ft_extension_name.SetText(OUString());
     558           0 :         m_dialog.m_ft_action.SetText(m_dialog.m_sFinished);
     559             :     }
     560             : }
     561             : 
     562           0 : void UpdateInstallDialog::Thread::removeTempDownloads()
     563             : {
     564           0 :     if (!m_sDownloadFolder.isEmpty())
     565             :     {
     566             :         dp_misc::erase_path(m_sDownloadFolder,
     567           0 :             cssu::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
     568             :         //remove also the temp file which we have used to create the unique name
     569           0 :         OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
     570           0 :         dp_misc::erase_path(tempFile, cssu::Reference<css::ucb::XCommandEnvironment>(),false);
     571           0 :         m_sDownloadFolder = OUString();
     572             :     }
     573           0 : }
     574             : 
     575             : 
     576           0 : void UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
     577             : {
     578             :     {
     579           0 :         SolarMutexGuard g;
     580           0 :         if (m_stop) {
     581           0 :             return;
     582           0 :         }
     583             :     }
     584             : 
     585             :     OSL_ASSERT(m_sDownloadFolder.getLength());
     586           0 :     OUString destFolder, tempEntry;
     587           0 :     if (::osl::File::createTempFile(
     588             :         &m_sDownloadFolder,
     589           0 :         0, &tempEntry ) != ::osl::File::E_None)
     590             :     {
     591             :         //ToDo feedback in window that download of this component failed
     592           0 :         throw cssu::Exception("Could not create temporary file in folder " + destFolder + ".", 0);
     593             :     }
     594           0 :     tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
     595             : 
     596           0 :     destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry );
     597           0 :     destFolder += "_";
     598             : 
     599           0 :     ::ucbhelper::Content destFolderContent;
     600           0 :     dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv.get() );
     601             : 
     602           0 :     ::ucbhelper::Content sourceContent;
     603           0 :     dp_misc::create_ucb_content( &sourceContent, sDownloadURL, m_updateCmdEnv.get() );
     604             : 
     605           0 :     const OUString sTitle( StrTitle::getTitle( sourceContent ) );
     606             : 
     607           0 :     if (destFolderContent.transferContent(
     608             :             sourceContent, ::ucbhelper::InsertOperation_COPY,
     609           0 :             sTitle, css::ucb::NameClash::OVERWRITE ))
     610             :     {
     611             :         //the user may have cancelled the dialog because downloading took to long
     612             :         {
     613           0 :             SolarMutexGuard g;
     614           0 :             if (m_stop) {
     615           0 :                 return;
     616             :             }
     617             :             //all errors should be handeld by the command environment.
     618           0 :             aUpdateData.sLocalURL = destFolder + "/" + sTitle;
     619             :         }
     620           0 :     }
     621             : }
     622             : 
     623             : 
     624             : // -------------------------------------------------------------------------------------------------------
     625             : 
     626           0 : UpdateCommandEnv::UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
     627             :     ::rtl::Reference<UpdateInstallDialog::Thread>const & thread)
     628             :     : m_installThread(thread),
     629           0 :     m_xContext(xCtx)
     630             : {
     631           0 : }
     632             : 
     633           0 : UpdateCommandEnv::~UpdateCommandEnv()
     634             : {
     635           0 : }
     636             : 
     637             : 
     638             : // XCommandEnvironment
     639             : //______________________________________________________________________________
     640           0 : cssu::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
     641             : throw (cssu::RuntimeException)
     642             : {
     643           0 :     return this;
     644             : }
     645             : 
     646             : //______________________________________________________________________________
     647           0 : cssu::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
     648             : throw (cssu::RuntimeException)
     649             : {
     650           0 :     return this;
     651             : }
     652             : 
     653             : // XInteractionHandler
     654           0 : void UpdateCommandEnv::handle(
     655             :     cssu::Reference< css::task::XInteractionRequest> const & xRequest )
     656             :     throw (cssu::RuntimeException)
     657             : {
     658           0 :     cssu::Any request( xRequest->getRequest() );
     659             :     OSL_ASSERT( request.getValueTypeClass() == cssu::TypeClass_EXCEPTION );
     660             :     dp_misc::TRACE("[dp_gui_cmdenv.cxx] incoming request:\n"
     661           0 :         + ::comphelper::anyToString(request) + "\n\n");
     662             : 
     663           0 :     css::deployment::VersionException verExc;
     664           0 :     bool approve = false;
     665           0 :     bool abort = false;
     666             : 
     667           0 :     if (request >>= verExc)
     668             :     {   //We must catch the version exception during the update,
     669             :         //because otherwise the user would be confronted with the dialogs, asking
     670             :         //them if they want to replace an already installed version of the same extension.
     671             :         //During an update we assume that we always want to replace the old version with the
     672             :         //new version.
     673           0 :         approve = true;
     674             :     }
     675             : 
     676           0 :     if (approve == false && abort == false)
     677             :     {
     678             :         //forward to interaction handler for main dialog.
     679           0 :         handleInteractionRequest( m_xContext, xRequest );
     680             :     }
     681             :     else
     682             :     {
     683             :         // select:
     684             :         cssu::Sequence< cssu::Reference< css::task::XInteractionContinuation > > conts(
     685           0 :             xRequest->getContinuations() );
     686             :         cssu::Reference< css::task::XInteractionContinuation > const * pConts =
     687           0 :             conts.getConstArray();
     688           0 :         sal_Int32 len = conts.getLength();
     689           0 :         for ( sal_Int32 pos = 0; pos < len; ++pos )
     690             :         {
     691           0 :             if (approve) {
     692             :                 cssu::Reference< css::task::XInteractionApprove > xInteractionApprove(
     693           0 :                     pConts[ pos ], cssu::UNO_QUERY );
     694           0 :                 if (xInteractionApprove.is()) {
     695           0 :                     xInteractionApprove->select();
     696             :                     // don't query again for ongoing continuations:
     697           0 :                     approve = false;
     698           0 :                 }
     699             :             }
     700           0 :             else if (abort) {
     701             :                 cssu::Reference< css::task::XInteractionAbort > xInteractionAbort(
     702           0 :                     pConts[ pos ], cssu::UNO_QUERY );
     703           0 :                 if (xInteractionAbort.is()) {
     704           0 :                     xInteractionAbort->select();
     705             :                     // don't query again for ongoing continuations:
     706           0 :                     abort = false;
     707           0 :                 }
     708             :             }
     709           0 :         }
     710           0 :     }
     711           0 : }
     712             : 
     713             : // XProgressHandler
     714           0 : void UpdateCommandEnv::push( cssu::Any const & /*Status*/ )
     715             : throw (cssu::RuntimeException)
     716             : {
     717           0 : }
     718             : 
     719             : 
     720           0 : void UpdateCommandEnv::update( cssu::Any const & /*Status */)
     721             : throw (cssu::RuntimeException)
     722             : {
     723           0 : }
     724             : 
     725           0 : void UpdateCommandEnv::pop() throw (cssu::RuntimeException)
     726             : {
     727           0 : }
     728             : 
     729             : 
     730           0 : } //end namespace dp_gui
     731             : 
     732             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10