LCOV - code coverage report
Current view: top level - desktop/source/deployment/gui - dp_gui_updateinstalldialog.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 265 0.0 %
Date: 2012-08-25 Functions: 0 28 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.10