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

Generated by: LCOV version 1.11