[Libreoffice-commits] .: 12 commits - configmgr/source desktop/inc desktop/source framework/inc framework/source

Jan Holesovsky kendy at kemper.freedesktop.org
Sun Oct 24 09:46:23 PDT 2010


 configmgr/source/components.cxx                              |   84 +
 configmgr/source/components.hxx                              |    8 
 configmgr/source/configurationprovider.cxx                   |   16 
 desktop/inc/app.hxx                                          |    1 
 desktop/source/app/app.cxx                                   |   32 
 desktop/source/deployment/manager/dp_commandenvironments.cxx |   55 -
 desktop/source/deployment/manager/dp_commandenvironments.hxx |   51 -
 desktop/source/deployment/manager/dp_extensionmanager.cxx    |  532 ++++++-----
 desktop/source/deployment/manager/dp_extensionmanager.hxx    |   76 -
 framework/inc/framework.hrc                                  |    8 
 framework/source/services/backingwindow.cxx                  |    8 
 11 files changed, 591 insertions(+), 280 deletions(-)

New commits:
commit e655e92b3ffecba794041df652fe9eaaf3b66eee
Merge: 91e635b... 84d5075...
Author: Jan Holesovsky <kendy at suse.cz>
Date:   Sun Oct 24 16:53:14 2010 +0200

    Merge commit 'ooo/OOO330_m12'
    
    Conflicts:
    	desktop/source/app/app.cxx

diff --cc desktop/source/app/app.cxx
index 6ad3ddd,663cca1..fb5e3f7
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@@ -755,7 -753,8 +755,8 @@@ void Desktop::DeInit(
      try {
          // instead of removing of the configManager just let it commit all the changes
          RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
 -        utl::ConfigManager::GetConfigManager()->StoreConfigItems();
 +        utl::ConfigManager::GetConfigManager().StoreConfigItems();
+         FlushConfiguration();
          RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
  
          // close splashscreen if it's still open
@@@ -2060,6 -2065,22 +2052,22 @@@ sal_Bool Desktop::InitializeConfigurati
      return bOk;
  }
  
+ void Desktop::FlushConfiguration()
+ {
 -    Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
++    Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager().GetConfigurationProvider(), UNO_QUERY );
+     if (xCFGFlush.is())
+     {
+         xCFGFlush->flush();
+     }
+     else
+     {
+         // because there is no method to flush the condiguration data, we must dispose the ConfigManager
 -        Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
++        Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager().GetConfigurationProvider(), UNO_QUERY );
+         if (xCFGDispose.is())
+             xCFGDispose->dispose();
+     }
+ }
+ 
  sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
  {
      try
diff --cc desktop/source/deployment/manager/dp_commandenvironments.cxx
index db0955f,f6995b9..ba32b30
--- a/desktop/source/deployment/manager/dp_commandenvironments.cxx
+++ b/desktop/source/deployment/manager/dp_commandenvironments.cxx
@@@ -2,7 -1,7 +2,7 @@@
  /*************************************************************************
   *
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-- * 
++ *
   * Copyright 2000, 2010 Oracle and/or its affiliates.
   *
   * OpenOffice.org - a multi-platform office productivity suite
@@@ -120,7 -121,7 +122,7 @@@ void BaseCommandEnv::handle_(bool appro
              else if (abort) {
                  Reference< task::XInteractionAbort > xInteractionAbort(
                      pConts[ pos ], uno::UNO_QUERY );
--                if (xInteractionAbort.is()) {           
++                if (xInteractionAbort.is()) {
                      xInteractionAbort->select();
                      // don't query again for ongoing continuations:
                      abort = false;
@@@ -137,7 -138,7 +139,6 @@@ throw (uno::RuntimeException
  {
  }
  
--
  void BaseCommandEnv::update( uno::Any const & /*Status */)
  throw (uno::RuntimeException)
  {
@@@ -164,8 -165,8 +165,8 @@@ void TmpRepositoryCommandEnv::handle
  {
      uno::Any request( xRequest->getRequest() );
      OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
--    
--    deployment::VersionException verExc;	
++
++    deployment::VersionException verExc;
      deployment::LicenseException licExc;
      deployment::InstallException instExc;
  
@@@ -175,7 -176,7 +176,7 @@@
      if ((request >>= verExc)
          || (request >>= licExc)
          || (request >>= instExc))
--    { 
++    {
          approve = true;
      }
  
@@@ -198,7 -199,7 +199,6 @@@ void LicenseCommandEnv::handle
  {
      uno::Any request( xRequest->getRequest() );
      OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
--    
  
      deployment::LicenseException licExc;
  
@@@ -237,7 -238,7 +237,6 @@@ void NoLicenseCommandEnv::handle
  {
      uno::Any request( xRequest->getRequest() );
      OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
--    
  
      deployment::LicenseException licExc;
  
@@@ -251,7 -252,43 +250,43 @@@
      handle_(approve, abort, xRequest);
  }
  
+ // SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv(
+ //     css::uno::Reference< css::task::XInteractionHandler> const & handler):
+ //     BaseCommandEnv(handler)
+ // {
+ // }
+ SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv()
+ {
+ }
+ 
+ void SilentCheckPrerequisitesCommandEnv::handle(
+        Reference< task::XInteractionRequest> const & xRequest )
+     throw (uno::RuntimeException)
+ {
+     uno::Any request( xRequest->getRequest() );
+     OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
 -    
++
+     deployment::LicenseException licExc;
+     deployment::PlatformException platformExc;
+     deployment::DependencyException depExc;
+     bool approve = false;
+     bool abort = false;
  
+     if (request >>= licExc)
+     {
+         approve = true;
+         handle_(approve, abort, xRequest);
+     }
+     else if ((request >>= platformExc)
+              || (request >>= depExc))
+     {
+         m_Exception = request;
+     }
+     else
+     {
+         m_UnknownException = request;
+     }
+ }
  // NoExceptionCommandEnv::NoExceptionCommandEnv(
  //     css::uno::Reference< css::task::XInteractionHandler> const & handler,
  //     css::uno::Type const & type):
@@@ -266,7 -303,7 +301,6 @@@
  // {
  //     uno::Any request( xRequest->getRequest() );
  //     OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
--    
  
  // 	deployment::LicenseException licExc;
  
@@@ -280,9 -317,8 +314,6 @@@
  //     handle_(approve, abort, xRequest);
  // }
  
--
--
  } // namespace dp_manager
  
--
 +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --cc desktop/source/deployment/manager/dp_commandenvironments.hxx
index b7d9f6a,6662d1f..72446fe
--- a/desktop/source/deployment/manager/dp_commandenvironments.hxx
+++ b/desktop/source/deployment/manager/dp_commandenvironments.hxx
@@@ -1,7 -1,7 +1,7 @@@
  /*************************************************************************
   *
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-- * 
++ *
   * Copyright 2000, 2010 Oracle and/or its affiliates.
   *
   * OpenOffice.org - a multi-platform office productivity suite
@@@ -28,18 -28,19 +28,14 @@@
  #if ! defined INCLUDED_DP_COMMANDENVIRONMENTS_HXX
  #define INCLUDED_DP_COMMANDENVIRONMENTS_HXX
  
--
  #include "cppuhelper/compbase3.hxx"
  #include "ucbhelper/content.hxx"
  #include "com/sun/star/uno/Type.hxx"
  
--
  namespace css = ::com::sun::star;
  
  namespace dp_manager {
  
--
--
  /**
     This command environment is to be used when an extension is temporarily
     stored in the "tmp" repository. It prevents all kind of user interaction.
@@@ -49,7 -50,7 +45,7 @@@ class BaseCommandEn
                                        css::task::XInteractionHandler,
                                        css::ucb::XProgressHandler >
  {
--protected:    
++protected:
      css::uno::Reference< css::uno::XComponentContext > m_xContext;
      css::uno::Reference< css::task::XInteractionHandler> m_forwardHandler;
  
@@@ -85,12 -86,12 +81,12 @@@ class TmpRepositoryCommandEnv : public 
  public:
      TmpRepositoryCommandEnv();
      TmpRepositoryCommandEnv(css::uno::Reference< css::task::XInteractionHandler> const & handler);
--    
++
  // XInteractionHandler
      virtual void SAL_CALL handle(
          css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
          throw (css::uno::RuntimeException);
--    
++
  };
  
  /** this class is for use in XPackageManager::synchronize.
@@@ -108,12 -109,12 +104,12 @@@ public
          css::uno::Reference< css::task::XInteractionHandler> const & handler,
          bool bSuppressLicense,
          ::rtl::OUString const & repository);
--    
++
  // XInteractionHandler
      virtual void SAL_CALL handle(
          css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
          throw (css::uno::RuntimeException);
--    
++
  };
  
  /** this class is for use in XPackageManager::checkPrerequisites
@@@ -126,12 -127,35 +122,35 @@@ class NoLicenseCommandEnv : public Base
  public:
      NoLicenseCommandEnv(){};
      NoLicenseCommandEnv(css::uno::Reference< css::task::XInteractionHandler> const & handler);
--    
++
  // XInteractionHandler
      virtual void SAL_CALL handle(
          css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
          throw (css::uno::RuntimeException);
--    
++
+ };
+ 
+ /* For use in XExtensionManager::addExtension in the call to
+    XPackage::checkPrerequisites
+    It prevents all user interactions. The license is always accepted.
+    It remembers if there was a platform or a dependency exception in
+    the member m_bException. if there was any other exception then m_bUnknownException
+    is set.
 -   
++
+  */
+ class SilentCheckPrerequisitesCommandEnv : public BaseCommandEnv
+ {
+ public:
+     SilentCheckPrerequisitesCommandEnv();
+     // XInteractionHandler
+     virtual void SAL_CALL handle(
+         css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+         throw (css::uno::RuntimeException);
+ 
+     // Set to true if a PlatformException or a DependencyException were handled.
+     css::uno::Any m_Exception;
+     // Set to true if an unknown exception was handled.
 -    css::uno::Any m_UnknownException;    
++    css::uno::Any m_UnknownException;
  };
  
  // class NoExceptionCommandEnv : public BaseCommandEnv
@@@ -142,18 -166,18 +161,14 @@@
  //     NoExceptionCommandEnv::NoExceptionCommandEnv(
  //         css::uno::Reference< css::task::XInteractionHandler> const & handler,
  //         css::uno::Type const & type);
--    
++
  // // XInteractionHandler
  //     virtual void SAL_CALL handle(
  //         css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
  //         throw (css::uno::RuntimeException);
--    
++
  // };
  
  }
  
--
--
--
  #endif
--
diff --cc desktop/source/deployment/manager/dp_extensionmanager.cxx
index b9e32d7,c809685..c6529ec
--- a/desktop/source/deployment/manager/dp_extensionmanager.cxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@@ -2,7 -1,7 +2,7 @@@
  /*************************************************************************
   *
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-- * 
++ *
   * Copyright 2000, 2010 Oracle and/or its affiliates.
   *
   * OpenOffice.org - a multi-platform office productivity suite
@@@ -25,12 -24,12 +25,12 @@@
   * for a copy of the LGPLv3 License.
   *
   ************************************************************************/
-- 
++
  // MARKER(update_precomp.py): autogen include statement, do not remove
  #include "precompiled_desktop.hxx"
  
  #include <cppuhelper/implbase1.hxx>
--  
++
  #include "comphelper/servicedecl.hxx"
  #include "cppuhelper/exc_hlp.hxx"
  #include "rtl/bootstrap.hxx"
@@@ -78,7 -77,7 +78,6 @@@ namespace beans = com::sun::star::beans
  namespace util = com::sun::star::util;
  namespace css = com::sun::star;
  
--
  //#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
  
  using ::com::sun::star::uno::Reference;
@@@ -103,7 -102,7 +102,7 @@@ struct CompIdentifier
  OUString CompIdentifiers::getName(::std::vector<Reference<deploy::XPackage> > const & a)
  {
      OSL_ASSERT(a.size() == 3);
--    //get the first non-null reference 
++    //get the first non-null reference
      Reference<deploy::XPackage>  extension;
      ::std::vector<Reference<deploy::XPackage> >::const_iterator it = a.begin();
      for (; it != a.end(); it++)
@@@ -140,12 -139,43 +139,41 @@@ void writeLastModified(OUString & url, 
              OUSTR("Failed to update") + url, 0, exc);
      }
  }
- } //end namespace
  
- namespace dp_manager {
+ class ExtensionRemoveGuard
+ {
+     css::uno::Reference<css::deployment::XPackage> m_extension;
+     css::uno::Reference<css::deployment::XPackageManager> m_xPackageManager;
+ 
+ public:
+     ExtensionRemoveGuard(
+         css::uno::Reference<css::deployment::XPackage> const & extension,
+         css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager):
+         m_extension(extension), m_xPackageManager(xPackageManager) {}
+     ~ExtensionRemoveGuard();
+ 
+     void reset(css::uno::Reference<css::deployment::XPackage> const & extension) {
+         m_extension = extension;
+     }
+ };
+ 
+ ExtensionRemoveGuard::~ExtensionRemoveGuard()
+ {
+     try {
+         if (m_xPackageManager.is() && m_extension.is())
+             m_xPackageManager->removePackage(
+                 dp_misc::getIdentifier(m_extension), ::rtl::OUString(),
+                 css::uno::Reference<css::task::XAbortChannel>(),
+                 css::uno::Reference<css::ucb::XCommandEnvironment>());
+     } catch (...) {
+         OSL_ASSERT(0);
+     }
+ }
  
+ } //end namespace
  
+ namespace dp_manager {
  
 -
 -
  //------------------------------------------------------------------------------
  
  //ToDo: bundled extension
@@@ -161,7 -191,7 +189,7 @@@ ExtensionManager::ExtensionManager( Ref
      m_tmpRepository =  xPackageManagerFactory->getPackageManager(OUSTR("tmp"));
  
      m_repositoryNames.push_back(OUSTR("user"));
--    m_repositoryNames.push_back(OUSTR("shared"));    
++    m_repositoryNames.push_back(OUSTR("shared"));
      m_repositoryNames.push_back(OUSTR("bundled"));
  }
  
@@@ -190,12 -220,12 +218,11 @@@ ExtensionManager::getPackageManager(::r
          xPackageManager = m_bundledRepository;
      else
          throw lang::IllegalArgumentException(
--            OUSTR("No valid repository name provided."), 
++            OUSTR("No valid repository name provided."),
              static_cast<cppu::OWeakObject*>(this), 0);
      return xPackageManager;
  }
  
--
  /*
    Enters the XPackage objects into a map. They must be all from the
    same repository. The value type of the map is a vector, where each vector
@@@ -218,7 -248,7 +245,7 @@@ void ExtensionManager::addExtensionsToM
          if (citNames->equals(repository))
              break;
      }
--    
++
      for (int i = 0; i < seqExt.getLength(); i++)
      {
          Reference<deploy::XPackage> const & xExtension = seqExt[i];
@@@ -237,7 -267,7 +264,7 @@@
      }
  }
  
--/* 
++/*
     returns a list containing extensions with the same identifier from
     all repositories (user, shared, bundled) If one repository does not
     have this extension, then the list contains an empty Referenc. The list
@@@ -256,7 -286,7 +283,7 @@@
  
  {
      ::std::list<Reference<deploy::XPackage> > extensionList;
--    try 
++    try
      {   //will throw an exception if the extension does not exist
          extensionList.push_back(m_userRepository->getDeployedPackage(
              identifier, fileName, Reference<ucb::XCommandEnvironment>()));
@@@ -290,14 -320,14 +317,14 @@@ ExtensionManager::getExtensionsWithSame
          OUString const & fileName,
          Reference< ucb::XCommandEnvironment> const & xCmdEnv )
          throw (
--            deploy::DeploymentException, 
++            deploy::DeploymentException,
              ucb::CommandFailedException,
              lang::IllegalArgumentException,
              uno::RuntimeException)
  {
      try
      {
--        ::std::list<Reference<deploy::XPackage> > listExtensions = 
++        ::std::list<Reference<deploy::XPackage> > listExtensions =
              getExtensionsWithSameId(
                  identifier, fileName, xCmdEnv);
          sal_Bool bHasExtension = false;
@@@ -308,7 -338,7 +335,7 @@@
              bHasExtension |= i->is();
          if (!bHasExtension)
              throw lang::IllegalArgumentException(
--                OUSTR("Could not find extension: ") + identifier + OUSTR(", ") + fileName, 
++                OUSTR("Could not find extension: ") + identifier + OUSTR(", ") + fileName,
                  static_cast<cppu::OWeakObject*>(this), -1);
  
          return comphelper::containerToSequence<
@@@ -337,8 -367,8 +364,6 @@@
      }
  }
  
--
--
  bool ExtensionManager::isUserDisabled(
      OUString const & identifier, OUString const & fileName)
  {
@@@ -373,15 -403,15 +398,15 @@@ bool ExtensionManager::isUserDisabled
              ! reg.Value.IsAmbiguous && ! reg.Value.Value)
              return true;
      }
--    return false;    
++    return false;
  }
  
  /*
      This method determines the active extension (XPackage.registerPackage) with a
--    particular identifier. 
++    particular identifier.
  
      The parameter bUserDisabled determines if the user extension is disabled.
--    
++
      When the user repository contains an extension with the given identifier and
      it is not disabled by the user, then it is always registered.  Otherwise an
      extension is only registered when there is no registered extension in one of
@@@ -454,7 -484,7 +479,7 @@@ void ExtensionManager::activateExtensio
              {
                  //This is the first extension in the ordered list, which becomes
                  //the active extension
--                bActive = true;    
++                bActive = true;
                  //Register if not already done.
                  //reregister if the value is ambiguous, which indicates that
                  //something went wrong during last registration.
@@@ -496,11 -526,112 +521,112 @@@ Reference<deploy::XPackage> ExtensionMa
  //Because all repositories support the same backends, we can just delegate this
  //call to one of the repositories.
  uno::Sequence< Reference<deploy::XPackageTypeInfo> >
--ExtensionManager::getSupportedPackageTypes() 
++ExtensionManager::getSupportedPackageTypes()
      throw (uno::RuntimeException)
  {
      return m_userRepository->getSupportedPackageTypes();
  }
+ //Do some necessary checks and user interaction. This function does not
+ //aquire the extension manager mutex and that mutex must not be aquired
+ //when this function is called. doChecksForAddExtension does  synchronous
+ //user interactions which may require aquiring the solar mutex.
+ //Returns true if the extension can be installed.
+ bool ExtensionManager::doChecksForAddExtension(
+     Reference<deploy::XPackageManager> const & xPackageMgr,
+     uno::Sequence<beans::NamedValue> const & properties,
+     css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
+     Reference<task::XAbortChannel> const & xAbortChannel,
+     Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+     Reference<deploy::XPackage> & out_existingExtension )
 -    throw (deploy::DeploymentException, 
++    throw (deploy::DeploymentException,
+            ucb::CommandFailedException,
 -           ucb::CommandAbortedException, 
++           ucb::CommandAbortedException,
+            lang::IllegalArgumentException,
+            uno::RuntimeException)
+ {
+     try
+     {
+         Reference<deploy::XPackage> xOldExtension;
+         const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
+         const OUString sFileName = xTmpExtension->getName();
+         const OUString sDisplayName = xTmpExtension->getDisplayName();
+         const OUString sVersion = xTmpExtension->getVersion();
 -        
++
+         try
+         {
+             xOldExtension = xPackageMgr->getDeployedPackage(
+                 sIdentifier, sFileName, xCmdEnv);
+             out_existingExtension = xOldExtension;
+         }
+         catch (lang::IllegalArgumentException &)
+         {
+         }
+         bool bCanInstall = false;
+ 
+         //This part is not guarded against other threads removing, adding, disabling ...
 -        //etc. the same extension. 
++        //etc. the same extension.
+         //checkInstall is safe because it notifies the user if the extension is not yet
+         //installed in the same repository. Because addExtension has its own guard
+         //(m_addMutex), another thread cannot add the extension in the meantime.
+         //checkUpdate is called if the same extension exists in the same
+         //repository. The user is asked if they want to replace it.  Another
+         //thread
+         //could already remove the extension. So asking the user was not
+         //necessary. No harm is done. The other thread may also ask the user
+         //if he wants to remove the extension. This depends on the
+         //XCommandEnvironment which it passes to removeExtension.
+         if (xOldExtension.is())
+         {
+             //throws a CommandFailedException if the user cancels
+             //the action.
+             checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
+         }
+         else
+         {
+             //throws a CommandFailedException if the user cancels
+             //the action.
+             checkInstall(sDisplayName, xCmdEnv);
+         }
+         //Prevent showing the license if requested.
+         Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
+         ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
+ 
+         dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
+         const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
+             info.getSimpleLicenseAttributes();
+ 
+         if (licenseAttributes && licenseAttributes->suppressIfRequired
+             && props.isSuppressedLicense())
+             _xCmdEnv = Reference<ucb::XCommandEnvironment>(
+                 new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
 -            
++
+         bCanInstall = xTmpExtension->checkPrerequisites(
+             xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
+ 
+         return bCanInstall;
+     }
+     catch (deploy::DeploymentException& ) {
+         throw;
+     } catch (ucb::CommandFailedException & ) {
+         throw;
+     } catch (ucb::CommandAbortedException & ) {
+         throw;
+     } catch (lang::IllegalArgumentException &) {
+         throw;
+     } catch (uno::RuntimeException &) {
+         throw;
+     } catch (uno::Exception &) {
+         uno::Any excOccurred = ::cppu::getCaughtException();
+         deploy::DeploymentException exc(
+             OUSTR("Extension Manager: exception in doChecksForAddExtension"),
+             static_cast<OWeakObject*>(this), excOccurred);
+         throw exc;
+     } catch (...) {
+         throw uno::RuntimeException(
+             OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
+             static_cast<OWeakObject*>(this));
+     }
+ }
  
  // Only add to shared and user repository
  Reference<deploy::XPackage> ExtensionManager::addExtension(
@@@ -523,168 -654,186 +649,186 @@@
          xPackageManager = m_sharedRepository;
      else
          throw lang::IllegalArgumentException(
--            OUSTR("No valid repository name provided."), 
++            OUSTR("No valid repository name provided."),
              static_cast<cppu::OWeakObject*>(this), 0);
-     ::osl::MutexGuard guard(getMutex());
+     //We must make sure that the xTmpExtension is not create twice, because this
+     //would remove the first one.
+     ::osl::MutexGuard addGuard(m_addMutex);
 -    
++
      Reference<deploy::XPackage> xTmpExtension =
          getTempExtension(url, xAbortChannel, xCmdEnv);
+     //Make sure the extension is removed from the tmp repository in case
+     //of an exception
+     ExtensionRemoveGuard tmpExtensionRemoveGuard(xTmpExtension, m_tmpRepository);
      const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
      const OUString sFileName = xTmpExtension->getName();
      Reference<deploy::XPackage> xOldExtension;
      Reference<deploy::XPackage> xExtensionBackup;
  
-     uno::Any excOccurred1;
      uno::Any excOccurred2;
      bool bUserDisabled = false;
-     try 
+     bool bCanInstall = doChecksForAddExtension(
+         xPackageManager,
+         properties,
+         xTmpExtension,
+         xAbortChannel,
+         xCmdEnv,
+         xOldExtension );
+ 
      {
-         bUserDisabled = isUserDisabled(sIdentifier, sFileName);
-         try
-         {
-             xOldExtension = xPackageManager->getDeployedPackage(
-                 sIdentifier, sFileName, xCmdEnv);
-         }
-         catch (lang::IllegalArgumentException &)
-         {
-         }
-         bool bCanInstall = false;
-         try
+         // In this garded section (getMutex) we must not use the argument xCmdEnv
+         // because it may bring up dialogs (XInteractionHandler::handle) this
+         //may potententially deadlock. See issue
+         //http://qa.openoffice.org/issues/show_bug.cgi?id=114933
+         //By not providing xCmdEnv the underlying APIs will throw an exception if
+         //the XInteractionRequest cannot be handled
+         ::osl::MutexGuard guard(getMutex());
 - 
++
+         if (bCanInstall)
          {
-             if (xOldExtension.is())
+             try
              {
-                 //throws a CommandFailedException if the user cancels
-                 //the action.
-                 checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
+                 bUserDisabled = isUserDisabled(sIdentifier, sFileName);
+                 if (xOldExtension.is())
+                 {
+                     try
+                     {
+                         xOldExtension->revokePackage(
+                             xAbortChannel, Reference<ucb::XCommandEnvironment>());
+                         //save the old user extension in case the user aborts
 -                        //store the extension in the tmp repository, this will overwrite 
 -                        //xTmpPackage (same identifier). Do not let the user abort or 
++                        //store the extension in the tmp repository, this will overwrite
++                        //xTmpPackage (same identifier). Do not let the user abort or
+                         //interact
+                         //importing the old extension in the tmp repository will remove
+                         //the xTmpExtension
+                         //no command environment supplied, only this class shall interact
+                         //with the user!
+                         xExtensionBackup = m_tmpRepository->importExtension(
 -                            xOldExtension, Reference<task::XAbortChannel>(), 
++                            xOldExtension, Reference<task::XAbortChannel>(),
+                             Reference<ucb::XCommandEnvironment>());
+                         tmpExtensionRemoveGuard.reset(xExtensionBackup);
+                         //xTmpExtension will later be used to check the dependencies
+                         //again. However, only xExtensionBackup will be later removed
+                         //from the tmp repository
+                         xTmpExtension = xExtensionBackup;
+                         OSL_ASSERT(xTmpExtension.is());
+                     }
+                     catch (lang::DisposedException &)
+                     {
+                         //Another thread might have removed the extension meanwhile
+                     }
+                 }
+                 //check again dependencies but prevent user interaction,
+                 //We can disregard the license, because the user must have already
+                 //accepted it, whe we called checkPrerequisites the first time
+                 SilentCheckPrerequisitesCommandEnv * pSilentCommandEnv =
+                     new SilentCheckPrerequisitesCommandEnv();
+                 Reference<ucb::XCommandEnvironment> silentCommandEnv(pSilentCommandEnv);
 -                
++
+                 sal_Int32 failedPrereq = xTmpExtension->checkPrerequisites(
+                     xAbortChannel, silentCommandEnv, true);
+                 if (failedPrereq == 0)
+                 {
+                     xNewExtension = xPackageManager->addPackage(
+                         url, properties, OUString(), xAbortChannel,
+                         Reference<ucb::XCommandEnvironment>());
+                     //If we add a user extension and there is already one which was
+                     //disabled by a user, then the newly installed one is enabled. If we
+                     //add to another repository then the user extension remains
+                     //disabled.
+                     bool bUserDisabled2 = bUserDisabled;
+                     if (repository.equals(OUSTR("user")))
+                         bUserDisabled2 = false;
 -                
++
+                     activateExtension(
+                         dp_misc::getIdentifier(xNewExtension),
+                         xNewExtension->getName(), bUserDisabled2, false, xAbortChannel,
+                         Reference<ucb::XCommandEnvironment>());
+                 }
+                 else
+                 {
+                     if (pSilentCommandEnv->m_Exception.hasValue())
+                         ::cppu::throwException(pSilentCommandEnv->m_Exception);
+                     else if ( pSilentCommandEnv->m_UnknownException.hasValue())
+                         ::cppu::throwException(pSilentCommandEnv->m_UnknownException);
+                     else
+                         throw deploy::DeploymentException (
+                             OUSTR("Extension Manager: exception during addExtension, ckeckPrerequisites failed"),
+                             static_cast<OWeakObject*>(this), uno::Any());
 -                }        
++                }
              }
-             else
-             {
-                 //throws a CommandFailedException if the user cancels
-                 //the action.
-                 checkInstall(sDisplayName, xCmdEnv);
+             catch (deploy::DeploymentException& ) {
+                 excOccurred2 = ::cppu::getCaughtException();
+             } catch (ucb::CommandFailedException & ) {
+                 excOccurred2 = ::cppu::getCaughtException();
+             } catch (ucb::CommandAbortedException & ) {
+                 excOccurred2 = ::cppu::getCaughtException();
+             } catch (lang::IllegalArgumentException &) {
+                 excOccurred2 = ::cppu::getCaughtException();
+             } catch (uno::RuntimeException &) {
+                 excOccurred2 = ::cppu::getCaughtException();
+             } catch (...) {
+                 excOccurred2 = ::cppu::getCaughtException();
+                 deploy::DeploymentException exc(
+                     OUSTR("Extension Manager: exception during addExtension, url: ")
+                     + url, static_cast<OWeakObject*>(this), excOccurred2);
+                 excOccurred2 <<= exc;
              }
-             //Prevent showing the license if requested.
-             Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
-             ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
-             if (licenseAttributes && licenseAttributes->suppressIfRequired
-                 && props.isSuppressedLicense())
-                 _xCmdEnv = Reference<ucb::XCommandEnvironment>(
-                     new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
-             
-             bCanInstall = xTmpExtension->checkPrerequisites(
-                 xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
-         }
-         catch (deploy::DeploymentException& ) {
-             excOccurred1 = ::cppu::getCaughtException();
-         } catch (ucb::CommandFailedException & ) {
-             excOccurred1 = ::cppu::getCaughtException();
-         } catch (ucb::CommandAbortedException & ) {
-             excOccurred1 = ::cppu::getCaughtException();
-         } catch (lang::IllegalArgumentException &) {
-             excOccurred1 = ::cppu::getCaughtException();
-         } catch (uno::RuntimeException &) {
-             excOccurred1 = ::cppu::getCaughtException();
-         } catch (...) {
-             excOccurred1 = ::cppu::getCaughtException();
-             deploy::DeploymentException exc(
-                 OUSTR("Extension Manager: exception during addExtension, url: ")
-                 + url, static_cast<OWeakObject*>(this), excOccurred1);
-             excOccurred1 <<= exc;
          }
  
-         if (bCanInstall)
+         if (excOccurred2.hasValue())
          {
-             if (xOldExtension.is())
+             //It does not matter what exception is thrown. We try to
+             //recover the original status.
+             //If the user aborted installation then a ucb::CommandAbortedException
+             //is thrown.
+             //Use a private AbortChannel so the user cannot interrupt.
+             try
+             {
+                 if (xExtensionBackup.is())
+                 {
 -                    Reference<deploy::XPackage> xRestored = 
++                    Reference<deploy::XPackage> xRestored =
+                         xPackageManager->importExtension(
 -                            xExtensionBackup, Reference<task::XAbortChannel>(), 
++                            xExtensionBackup, Reference<task::XAbortChannel>(),
+                             Reference<ucb::XCommandEnvironment>());
+                 }
+                 activateExtension(
+                     sIdentifier, sFileName, bUserDisabled, false,
+                     Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
+             }
+             catch (...)
              {
-                 xOldExtension->revokePackage(xAbortChannel, xCmdEnv);
-                 //save the old user extension in case the user aborts
-                 //store the extension in the tmp repository, this will overwrite 
-                 //xTmpPackage (same identifier). Do not let the user abort or 
-                 //interact
-                 Reference<ucb::XCommandEnvironment> tmpCmdEnv(
-                     new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
-                 //importing the old extension in the tmp repository will remove
-                 //the xTmpExtension
-                 xTmpExtension = 0;
-                 xExtensionBackup = m_tmpRepository->importExtension(
-                     xOldExtension, Reference<task::XAbortChannel>(), 
-                     tmpCmdEnv);        
              }
-             xNewExtension = xPackageManager->addPackage(
-                 url, properties, OUString(), xAbortChannel, xCmdEnv);
-             //If we add a user extension and there is already one which was
-             //disabled by a user, then the newly installed one is enabled. If we
-             //add to another repository then the user extension remains
-             //disabled.
-             bool bUserDisabled2 = bUserDisabled;
-             if (repository.equals(OUSTR("user")))
-                 bUserDisabled2 = false;
-             activateExtension(
-                 dp_misc::getIdentifier(xNewExtension),
-                 xNewExtension->getName(), bUserDisabled2, false, xAbortChannel, xCmdEnv);
-             fireModified();
+             ::cppu::throwException(excOccurred2);
          }
-     }
-     catch (deploy::DeploymentException& ) {
-         excOccurred2 = ::cppu::getCaughtException();
+     } // leaving the garded section (getMutex())
+ 
+     try
+     {
+         fireModified();
+ 
+     }catch (deploy::DeploymentException& ) {
+         throw;
      } catch (ucb::CommandFailedException & ) {
-         excOccurred2 = ::cppu::getCaughtException();
+         throw;
      } catch (ucb::CommandAbortedException & ) {
-         excOccurred2 = ::cppu::getCaughtException();
+         throw;
      } catch (lang::IllegalArgumentException &) {
-         excOccurred2 = ::cppu::getCaughtException();
+         throw;
      } catch (uno::RuntimeException &) {
-         excOccurred2 = ::cppu::getCaughtException();
-     } catch (...) {
-         excOccurred2 = ::cppu::getCaughtException();
+         throw;
+     } catch (uno::Exception &) {
+         uno::Any excOccurred = ::cppu::getCaughtException();
          deploy::DeploymentException exc(
-             OUSTR("Extension Manager: exception during addExtension, url: ")
-             + url, static_cast<OWeakObject*>(this), excOccurred2);
-         excOccurred2 <<= exc;
-     }
- 
-     if (excOccurred2.hasValue())
-     {
-         //It does not matter what exception is thrown. We try to
-         //recover the original status.
-         //If the user aborted installation then a ucb::CommandAbortedException
-         //is thrown.
-         //Use a private AbortChannel so the user cannot interrupt.
-         try
-         {
-             Reference<ucb::XCommandEnvironment> tmpCmdEnv(
-                 new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
-             if (xExtensionBackup.is())
-             {
-                 Reference<deploy::XPackage> xRestored = 
-                     xPackageManager->importExtension(
-                         xExtensionBackup, Reference<task::XAbortChannel>(), 
-                         tmpCmdEnv);
-             }
-             activateExtension(
-                 sIdentifier, sFileName, bUserDisabled, false,
-                 Reference<task::XAbortChannel>(), tmpCmdEnv);
-             if (xTmpExtension.is() || xExtensionBackup.is())
-                 m_tmpRepository->removePackage(
-                     sIdentifier, OUString(), xAbortChannel, xCmdEnv);
-             fireModified();
-         }
-         catch (...)
-         {
-         }
-         ::cppu::throwException(excOccurred2);
+             OUSTR("Extension Manager: exception in doChecksForAddExtension"),
+             static_cast<OWeakObject*>(this), excOccurred);
+         throw exc;
+     } catch (...) {
+         throw uno::RuntimeException(
+             OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
+             static_cast<OWeakObject*>(this));
      }
-     if (xTmpExtension.is() || xExtensionBackup.is())
-         m_tmpRepository->removePackage(
-             sIdentifier,OUString(), xAbortChannel, xCmdEnv);
  
-     if (excOccurred1.hasValue())
-         ::cppu::throwException(excOccurred1);
-     
      return xNewExtension;
  }
  
@@@ -713,9 -862,9 +857,9 @@@ void ExtensionManager::removeExtension
              xPackageManager = m_sharedRepository;
          else
              throw lang::IllegalArgumentException(
--                OUSTR("No valid repository name provided."), 
++                OUSTR("No valid repository name provided."),
                  static_cast<cppu::OWeakObject*>(this), 0);
--        
++
          bUserDisabled = isUserDisabled(identifier, fileName);
          //Backup the extension, in case the user cancels the action
          xExtensionBackup = backupExtension(
@@@ -750,7 -899,7 +894,7 @@@
              static_cast<OWeakObject*>(this), excOccurred1);
          excOccurred1 <<= exc;
      }
--    
++
      if (excOccurred1.hasValue())
      {
          //User aborted installation, restore the previous situation.
@@@ -761,15 -910,15 +905,15 @@@
                  new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
              if (xExtensionBackup.is())
              {
--                Reference<deploy::XPackage> xRestored = 
++                Reference<deploy::XPackage> xRestored =
                      xPackageManager->importExtension(
--                        xExtensionBackup, Reference<task::XAbortChannel>(), 
++                        xExtensionBackup, Reference<task::XAbortChannel>(),
                          tmpCmdEnv);
                  activateExtension(
                      identifier, fileName, bUserDisabled, false,
                      Reference<task::XAbortChannel>(),
                      tmpCmdEnv);
--                
++
                  m_tmpRepository->removePackage(
                      dp_misc::getIdentifier(xExtensionBackup),
                      xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
@@@ -781,7 -930,7 +925,7 @@@
          }
          ::cppu::throwException(excOccurred1);
      }
--            
++
      if (xExtensionBackup.is())
          m_tmpRepository->removePackage(
              dp_misc::getIdentifier(xExtensionBackup),
@@@ -809,12 -958,12 +953,12 @@@ void ExtensionManager::enableExtension
          OUString repository = extension->getRepositoryName();
          if (!repository.equals(OUSTR("user")))
              throw lang::IllegalArgumentException(
--                OUSTR("No valid repository name provided."), 
++                OUSTR("No valid repository name provided."),
                  static_cast<cppu::OWeakObject*>(this), 0);
--        
++
          bUserDisabled = isUserDisabled(dp_misc::getIdentifier(extension),
                                         extension->getName());
--        
++
          activateExtension(dp_misc::getIdentifier(extension),
                            extension->getName(), false, false,
                            xAbortChannel, xCmdEnv);
@@@ -880,7 -1029,7 +1024,7 @@@ sal_Int32 ExtensionManager::checkPrereq
          }
          const OUString id(dp_misc::getIdentifier(extension));
          activateExtension(id, extension->getName(),
--                          isUserDisabled(id, extension->getName()), false, 
++                          isUserDisabled(id, extension->getName()), false,
                            xAbortChannel, xCmdEnv);
          return ret;
      }
@@@ -903,7 -1052,7 +1047,6 @@@
      }
  }
  
--
  void ExtensionManager::disableExtension(
      Reference<deploy::XPackage> const & extension,
      Reference<task::XAbortChannel> const & xAbortChannel,
@@@ -924,12 -1073,12 +1067,12 @@@
          const OUString repository( extension->getRepositoryName());
          if (!repository.equals(OUSTR("user")))
              throw lang::IllegalArgumentException(
--                OUSTR("No valid repository name provided."), 
++                OUSTR("No valid repository name provided."),
                  static_cast<cppu::OWeakObject*>(this), 0);
  
          const OUString id(dp_misc::getIdentifier(extension));
          bUserDisabled = isUserDisabled(id, extension->getName());
--        
++
          activateExtension(id, extension->getName(), true, false,
                            xAbortChannel, xCmdEnv);
      }
@@@ -963,7 -1112,7 +1106,7 @@@
          {
          }
          ::cppu::throwException(excOccurred);
--    }    
++    }
  }
  
  uno::Sequence< Reference<deploy::XPackage> >
@@@ -971,9 -1120,9 +1114,9 @@@
      OUString const & repository,
      Reference<task::XAbortChannel> const &xAbort,
      Reference<ucb::XCommandEnvironment> const & xCmdEnv )
--    throw (deploy::DeploymentException, 
++    throw (deploy::DeploymentException,
          ucb::CommandFailedException,
--        ucb::CommandAbortedException, 
++        ucb::CommandAbortedException,
          lang::IllegalArgumentException,
          uno::RuntimeException)
  {
@@@ -985,9 -1134,9 +1128,9 @@@ Reference<deploy::XPackage
      ExtensionManager::getDeployedExtension(
      OUString const & repository,
      OUString const & identifier,
--    OUString const & filename,    
++    OUString const & filename,
      Reference<ucb::XCommandEnvironment> const & xCmdEnv )
--    throw (deploy::DeploymentException, 
++    throw (deploy::DeploymentException,
          ucb::CommandFailedException,
          lang::IllegalArgumentException,
          uno::RuntimeException)
@@@ -1000,9 -1149,9 +1143,9 @@@ uno::Sequence< uno::Sequence<Reference<
      ExtensionManager::getAllExtensions(
      Reference<task::XAbortChannel> const & xAbort,
      Reference<ucb::XCommandEnvironment> const & xCmdEnv )
--    throw (deploy::DeploymentException, 
++    throw (deploy::DeploymentException,
          ucb::CommandFailedException,
--        ucb::CommandAbortedException, 
++        ucb::CommandAbortedException,
          lang::IllegalArgumentException,
          uno::RuntimeException)
  {
@@@ -1026,7 -1175,7 +1169,7 @@@
          id2extensions::const_iterator mapIt = mapExt.begin();
          for (;mapIt != mapExt.end(); mapIt++)
              vecExtensions.push_back(mapIt->second);
--    
++
          //sort the element according to the identifier
          ::std::sort(vecExtensions.begin(), vecExtensions.end(), CompIdentifiers());
  
@@@ -1079,7 -1228,7 +1222,7 @@@ void ExtensionManager::reinstallDeploye
          dp_misc::syncRepositories(xCmdEnv);
          const uno::Sequence< Reference<deploy::XPackage> > extensions(
              xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
--        
++
          for ( sal_Int32 pos = 0; pos < extensions.getLength(); ++pos )
          {
              try
@@@ -1108,7 -1257,7 +1251,7 @@@
          throw deploy::DeploymentException(
              OUSTR("Extension Manager: exception during enableExtension"),
              static_cast<OWeakObject*>(this), exc);
--    }    
++    }
  }
  
  sal_Bool ExtensionManager::synchronize(
@@@ -1123,27 -1272,27 +1266,27 @@@
      try
      {
          sal_Bool bModified = sal_False;
--            
++
          ::osl::MutexGuard guard(getMutex());
          String sSynchronizingShared(StrSyncRepository::get());
          sSynchronizingShared.SearchAndReplaceAllAscii( "%NAME", OUSTR("shared"));
--        dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);    
++        dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);
          bModified = m_sharedRepository->synchronize(xAbortChannel, xCmdEnv);
          progressShared.update(OUSTR("\n\n"));
--        
++
          String sSynchronizingBundled(StrSyncRepository::get());
          sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled"));
--        dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);        
++        dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
          bModified |= m_bundledRepository->synchronize(xAbortChannel, xCmdEnv);
          progressBundled.update(OUSTR("\n\n"));
--        
--        //Always determine the active extension. This is necessary for the 
--        //first-start optimization. The setup creates the registration data for the 
--        //bundled extensions (brand_layer/share/prereg/bundled), which is copied to the user 
--        //installation (user_installation/extension/bundled) when a user starts OOo 
++
++        //Always determine the active extension. This is necessary for the
++        //first-start optimization. The setup creates the registration data for the
++        //bundled extensions (brand_layer/share/prereg/bundled), which is copied to the user
++        //installation (user_installation/extension/bundled) when a user starts OOo
          //for the first time after running setup. All bundled extensions are registered
          //at that moment. However, extensions with the same identifier can be in the
--        //shared or user repository, in which case the respective bundled extensions must 
++        //shared or user repository, in which case the respective bundled extensions must
          //be revoked.
          try
          {
@@@ -1207,7 -1356,7 +1350,7 @@@ void ExtensionManager::checkInstall
          bool approve = false, abort = false;
          if (! dp_misc::interactContinuation(
                  request, task::XInteractionApprove::static_type(),
--                cmdEnv, &approve, &abort )) 
++                cmdEnv, &approve, &abort ))
          {
              OSL_ASSERT( !approve && !abort );
              throw deploy::DeploymentException(
@@@ -1251,7 -1400,7 +1394,7 @@@ void ExtensionManager::checkUpdate
          throw ucb::CommandFailedException(
              dp_misc::getResourceString(
                  RID_STR_PACKAGE_ALREADY_ADDED) + newDisplayName,
--            static_cast<OWeakObject *>(this), request );               
++            static_cast<OWeakObject *>(this), request );
  }
  
  Reference<deploy::XPackage> ExtensionManager::getTempExtension(
@@@ -1264,7 -1413,7 +1407,7 @@@
      Reference<deploy::XPackage> xTmpPackage = m_tmpRepository->addPackage(
          url, uno::Sequence<beans::NamedValue>(),OUString(), xAbortChannel, tmpCmdEnvA);
      if (!xTmpPackage.is())
--    {   
++    {
          throw deploy::DeploymentException(
              OUSTR("Extension Manager: Failed to create temporary XPackage for url: ") + url,
              static_cast<OWeakObject*>(this), uno::Any());
@@@ -1367,5 -1516,4 +1510,4 @@@ void ExtensionManager::fireModified(
  
  } // namespace dp_manager
  
--
 +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --cc desktop/source/deployment/manager/dp_extensionmanager.hxx
index d928ea1,be86f48..c4140e2
--- a/desktop/source/deployment/manager/dp_extensionmanager.hxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@@ -1,7 -1,7 +1,7 @@@
  /*************************************************************************
   *
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-- * 
++ *
   * Copyright 2000, 2010 Oracle and/or its affiliates.
   *
   * OpenOffice.org - a multi-platform office productivity suite
@@@ -25,7 -25,7 +25,6 @@@
   *
   ************************************************************************/
  
--
  #if ! defined INCLUDED_DP_EXTENSIONMANAGER_H
  #define INCLUDED_DP_EXTENSIONMANAGER_H
  
@@@ -41,7 -41,7 +40,6 @@@
  #include "osl/mutex.hxx"
  #include <list>
  
--
  namespace css = ::com::sun::star;
  
  namespace dp_manager {
@@@ -51,10 -51,10 +49,9 @@@ typedef ::std::hash_map
      ::std::vector<css::uno::Reference<css::deployment::XPackage> >,
      ::rtl::OUStringHash > id2extensions;
  
--
  class ExtensionManager : private ::dp_misc::MutexHolder,
          public ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >
--{ 
++{
  public:
      ExtensionManager( css::uno::Reference< css::uno::XComponentContext >const& xContext);
      virtual     ~ExtensionManager();
@@@ -64,7 -64,7 +61,7 @@@
  
      void check();
      void fireModified();
--    
++
  public:
  
  //    XModifyBroadcaster
@@@ -78,12 -78,12 +75,12 @@@
  //XExtensionManager
      virtual css::uno::Sequence<
          css::uno::Reference<css::deployment::XPackageTypeInfo> > SAL_CALL
--        getSupportedPackageTypes() 
++        getSupportedPackageTypes()
              throw (css::uno::RuntimeException);
--    
++
      virtual css::uno::Reference<css::task::XAbortChannel> SAL_CALL
      createAbortChannel() throw (css::uno::RuntimeException);
--    
++
      virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL addExtension(
          ::rtl::OUString const & url,
          css::uno::Sequence<css::beans::NamedValue> const & properties,
@@@ -95,9 -95,9 +92,9 @@@
                 css::ucb::CommandAbortedException,
                 css::lang::IllegalArgumentException,
                 css::uno::RuntimeException);
--    
++
      virtual void SAL_CALL removeExtension(
--        ::rtl::OUString const & identifier, 
++        ::rtl::OUString const & identifier,
          ::rtl::OUString const & filename,
          ::rtl::OUString const & repository,
          css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
@@@ -128,7 -128,7 +125,6 @@@
              css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
  
--
      virtual sal_Int32 SAL_CALL checkPrerequisitesAndEnable(
          css::uno::Reference<css::deployment::XPackage> const & extension,
          css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
@@@ -139,15 -139,15 +135,14 @@@
              css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
  
--
--    virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> > 
++    virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
          SAL_CALL getDeployedExtensions(
          ::rtl::OUString const & repository,
          css::uno::Reference<css::task::XAbortChannel> const &,
          css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
--        throw (css::deployment::DeploymentException, 
++        throw (css::deployment::DeploymentException,
              css::ucb::CommandFailedException,
--            css::ucb::CommandAbortedException, 
++            css::ucb::CommandAbortedException,
              css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
  
@@@ -158,7 -158,7 +153,7 @@@
          ::rtl::OUString const & filename,
          css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv )
          throw (
--            css::deployment::DeploymentException, 
++            css::deployment::DeploymentException,
              css::ucb::CommandFailedException,
              css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
@@@ -169,31 -169,31 +164,30 @@@
          ::rtl::OUString const & filename,
          css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv )
          throw (
--            css::deployment::DeploymentException, 
++            css::deployment::DeploymentException,
              css::ucb::CommandFailedException,
              css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
--    
++
      virtual css::uno::Sequence< css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > >
          SAL_CALL getAllExtensions(
          css::uno::Reference<css::task::XAbortChannel> const &,
          css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
--        throw (css::deployment::DeploymentException, 
++        throw (css::deployment::DeploymentException,
              css::ucb::CommandFailedException,
--            css::ucb::CommandAbortedException, 
++            css::ucb::CommandAbortedException,
              css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
  
--    
      virtual void SAL_CALL reinstallDeployedExtensions(
          ::rtl::OUString const & repository,
          css::uno::Reference< css::task::XAbortChannel> const & xAbortChannel,
          css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv )
          throw (
              css::deployment::DeploymentException,
--            css::ucb::CommandFailedException, 
++            css::ucb::CommandFailedException,
              css::ucb::CommandAbortedException,
--            css::lang::IllegalArgumentException, 
++            css::lang::IllegalArgumentException,
              css::uno::RuntimeException);
  
      virtual sal_Bool SAL_CALL synchronize(
@@@ -211,15 -211,15 +205,15 @@@
          css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
          throw (css::deployment::DeploymentException,
                 css::uno::RuntimeException);
--    
++
      virtual sal_Bool SAL_CALL isReadOnlyRepository(::rtl::OUString const & repository)
          throw (css::uno::RuntimeException);
--    
++
  private:
  
      struct StrSyncRepository : public ::dp_misc::StaticResourceString<
          StrSyncRepository, RID_STR_SYNCHRONIZING_REPOSITORY> {};
--    
++
      struct ExtensionInfos
      {
          ::rtl::OUString identifier;
@@@ -231,7 -231,7 +225,7 @@@
      css::uno::Reference< css::uno::XComponentContext> m_xContext;
  
      css::uno::Reference<css::deployment::XPackageManager> m_userRepository;
--    css::uno::Reference<css::deployment::XPackageManager> m_sharedRepository; 
++    css::uno::Reference<css::deployment::XPackageManager> m_sharedRepository;
      css::uno::Reference<css::deployment::XPackageManager> m_bundledRepository;
      css::uno::Reference<css::deployment::XPackageManager> m_tmpRepository;
  
@@@ -250,7 -252,7 +246,7 @@@
      void activateExtension(
          ::rtl::OUString const & identifier,
          ::rtl::OUString const & fileName,
--        bool bUserDisabled, bool bStartup, 
++        bool bUserDisabled, bool bStartup,
          css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
          css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
  
@@@ -260,8 -262,8 +256,7 @@@
          css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
          css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
  
--
--    ::std::list<css::uno::Reference<css::deployment::XPackage> > 
++    ::std::list<css::uno::Reference<css::deployment::XPackage> >
      getExtensionsWithSameId(::rtl::OUString  const & identifier,
                              ::rtl::OUString const & fileName,
                              css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv =
@@@ -287,7 -289,7 +282,6 @@@
          css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
          css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
  
--    
      void addExtensionsToMap(
          id2extensions & mapExt,
          css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt,
@@@ -296,12 -298,27 +290,22 @@@
      css::uno::Reference<css::deployment::XPackageManager>
      getPackageManager(::rtl::OUString const & repository)
          throw (css::lang::IllegalArgumentException);
- };
- 
- }
  
+     bool doChecksForAddExtension(
+         css::uno::Reference<css::deployment::XPackageManager> const & xPackageMgr,
+         css::uno::Sequence<css::beans::NamedValue> const & properties,
+         css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
+         css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+         css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+         css::uno::Reference<css::deployment::XPackage> & out_existingExtension )
 -        throw (css::deployment::DeploymentException, 
++        throw (css::deployment::DeploymentException,
+                css::ucb::CommandFailedException,
 -               css::ucb::CommandAbortedException, 
++               css::ucb::CommandAbortedException,
+                css::lang::IllegalArgumentException,
+                css::uno::RuntimeException);
 -        
 -        
 +
+ };
  
+ }
  
 -
 -
 -
  #endif
--
commit 84d50758d4b9ebf25216259eb780757639f708ac
Merge: f38a8cf... dc31e3b...
Author: Kurt Zenker <kz at openoffice.org>
Date:   Wed Oct 20 16:59:30 2010 +0200

    CWS-TOOLING: integrate CWS ooo33gsl11

commit f38a8cf165f8eaca6b7959a34b2465e3b82be498
Merge: 570ff21... e97774c...
Author: Kurt Zenker <kz at openoffice.org>
Date:   Wed Oct 20 16:46:26 2010 +0200

    CWS-TOOLING: integrate CWS sb134

commit e97774c142014a662053d4649e760d791bfc10c1
Author: sb <sb at openoffice.org>
Date:   Tue Oct 19 09:47:40 2010 +0200

    sb134: #i114705# call FlushConfiguration only after all modifications have been made

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index a5f6b9e..663cca1 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -785,7 +785,6 @@ BOOL Desktop::QueryExit()
     {
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
-        FlushConfiguration();
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
     }
     catch ( RuntimeException& )
@@ -817,6 +816,7 @@ BOOL Desktop::QueryExit()
     }
     else
     {
+        FlushConfiguration();
         try
         {
             // it is no problem to call DisableOfficeIPCThread() more than once
commit dc31e3b09838409c57f5ff9181cf4d6950575c81
Author: Philipp Lohmann [pl] <Philipp.Lohmann at Oracle.COM>
Date:   Mon Oct 18 17:00:27 2010 +0200

    ooo33gsl11: #i115088# add a nodoc string, workaround botched define in classes/resource.hrc

diff --git a/framework/inc/framework.hrc b/framework/inc/framework.hrc
index b1abc91..86ad3f7 100644
--- a/framework/inc/framework.hrc
+++ b/framework/inc/framework.hrc
@@ -35,9 +35,9 @@
 #define RID_GROUPS_OFFSET           32000
 #define RID_GROUPS_END              32767
 
-#define RID_FWK_DIALOG_START        (RID_FWK_START + 2048)
+#define RID_FWK_DIALOG_START_CORRECT        (RID_FWK_START + 2048)
 
-#define	DLG_FILTER_SELECT			(RID_FWK_DIALOG_START + 0)
+#define	DLG_FILTER_SELECT			(RID_FWK_DIALOG_START_CORRECT + 0)
 
 #define	STR_FILTER_DOWNLOAD			(RID_FWK_START+0)
 #define STR_FILTER_CHOOSER			(RID_FWK_START+1)
@@ -45,7 +45,7 @@
 #define STR_FILTER_ZIPPED			(RID_FWK_START+3)
 
 // ResIds for BackingWindow
-#define DLG_BACKING                         (RID_FWK_DIALOG_START+100)
+#define DLG_BACKING                         (RID_FWK_DIALOG_START_CORRECT+100)
 #define STR_BACKING_WELCOME                 1
 #define STR_BACKING_WELCOMEPRODUCT          2
 #define STR_BACKING_CREATE                  3
@@ -78,7 +78,7 @@
 #define BMP_BACKING_OPENTEMPLATE            17
 
 // Ids of TabWindow
-#define WIN_TABWINDOW                       (RID_FWK_DIALOG_START+101)
+#define WIN_TABWINDOW                       (RID_FWK_DIALOG_START_CORRECT+101)
 #define TC_TABCONTROL                        1
 
 #endif
diff --git a/framework/source/services/backingwindow.cxx b/framework/source/services/backingwindow.cxx
index 8817e60..b80c7f3 100644
--- a/framework/source/services/backingwindow.cxx
+++ b/framework/source/services/backingwindow.cxx
@@ -29,6 +29,7 @@
 #include "precompiled_framework.hxx"
 
 #include "backingwindow.hxx"
+#include "classes/resource.hrc"
 #include "framework.hrc"
 #include "classes/fwkresid.hxx"
 #include <services.h>
@@ -388,8 +389,13 @@ void BackingWindow::prepareRecentFileMenu()
             aBuf.append( aMenuTitle );
             mpRecentMenu->InsertItem( static_cast<USHORT>(i+1), aBuf.makeStringAndClear() );
         }
-        maOpenButton.SetPopupMenu( mpRecentMenu );
     }
+    else
+    {
+        String aNoDoc( FwkResId( STR_NODOCUMENT ) );
+        mpRecentMenu->InsertItem( 0xffff, aNoDoc );
+    }
+    maOpenButton.SetPopupMenu( mpRecentMenu );
 }
 
 void BackingWindow::initBackground()
commit 570ff2183f97714f28dc2187279e41e656903bdc
Merge: 0e810a7... 6e45443...
Author: Jens-Heiner Rechtien <hr at openoffice.org>
Date:   Thu Oct 14 15:50:39 2010 +0200

    CWS-TOOLING: integrate CWS jl161

commit 0e810a79aaaa25996ed4e8a658a1c04b8060bbd2
Merge: c84cd16... d2ddf1c...
Author: Jens-Heiner Rechtien <hr at openoffice.org>
Date:   Thu Oct 14 15:47:51 2010 +0200

    CWS-TOOLING: integrate CWS sb133

commit 6e45443837ee59c970dfc903cfa8239669e89439
Author: Joachim Lingner <jl at openoffice.org>
Date:   Fri Oct 8 08:44:14 2010 +0200

    jl161 #i114933# solve deadlock problem when adding an extension

diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx
index 71eaa2a..c809685 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.cxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@ -531,7 +531,11 @@ ExtensionManager::getSupportedPackageTypes()
 {
     return m_userRepository->getSupportedPackageTypes();
 }
-
+//Do some necessary checks and user interaction. This function does not
+//aquire the extension manager mutex and that mutex must not be aquired
+//when this function is called. doChecksForAddExtension does  synchronous
+//user interactions which may require aquiring the solar mutex.
+//Returns true if the extension can be installed.
 bool ExtensionManager::doChecksForAddExtension(
     Reference<deploy::XPackageManager> const & xPackageMgr,
     uno::Sequence<beans::NamedValue> const & properties,
@@ -708,6 +712,9 @@ Reference<deploy::XPackage> ExtensionManager::addExtension(
                             xOldExtension, Reference<task::XAbortChannel>(), 
                             Reference<ucb::XCommandEnvironment>());
                         tmpExtensionRemoveGuard.reset(xExtensionBackup);
+                        //xTmpExtension will later be used to check the dependencies
+                        //again. However, only xExtensionBackup will be later removed
+                        //from the tmp repository
                         xTmpExtension = xExtensionBackup;
                         OSL_ASSERT(xTmpExtension.is());
                     }
@@ -783,18 +790,16 @@ Reference<deploy::XPackage> ExtensionManager::addExtension(
             //Use a private AbortChannel so the user cannot interrupt.
             try
             {
-                Reference<ucb::XCommandEnvironment> tmpCmdEnv(
-                    new TmpRepositoryCommandEnv());
                 if (xExtensionBackup.is())
                 {
                     Reference<deploy::XPackage> xRestored = 
                         xPackageManager->importExtension(
                             xExtensionBackup, Reference<task::XAbortChannel>(), 
-                            tmpCmdEnv);
+                            Reference<ucb::XCommandEnvironment>());
                 }
                 activateExtension(
                     sIdentifier, sFileName, bUserDisabled, false,
-                    Reference<task::XAbortChannel>(), tmpCmdEnv);
+                    Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
             }
             catch (...)
             {
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx
index ff85185..be86f48 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.hxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@ -299,9 +299,6 @@ private:
     getPackageManager(::rtl::OUString const & repository)
         throw (css::lang::IllegalArgumentException);
 
-    //Do some necessary checks and user interaction. This function does not
-    //aquire the extension manager mutex.
-    //Returns true if the extension can be installed.
     bool doChecksForAddExtension(
         css::uno::Reference<css::deployment::XPackageManager> const & xPackageMgr,
         css::uno::Sequence<css::beans::NamedValue> const & properties,
commit 457fe87eda6cbea16520e1efc0ec5a05f2ae3e0c
Author: Joachim Lingner <jl at openoffice.org>
Date:   Thu Oct 7 17:20:55 2010 +0200

    jl161 #i114933# solve deadlock problem when adding an extension

diff --git a/desktop/source/deployment/manager/dp_commandenvironments.cxx b/desktop/source/deployment/manager/dp_commandenvironments.cxx
index 789cac1..f6995b9 100644
--- a/desktop/source/deployment/manager/dp_commandenvironments.cxx
+++ b/desktop/source/deployment/manager/dp_commandenvironments.cxx
@@ -31,6 +31,8 @@
 #include "com/sun/star/deployment/VersionException.hpp"
 #include "com/sun/star/deployment/LicenseException.hpp"
 #include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
 #include "com/sun/star/task/XInteractionApprove.hpp"
 #include "com/sun/star/task/XInteractionAbort.hpp"
 #include "com/sun/star/task/XInteractionHandler.hpp"
@@ -250,7 +252,43 @@ void NoLicenseCommandEnv::handle(
     handle_(approve, abort, xRequest);
 }
 
+// SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv(
+//     css::uno::Reference< css::task::XInteractionHandler> const & handler):
+//     BaseCommandEnv(handler)
+// {
+// }
+SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv()
+{
+}
 
+void SilentCheckPrerequisitesCommandEnv::handle(
+       Reference< task::XInteractionRequest> const & xRequest )
+    throw (uno::RuntimeException)
+{
+    uno::Any request( xRequest->getRequest() );
+    OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+    
+    deployment::LicenseException licExc;
+    deployment::PlatformException platformExc;
+    deployment::DependencyException depExc;
+    bool approve = false;
+    bool abort = false;
+
+    if (request >>= licExc)
+    {
+        approve = true;
+        handle_(approve, abort, xRequest);
+    }
+    else if ((request >>= platformExc)
+             || (request >>= depExc))
+    {
+        m_Exception = request;
+    }
+    else
+    {
+        m_UnknownException = request;
+    }
+}
 // NoExceptionCommandEnv::NoExceptionCommandEnv(
 //     css::uno::Reference< css::task::XInteractionHandler> const & handler,
 //     css::uno::Type const & type):
diff --git a/desktop/source/deployment/manager/dp_commandenvironments.hxx b/desktop/source/deployment/manager/dp_commandenvironments.hxx
index 702b1b3..6662d1f 100644
--- a/desktop/source/deployment/manager/dp_commandenvironments.hxx
+++ b/desktop/source/deployment/manager/dp_commandenvironments.hxx
@@ -135,6 +135,29 @@ public:
     
 };
 
+/* For use in XExtensionManager::addExtension in the call to
+   XPackage::checkPrerequisites
+   It prevents all user interactions. The license is always accepted.
+   It remembers if there was a platform or a dependency exception in
+   the member m_bException. if there was any other exception then m_bUnknownException
+   is set.
+   
+ */
+class SilentCheckPrerequisitesCommandEnv : public BaseCommandEnv
+{
+public:
+    SilentCheckPrerequisitesCommandEnv();
+    // XInteractionHandler
+    virtual void SAL_CALL handle(
+        css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+        throw (css::uno::RuntimeException);
+
+    // Set to true if a PlatformException or a DependencyException were handled.
+    css::uno::Any m_Exception;
+    // Set to true if an unknown exception was handled.
+    css::uno::Any m_UnknownException;    
+};
+
 // class NoExceptionCommandEnv : public BaseCommandEnv
 // {
 //     css::uno::Type m_type;
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx
index ab0baa7..71eaa2a 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.cxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@ -139,6 +139,37 @@ void writeLastModified(OUString & url, Reference<ucb::XCommandEnvironment> const
             OUSTR("Failed to update") + url, 0, exc);
     }
 }
+
+class ExtensionRemoveGuard
+{
+    css::uno::Reference<css::deployment::XPackage> m_extension;
+    css::uno::Reference<css::deployment::XPackageManager> m_xPackageManager;
+
+public:
+    ExtensionRemoveGuard(
+        css::uno::Reference<css::deployment::XPackage> const & extension,
+        css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager):
+        m_extension(extension), m_xPackageManager(xPackageManager) {}
+    ~ExtensionRemoveGuard();
+
+    void reset(css::uno::Reference<css::deployment::XPackage> const & extension) {
+        m_extension = extension;
+    }
+};
+
+ExtensionRemoveGuard::~ExtensionRemoveGuard()
+{
+    try {
+        if (m_xPackageManager.is() && m_extension.is())
+            m_xPackageManager->removePackage(
+                dp_misc::getIdentifier(m_extension), ::rtl::OUString(),
+                css::uno::Reference<css::task::XAbortChannel>(),
+                css::uno::Reference<css::ucb::XCommandEnvironment>());
+    } catch (...) {
+        OSL_ASSERT(0);
+    }
+}
+
 } //end namespace
 
 namespace dp_manager {
@@ -501,6 +532,103 @@ ExtensionManager::getSupportedPackageTypes()
     return m_userRepository->getSupportedPackageTypes();
 }
 
+bool ExtensionManager::doChecksForAddExtension(
+    Reference<deploy::XPackageManager> const & xPackageMgr,
+    uno::Sequence<beans::NamedValue> const & properties,
+    css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
+    Reference<task::XAbortChannel> const & xAbortChannel,
+    Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+    Reference<deploy::XPackage> & out_existingExtension )
+    throw (deploy::DeploymentException, 
+           ucb::CommandFailedException,
+           ucb::CommandAbortedException, 
+           lang::IllegalArgumentException,
+           uno::RuntimeException)
+{
+    try
+    {
+        Reference<deploy::XPackage> xOldExtension;
+        const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
+        const OUString sFileName = xTmpExtension->getName();
+        const OUString sDisplayName = xTmpExtension->getDisplayName();
+        const OUString sVersion = xTmpExtension->getVersion();
+        
+        try
+        {
+            xOldExtension = xPackageMgr->getDeployedPackage(
+                sIdentifier, sFileName, xCmdEnv);
+            out_existingExtension = xOldExtension;
+        }
+        catch (lang::IllegalArgumentException &)
+        {
+        }
+        bool bCanInstall = false;
+
+        //This part is not guarded against other threads removing, adding, disabling ...
+        //etc. the same extension. 
+        //checkInstall is safe because it notifies the user if the extension is not yet
+        //installed in the same repository. Because addExtension has its own guard
+        //(m_addMutex), another thread cannot add the extension in the meantime.
+        //checkUpdate is called if the same extension exists in the same
+        //repository. The user is asked if they want to replace it.  Another
+        //thread
+        //could already remove the extension. So asking the user was not
+        //necessary. No harm is done. The other thread may also ask the user
+        //if he wants to remove the extension. This depends on the
+        //XCommandEnvironment which it passes to removeExtension.
+        if (xOldExtension.is())
+        {
+            //throws a CommandFailedException if the user cancels
+            //the action.
+            checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
+        }
+        else
+        {
+            //throws a CommandFailedException if the user cancels
+            //the action.
+            checkInstall(sDisplayName, xCmdEnv);
+        }
+        //Prevent showing the license if requested.
+        Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
+        ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
+
+        dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
+        const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
+            info.getSimpleLicenseAttributes();
+
+        if (licenseAttributes && licenseAttributes->suppressIfRequired
+            && props.isSuppressedLicense())
+            _xCmdEnv = Reference<ucb::XCommandEnvironment>(
+                new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
+            
+        bCanInstall = xTmpExtension->checkPrerequisites(
+            xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
+
+        return bCanInstall;
+    }
+    catch (deploy::DeploymentException& ) {
+        throw;
+    } catch (ucb::CommandFailedException & ) {
+        throw;
+    } catch (ucb::CommandAbortedException & ) {
+        throw;
+    } catch (lang::IllegalArgumentException &) {
+        throw;
+    } catch (uno::RuntimeException &) {
+        throw;
+    } catch (uno::Exception &) {
+        uno::Any excOccurred = ::cppu::getCaughtException();
+        deploy::DeploymentException exc(
+            OUSTR("Extension Manager: exception in doChecksForAddExtension"),
+            static_cast<OWeakObject*>(this), excOccurred);
+        throw exc;
+    } catch (...) {
+        throw uno::RuntimeException(
+            OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
+            static_cast<OWeakObject*>(this));
+    }
+}
+
 // Only add to shared and user repository
 Reference<deploy::XPackage> ExtensionManager::addExtension(
     OUString const & url, uno::Sequence<beans::NamedValue> const & properties,
@@ -524,166 +652,183 @@ Reference<deploy::XPackage> ExtensionManager::addExtension(
         throw lang::IllegalArgumentException(
             OUSTR("No valid repository name provided."), 
             static_cast<cppu::OWeakObject*>(this), 0);
-    ::osl::MutexGuard guard(getMutex());
+    //We must make sure that the xTmpExtension is not create twice, because this
+    //would remove the first one.
+    ::osl::MutexGuard addGuard(m_addMutex);
+    
     Reference<deploy::XPackage> xTmpExtension =
         getTempExtension(url, xAbortChannel, xCmdEnv);
+    //Make sure the extension is removed from the tmp repository in case
+    //of an exception
+    ExtensionRemoveGuard tmpExtensionRemoveGuard(xTmpExtension, m_tmpRepository);
     const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
     const OUString sFileName = xTmpExtension->getName();
-    const OUString sDisplayName = xTmpExtension->getDisplayName();
-    const OUString sVersion = xTmpExtension->getVersion();
-    dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
-    const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
-        info.getSimpleLicenseAttributes();
     Reference<deploy::XPackage> xOldExtension;
     Reference<deploy::XPackage> xExtensionBackup;
 
-    uno::Any excOccurred1;
     uno::Any excOccurred2;
     bool bUserDisabled = false;
-    try 
+    bool bCanInstall = doChecksForAddExtension(
+        xPackageManager,
+        properties,
+        xTmpExtension,
+        xAbortChannel,
+        xCmdEnv,
+        xOldExtension );
+
     {
-        bUserDisabled = isUserDisabled(sIdentifier, sFileName);
-        try
-        {
-            xOldExtension = xPackageManager->getDeployedPackage(
-                sIdentifier, sFileName, xCmdEnv);
-        }
-        catch (lang::IllegalArgumentException &)
-        {
-        }
-        bool bCanInstall = false;
-        try
+        // In this garded section (getMutex) we must not use the argument xCmdEnv
+        // because it may bring up dialogs (XInteractionHandler::handle) this
+        //may potententially deadlock. See issue
+        //http://qa.openoffice.org/issues/show_bug.cgi?id=114933
+        //By not providing xCmdEnv the underlying APIs will throw an exception if
+        //the XInteractionRequest cannot be handled
+        ::osl::MutexGuard guard(getMutex());
+ 
+        if (bCanInstall)
         {
-            if (xOldExtension.is())
+            try
             {
-                //throws a CommandFailedException if the user cancels
-                //the action.
-                checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
+                bUserDisabled = isUserDisabled(sIdentifier, sFileName);
+                if (xOldExtension.is())
+                {
+                    try
+                    {
+                        xOldExtension->revokePackage(
+                            xAbortChannel, Reference<ucb::XCommandEnvironment>());
+                        //save the old user extension in case the user aborts
+                        //store the extension in the tmp repository, this will overwrite 
+                        //xTmpPackage (same identifier). Do not let the user abort or 
+                        //interact
+                        //importing the old extension in the tmp repository will remove
+                        //the xTmpExtension
+                        //no command environment supplied, only this class shall interact
+                        //with the user!
+                        xExtensionBackup = m_tmpRepository->importExtension(
+                            xOldExtension, Reference<task::XAbortChannel>(), 
+                            Reference<ucb::XCommandEnvironment>());
+                        tmpExtensionRemoveGuard.reset(xExtensionBackup);
+                        xTmpExtension = xExtensionBackup;
+                        OSL_ASSERT(xTmpExtension.is());
+                    }
+                    catch (lang::DisposedException &)
+                    {
+                        //Another thread might have removed the extension meanwhile
+                    }
+                }
+                //check again dependencies but prevent user interaction,
+                //We can disregard the license, because the user must have already
+                //accepted it, whe we called checkPrerequisites the first time
+                SilentCheckPrerequisitesCommandEnv * pSilentCommandEnv =
+                    new SilentCheckPrerequisitesCommandEnv();
+                Reference<ucb::XCommandEnvironment> silentCommandEnv(pSilentCommandEnv);
+                
+                sal_Int32 failedPrereq = xTmpExtension->checkPrerequisites(
+                    xAbortChannel, silentCommandEnv, true);
+                if (failedPrereq == 0)
+                {
+                    xNewExtension = xPackageManager->addPackage(
+                        url, properties, OUString(), xAbortChannel,
+                        Reference<ucb::XCommandEnvironment>());
+                    //If we add a user extension and there is already one which was
+                    //disabled by a user, then the newly installed one is enabled. If we
+                    //add to another repository then the user extension remains
+                    //disabled.
+                    bool bUserDisabled2 = bUserDisabled;
+                    if (repository.equals(OUSTR("user")))
+                        bUserDisabled2 = false;
+                
+                    activateExtension(
+                        dp_misc::getIdentifier(xNewExtension),
+                        xNewExtension->getName(), bUserDisabled2, false, xAbortChannel,
+                        Reference<ucb::XCommandEnvironment>());
+                }
+                else
+                {
+                    if (pSilentCommandEnv->m_Exception.hasValue())
+                        ::cppu::throwException(pSilentCommandEnv->m_Exception);
+                    else if ( pSilentCommandEnv->m_UnknownException.hasValue())
+                        ::cppu::throwException(pSilentCommandEnv->m_UnknownException);
+                    else
+                        throw deploy::DeploymentException (
+                            OUSTR("Extension Manager: exception during addExtension, ckeckPrerequisites failed"),
+                            static_cast<OWeakObject*>(this), uno::Any());
+                }        
             }
-            else
-            {
-                //throws a CommandFailedException if the user cancels
-                //the action.
-                checkInstall(sDisplayName, xCmdEnv);
+            catch (deploy::DeploymentException& ) {
+                excOccurred2 = ::cppu::getCaughtException();
+            } catch (ucb::CommandFailedException & ) {
+                excOccurred2 = ::cppu::getCaughtException();
+            } catch (ucb::CommandAbortedException & ) {
+                excOccurred2 = ::cppu::getCaughtException();
+            } catch (lang::IllegalArgumentException &) {
+                excOccurred2 = ::cppu::getCaughtException();
+            } catch (uno::RuntimeException &) {
+                excOccurred2 = ::cppu::getCaughtException();
+            } catch (...) {
+                excOccurred2 = ::cppu::getCaughtException();
+                deploy::DeploymentException exc(
+                    OUSTR("Extension Manager: exception during addExtension, url: ")
+                    + url, static_cast<OWeakObject*>(this), excOccurred2);
+                excOccurred2 <<= exc;
             }
-            //Prevent showing the license if requested.
-            Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
-            ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
-            if (licenseAttributes && licenseAttributes->suppressIfRequired
-                && props.isSuppressedLicense())
-                _xCmdEnv = Reference<ucb::XCommandEnvironment>(
-                    new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
-            
-            bCanInstall = xTmpExtension->checkPrerequisites(
-                xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
-        }
-        catch (deploy::DeploymentException& ) {
-            excOccurred1 = ::cppu::getCaughtException();
-        } catch (ucb::CommandFailedException & ) {
-            excOccurred1 = ::cppu::getCaughtException();
-        } catch (ucb::CommandAbortedException & ) {
-            excOccurred1 = ::cppu::getCaughtException();
-        } catch (lang::IllegalArgumentException &) {
-            excOccurred1 = ::cppu::getCaughtException();
-        } catch (uno::RuntimeException &) {
-            excOccurred1 = ::cppu::getCaughtException();
-        } catch (...) {
-            excOccurred1 = ::cppu::getCaughtException();
-            deploy::DeploymentException exc(
-                OUSTR("Extension Manager: exception during addExtension, url: ")
-                + url, static_cast<OWeakObject*>(this), excOccurred1);
-            excOccurred1 <<= exc;
         }
 
-        if (bCanInstall)
+        if (excOccurred2.hasValue())
         {
-            if (xOldExtension.is())
+            //It does not matter what exception is thrown. We try to
+            //recover the original status.
+            //If the user aborted installation then a ucb::CommandAbortedException
+            //is thrown.
+            //Use a private AbortChannel so the user cannot interrupt.
+            try
             {
-                xOldExtension->revokePackage(xAbortChannel, xCmdEnv);
-                //save the old user extension in case the user aborts
-                //store the extension in the tmp repository, this will overwrite 
-                //xTmpPackage (same identifier). Do not let the user abort or 
-                //interact
                 Reference<ucb::XCommandEnvironment> tmpCmdEnv(
-                    new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
-                //importing the old extension in the tmp repository will remove
-                //the xTmpExtension
-                xTmpExtension = 0;
-                xExtensionBackup = m_tmpRepository->importExtension(
-                    xOldExtension, Reference<task::XAbortChannel>(), 
-                    tmpCmdEnv);        
+                    new TmpRepositoryCommandEnv());
+                if (xExtensionBackup.is())
+                {
+                    Reference<deploy::XPackage> xRestored = 
+                        xPackageManager->importExtension(
+                            xExtensionBackup, Reference<task::XAbortChannel>(), 
+                            tmpCmdEnv);
+                }
+                activateExtension(
+                    sIdentifier, sFileName, bUserDisabled, false,
+                    Reference<task::XAbortChannel>(), tmpCmdEnv);
+            }
+            catch (...)
+            {
             }
-            xNewExtension = xPackageManager->addPackage(
-                url, properties, OUString(), xAbortChannel, xCmdEnv);
-            //If we add a user extension and there is already one which was
-            //disabled by a user, then the newly installed one is enabled. If we
-            //add to another repository then the user extension remains
-            //disabled.
-            bool bUserDisabled2 = bUserDisabled;
-            if (repository.equals(OUSTR("user")))
-                bUserDisabled2 = false;
-            activateExtension(
-                dp_misc::getIdentifier(xNewExtension),
-                xNewExtension->getName(), bUserDisabled2, false, xAbortChannel, xCmdEnv);
-            fireModified();
+            ::cppu::throwException(excOccurred2);
         }
-    }
-    catch (deploy::DeploymentException& ) {
-        excOccurred2 = ::cppu::getCaughtException();
+    } // leaving the garded section (getMutex())
+
+    try
+    {
+        fireModified();
+
+    }catch (deploy::DeploymentException& ) {
+        throw;
     } catch (ucb::CommandFailedException & ) {
-        excOccurred2 = ::cppu::getCaughtException();
+        throw;
     } catch (ucb::CommandAbortedException & ) {
-        excOccurred2 = ::cppu::getCaughtException();
+        throw;
     } catch (lang::IllegalArgumentException &) {
-        excOccurred2 = ::cppu::getCaughtException();
+        throw;
     } catch (uno::RuntimeException &) {
-        excOccurred2 = ::cppu::getCaughtException();
-    } catch (...) {
-        excOccurred2 = ::cppu::getCaughtException();
+        throw;
+    } catch (uno::Exception &) {
+        uno::Any excOccurred = ::cppu::getCaughtException();
         deploy::DeploymentException exc(
-            OUSTR("Extension Manager: exception during addExtension, url: ")
-            + url, static_cast<OWeakObject*>(this), excOccurred2);
-        excOccurred2 <<= exc;
-    }
-
-    if (excOccurred2.hasValue())
-    {
-        //It does not matter what exception is thrown. We try to
-        //recover the original status.
-        //If the user aborted installation then a ucb::CommandAbortedException
-        //is thrown.
-        //Use a private AbortChannel so the user cannot interrupt.
-        try
-        {
-            Reference<ucb::XCommandEnvironment> tmpCmdEnv(
-                new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
-            if (xExtensionBackup.is())
-            {
-                Reference<deploy::XPackage> xRestored = 
-                    xPackageManager->importExtension(
-                        xExtensionBackup, Reference<task::XAbortChannel>(), 
-                        tmpCmdEnv);
-            }
-            activateExtension(
-                sIdentifier, sFileName, bUserDisabled, false,
-                Reference<task::XAbortChannel>(), tmpCmdEnv);
-            if (xTmpExtension.is() || xExtensionBackup.is())
-                m_tmpRepository->removePackage(
-                    sIdentifier, OUString(), xAbortChannel, xCmdEnv);
-            fireModified();
-        }
-        catch (...)
-        {
-        }
-        ::cppu::throwException(excOccurred2);
+            OUSTR("Extension Manager: exception in doChecksForAddExtension"),
+            static_cast<OWeakObject*>(this), excOccurred);
+        throw exc;
+    } catch (...) {
+        throw uno::RuntimeException(
+            OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
+            static_cast<OWeakObject*>(this));
     }
-    if (xTmpExtension.is() || xExtensionBackup.is())
-        m_tmpRepository->removePackage(
-            sIdentifier,OUString(), xAbortChannel, xCmdEnv);
 
-    if (excOccurred1.hasValue())
-        ::cppu::throwException(excOccurred1);
-    
     return xNewExtension;
 }
 
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx
index d928ea1..ff85185 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.hxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@ -235,6 +235,8 @@ private:
     css::uno::Reference<css::deployment::XPackageManager> m_bundledRepository;
     css::uno::Reference<css::deployment::XPackageManager> m_tmpRepository;
 
+    //only to be used within addExtension
+    ::osl::Mutex m_addMutex;
     /* contains the names of all repositories (except tmp) in order of there
        priority. That is, the first element is "user" follod by "shared" and
        then "bundled"
@@ -296,6 +298,24 @@ private:
     css::uno::Reference<css::deployment::XPackageManager>
     getPackageManager(::rtl::OUString const & repository)
         throw (css::lang::IllegalArgumentException);
+
+    //Do some necessary checks and user interaction. This function does not
+    //aquire the extension manager mutex.
+    //Returns true if the extension can be installed.
+    bool doChecksForAddExtension(
+        css::uno::Reference<css::deployment::XPackageManager> const & xPackageMgr,
+        css::uno::Sequence<css::beans::NamedValue> const & properties,
+        css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
+        css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+        css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+        css::uno::Reference<css::deployment::XPackage> & out_existingExtension )
+        throw (css::deployment::DeploymentException, 
+               css::ucb::CommandFailedException,
+               css::ucb::CommandAbortedException, 
+               css::lang::IllegalArgumentException,
+               css::uno::RuntimeException);
+        
+        
 };
 
 }
commit d2ddf1ca02ef283075e6609407a93f2a27d7662f
Author: sb <sb at openoffice.org>
Date:   Wed Oct 6 09:24:31 2010 +0200

    sb133: #i114705# flush configmgr on every soffice exit path

diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index 510b16d..5c3d3a3 100644
--- a/desktop/inc/app.hxx
+++ b/desktop/inc/app.hxx
@@ -155,6 +155,7 @@ class Desktop : public Application
 
         sal_Bool				InitializeInstallation( const rtl::OUString& rAppFilename );
         sal_Bool				InitializeConfiguration();
+        void                    FlushConfiguration();
         sal_Bool				InitializeQuickstartMode( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr );
 
         void					HandleBootstrapPathErrors( ::utl::Bootstrap::Status, const ::rtl::OUString& aMsg );
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 045970e..a5f6b9e 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -754,6 +754,7 @@ void Desktop::DeInit()
         // instead of removing of the configManager just let it commit all the changes
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+        FlushConfiguration();
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
 
         // close splashscreen if it's still open
@@ -784,6 +785,7 @@ BOOL Desktop::QueryExit()
     {
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+        FlushConfiguration();
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
     }
     catch ( RuntimeException& )
@@ -1436,18 +1438,7 @@ USHORT Desktop::Exception(USHORT nError)
     if ( bAllowRecoveryAndSessionManagement )
         bRestart = SaveTasks();
 
-    // because there is no method to flush the condiguration data, we must dispose the ConfigManager
-    Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
-    if (xCFGFlush.is())
-    {
-        xCFGFlush->flush();
-    }
-    else
-    {
-        Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
-        if (xCFGDispose.is())
-            xCFGDispose->dispose();
-    }
+    FlushConfiguration();
 
     switch( nError & EXC_MAJORTYPE )
     {
@@ -1976,6 +1967,7 @@ void Desktop::Main()
 
     // remove temp directory
     RemoveTemporaryDirectory();
+    FlushConfiguration();
     // The acceptors in the AcceptorMap must be released (in DeregisterServices)
     // with the solar mutex unlocked, to avoid deadlock:
     nAcquireCount = Application::ReleaseSolarMutex();
@@ -2073,6 +2065,22 @@ sal_Bool Desktop::InitializeConfiguration()
     return bOk;
 }
 
+void Desktop::FlushConfiguration()
+{
+    Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+    if (xCFGFlush.is())
+    {
+        xCFGFlush->flush();
+    }
+    else
+    {
+        // because there is no method to flush the condiguration data, we must dispose the ConfigManager
+        Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+        if (xCFGDispose.is())
+            xCFGDispose->dispose();
+    }
+}
+
 sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
 {
     try
commit a04b9687b571a7e1179ca857af868a860502ffd1
Author: sb <sb at openoffice.org>
Date:   Mon Oct 4 16:02:38 2010 +0200

    sb133: #i114705# osl::Thread::onTerminated must not be called on deleted object

diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index d1ffa86..d812e54 100644
--- a/configmgr/source/components.cxx
+++ b/configmgr/source/components.cxx
@@ -175,6 +175,8 @@ private:
 
     virtual void SAL_CALL run();
 
+    virtual void SAL_CALL onTerminated() { release(); }
+
     rtl::Reference< WriteThread > * reference_;
     Components & components_;
     rtl::OUString url_;
@@ -188,6 +190,7 @@ Components::WriteThread::WriteThread(
     reference_(reference), components_(components), url_(url), data_(data)
 {
     OSL_ASSERT(reference != 0);
+    acquire();
 }
 
 void Components::WriteThread::run() {
commit 9c3ac85b0904ffb3a3bd7ccbfae9f871659edcb3
Author: sb <sb at openoffice.org>
Date:   Mon Oct 4 13:59:08 2010 +0200

    sb133: #i114705# for performance reasons, call configmgr::writeModFile asynchronously

diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index cc5ea1e..d1ffa86 100644
--- a/configmgr/source/components.cxx
+++ b/configmgr/source/components.cxx
@@ -29,6 +29,7 @@
 #include "sal/config.h"
 
 #include <algorithm>
+#include <cstddef>
 #include <list>
 
 #include "com/sun/star/beans/Optional.hpp"
@@ -43,8 +44,11 @@
 #include "com/sun/star/uno/RuntimeException.hpp"
 #include "com/sun/star/uno/XComponentContext.hpp"
 #include "com/sun/star/uno/XInterface.hpp"
+#include "osl/conditn.hxx"
 #include "osl/diagnose.h"
 #include "osl/file.hxx"
+#include "osl/mutex.hxx"
+#include "osl/thread.hxx"
 #include "rtl/bootstrap.hxx"
 #include "rtl/logfile.h"
 #include "rtl/ref.hxx"
@@ -53,10 +57,12 @@
 #include "rtl/ustring.h"
 #include "rtl/ustring.hxx"
 #include "sal/types.h"
+#include "salhelper/simplereferenceobject.hxx"
 
 #include "additions.hxx"
 #include "components.hxx"
 #include "data.hxx"
+#include "lock.hxx"
 #include "modifications.hxx"
 #include "node.hxx"
 #include "nodemap.hxx"
@@ -148,6 +154,63 @@ static Components * singleton = 0;
 
 }
 
+class Components::WriteThread:
+    public osl::Thread, public salhelper::SimpleReferenceObject
+{
+public:
+    static void * operator new(std::size_t size)
+    { return Thread::operator new(size); }
+
+    static void operator delete(void * pointer)
+    { Thread::operator delete(pointer); }
+
+    WriteThread(
+        rtl::Reference< WriteThread > * reference, Components & components,
+        rtl::OUString const & url, Data const & data);
+
+    void flush() { delay_.set(); }
+
+private:
+    virtual ~WriteThread() {}
+
+    virtual void SAL_CALL run();
+
+    rtl::Reference< WriteThread > * reference_;
+    Components & components_;
+    rtl::OUString url_;
+    Data const & data_;
+    osl::Condition delay_;
+};
+
+Components::WriteThread::WriteThread(
+    rtl::Reference< WriteThread > * reference, Components & components,
+    rtl::OUString const & url, Data const & data):
+    reference_(reference), components_(components), url_(url), data_(data)
+{
+    OSL_ASSERT(reference != 0);
+}
+
+void Components::WriteThread::run() {
+    TimeValue t = { 1, 0 }; // 1 sec
+    delay_.wait(&t); // must not throw; result_error is harmless and ignored
+    osl::MutexGuard g(lock); // must not throw
+    try {
+        try {
+            writeModFile(components_, url_, data_);

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list