diff options
Diffstat (limited to 'desktop/source/app/configinit.cxx')
-rw-r--r-- | desktop/source/app/configinit.cxx | 265 |
1 files changed, 234 insertions, 31 deletions
diff --git a/desktop/source/app/configinit.cxx b/desktop/source/app/configinit.cxx index 4d34075fba..0016171d0c 100644 --- a/desktop/source/app/configinit.cxx +++ b/desktop/source/app/configinit.cxx @@ -14,6 +14,9 @@ #ifndef _COMPHELPER_PROCESSFACTORY_HXX_ #include <comphelper/processfactory.hxx> #endif +#ifndef _RTL_BOOTSTRAP_HXX_ +#include <rtl/bootstrap.hxx> +#endif #ifndef _UTL_BOOTSTRAP_HXX #include <unotools/bootstrap.hxx> #endif @@ -31,6 +34,15 @@ #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ #include <com/sun/star/beans/XPropertySet.hpp> #endif +#ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_ +#include <com/sun/star/beans/NamedValue.hpp> +#endif +#ifndef _COM_SUN_STAR_TASK_XJOB_HPP_ +#include <com/sun/star/task/XJob.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_XCHANGESBATCH_HPP_ +#include <com/sun/star/util/XChangesBatch.hpp> +#endif #include <com/sun/star/configuration/CannotLoadConfigurationException.hpp> #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp> #include <drafts/com/sun/star/configuration/backend/BackendSetupException.hpp> @@ -40,11 +52,13 @@ #include <drafts/com/sun/star/configuration/backend/BackendAccessException.hpp> #include <drafts/com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp> - // ---------------------------------------------------------------------------- namespace uno = ::com::sun::star::uno; namespace lang = ::com::sun::star::lang; +namespace beans = ::com::sun::star::beans; +namespace util = ::com::sun::star::util; +namespace task = ::com::sun::star::task; namespace configuration = ::com::sun::star::configuration; namespace backend = drafts::com::sun::star::configuration::backend; using rtl::OUString; @@ -57,11 +71,25 @@ static char const LOCAL_BACKEND[] = "com.sun.star.configuration.backen static char const SIMPLE_BACKEND_WRAPPER[] = "com.sun.star.configuration.backend.OnlineBackend"; static char const OFFLINE_BACKEND_WRAPPER[] = "com.sun.star.configuration.backend.OfflineBackend"; -#define CFG_PREFIX "com.sun.star.configuration.bootstrap." +static char const READONLY_ACCESS[] = "com.sun.star.configuration.ConfigurationAccess"; +static char const UPDATE_ACCESS[] = "com.sun.star.configuration.ConfigurationUpdateAccess"; +static char const USERDATA_LOCATOR[] = "com.sun.star.configuration.backend.local.HierarchyBrowser"; +static char const USERDATA_IMPORTER[] = "com.sun.star.configuration.backend.LocalDataImporter"; +static char const USERDATA_IMPORTSERVICE[] = "com.sun.star.configuration.backend.CopyImporter"; + +static char const CONFIGURATION_SETTINGS[] = "/org.openoffice.Setup/Configuration"; + static char const SETTING_DOIMPORT[] = "TransferUserSettingsOnce"; + +#define CFG_PREFIX "/modules/com.sun.star.configuration/bootstrap/" +#define CFG_INIPREFIX "CFG_" static char const OFFLINE_ENTRY[] = CFG_PREFIX "Offline"; static char const SERVICE_ENTRY[] = CFG_PREFIX "BackendService"; static char const WRAPPER_ENTRY[] = CFG_PREFIX "BackendWrapper"; +static char const INITUSERDATA_ENTRY[] = CFG_INIPREFIX "InitializeUserDataFromURL"; + +#define CONTEXT_ITEM_PASSTHRU "/implementations/com.sun.star.com.configuration.bootstrap.ComponentContext/isPassthrough" + // ---------------------------------------------------------------------------- #define arraysize( arr ) ( sizeof (arr)/sizeof *(arr) ) @@ -77,6 +105,9 @@ typedef uno::Reference< lang::XMultiServiceFactory > ConfigurationProvider; #define k_OFFLINEWRAPPER OUSTRING( OFFLINE_BACKEND_WRAPPER ) // ---------------------------------------------------------------------------- +static void initializeUserData( ConfigurationProvider const & xProvider ); +static uno::Reference< uno::XInterface > getConfigurationSettings( ConfigurationProvider const & xProvider, bool bUpdate ); + // ---------------------------------------------------------------------------- // Get a message string securely. There is a fallback string if the resource // is not available. Adapted from Desktop::GetMsgString() @@ -91,7 +122,18 @@ OUString getMsgString( USHORT nId, char const * aFallBackMsg ) } // ---------------------------------------------------------------------------- -/// @attention Must be called (directly or indirectly) from within a catch block +void setMsgBoxTitle( MessBox & aMsgBox ) +{ + ResMgr* pResMgr = Desktop::GetDesktopResManager(); + + OUString aMsgBoxTitle = pResMgr ? OUString( ResId( STR_TITLE_CONFIG_MSGBOX, pResMgr )) : + utl::Bootstrap::getProductKey(); + + if (aMsgBoxTitle.getLength()) + aMsgBox.SetText(aMsgBoxTitle); +} +// ---------------------------------------------------------------------------- + static bool showFallbackMsg( OUString const & sFallbackMsg, const rtl::OUString& aMessage) @@ -109,12 +151,12 @@ bool showFallbackMsg( OUString const & sFallbackMsg, else { WarningBox aMsgBox( NULL, WB_OK_CANCEL | WB_DEF_OK, sMsg.makeStringAndClear() ); + setMsgBoxTitle( aMsgBox ); return (aMsgBox.Execute() == RET_OK); } } // ---------------------------------------------------------------------------- -/// @attention Must be called (directly or indirectly) from within a catch block static void showOfflineFallbackMsg( ConfigurationProvider & rxOfflineProvider, const rtl::OUString& aMessage) @@ -133,7 +175,6 @@ void showOfflineFallbackMsg( ConfigurationProvider & rxOfflineProvider, } // ---------------------------------------------------------------------------- -/// @attention Must be called (directly or indirectly) from within a catch block static void showLocalFallbackMsg( ConfigurationProvider & rxLocalProvider, const rtl::OUString& aMessage) @@ -160,6 +201,7 @@ sal_Bool relogin() sMsg.appendAscii("\n").append( getMsgString( STR_SSO_RELOGIN, "Please log in again.") ); ErrorBox aMsgBox( NULL, WB_RETRY_CANCEL | WB_DEF_RETRY, sMsg.makeStringAndClear() ); + setMsgBoxTitle( aMsgBox ); if (aMsgBox.Execute() == RET_RETRY) { @@ -170,6 +212,40 @@ sal_Bool relogin() } // ---------------------------------------------------------------------------- +static +uno::Reference< uno::XComponentContext > getProcessContext( ) +{ + uno::Reference< uno::XComponentContext > xBaseContext; + try + { + uno::Reference< ::com::sun::star::beans::XPropertySet > + xPS( ::comphelper::getProcessServiceFactory(), UNO_QUERY ); + + OSL_ENSURE( xPS.is(), "Cannot get default component context for the process service-manager: no property-set"); + if (xPS.is()) + { + OSL_VERIFY( xPS->getPropertyValue( OUSTRING( "DefaultContext" ) ) >>= xBaseContext ); + } + } + catch (uno::Exception & ) + { + OSL_ENSURE( false, "Cannot get default component context for the process service-manager"); + } + return xBaseContext; +} +// ---------------------------------------------------------------------------- + +static +inline +uno::Reference< uno::XComponentContext > + wrapContext( cppu::ContextEntry_Init * pEntries, sal_Int32 nEntries ) +{ + uno::Reference< uno::XComponentContext > xBaseContext = getProcessContext( ); + + return cppu::createComponentContext(pEntries, nEntries, xBaseContext); +} +// ---------------------------------------------------------------------------- + /** Creates the normal configuration provider. <p> If creation fails because of invalid authentication, @@ -220,31 +296,9 @@ ConfigurationProvider createDefaultConfigurationProvider( ) throw lang::ServiceNotRegisteredException(sMsg, xServiceManager); } - return xProvider; -} -// ---------------------------------------------------------------------------- + initializeUserData(xProvider); -static -uno::Reference< uno::XComponentContext > - wrapContext( cppu::ContextEntry_Init * pEntries, sal_Int32 nEntries ) -{ - uno::Reference< uno::XComponentContext > xBaseContext; - try - { - uno::Reference< ::com::sun::star::beans::XPropertySet > - xPS( ::comphelper::getProcessServiceFactory(), UNO_QUERY ); - - OSL_ENSURE( xPS.is(), "Cannot get default component context for the process service-manager: no property-set"); - if (xPS.is()) - { - OSL_VERIFY( xPS->getPropertyValue( OUSTRING( "DefaultContext" ) ) >>= xBaseContext ); - } - } - catch (uno::Exception & ) - { - OSL_ENSURE( false, "Cannot get default component context for the process service-manager"); - } - return cppu::createComponentContext(pEntries, nEntries, xBaseContext); + return xProvider; } // ---------------------------------------------------------------------------- @@ -288,7 +342,8 @@ sal_Bool tryCreateOfflineConfiguration( ConfigurationProvider & rxProvider ) cppu::ContextEntry_Init aEntries[] = { // { false, OUSTRING( WRAPPER_ENTRY ), uno::makeAny<OUString>( k_OFFLINEWRAPPER ) }, - defineContextEntry( OUSTRING( OFFLINE_ENTRY ), uno::makeAny<sal_Bool>(sal_True) ) + defineContextEntry( OUSTRING( OFFLINE_ENTRY ), uno::makeAny<sal_Bool>(sal_True) ), + defineContextEntry( OUSTRING( CONTEXT_ITEM_PASSTHRU ), uno::makeAny<sal_Bool>(sal_True) ) }; return tryCreateConfigurationWithContext( rxProvider, wrapContext(aEntries, arraysize( aEntries )) ); } @@ -301,7 +356,8 @@ sal_Bool tryCreateLocalConfiguration( ConfigurationProvider & rxProvider ) { defineContextEntry( OUSTRING( SERVICE_ENTRY ), uno::makeAny<OUString>( k_LOCALBE ) ), defineContextEntry( OUSTRING( WRAPPER_ENTRY ), uno::makeAny<OUString>( k_SIMPLEWRAPPER ) ), - defineContextEntry( OUSTRING( OFFLINE_ENTRY ), uno::Any() ) + defineContextEntry( OUSTRING( OFFLINE_ENTRY ), uno::Any() ), + defineContextEntry( OUSTRING( CONTEXT_ITEM_PASSTHRU ), uno::makeAny<sal_Bool>(sal_True) ) }; return tryCreateConfigurationWithContext( rxProvider, wrapContext(aEntries, arraysize( aEntries )) ); } @@ -421,3 +477,150 @@ uno::Reference< lang::XMultiServiceFactory > CreateApplicationConfigurationProvi } return xProvider ; } +// ---------------------------------------------------------------------------- + +static uno::Sequence< OUString > locateUserData(uno::Reference< lang::XMultiServiceFactory > const & xLocatorFactory, OUString const & sUserDataSource ) +{ + uno::Sequence< OUString > aResult; + + uno::Reference< task::XJob > xLocator( xLocatorFactory->createInstance( OUSTRING(USERDATA_LOCATOR) ), uno::UNO_QUERY); + + if (xLocator.is()) + { + uno::Sequence< beans::NamedValue > aArgs(2); + + aArgs[0].Name = OUSTRING("LayerDataUrl"); + aArgs[0].Value <<= sUserDataSource; + + OUString aUserProfile = OUSTRING("org.openoffice.UserProfile"); + uno::Sequence< OUString > aSkipComponents(&aUserProfile,1); + aArgs[1].Name = OUSTRING("ExcludeComponents"); + aArgs[1].Value <<= aSkipComponents; + + uno::Any aFound = xLocator->execute(aArgs); + aFound >>= aResult; + } + else + OSL_TRACE("Configuration - Import of user settings into new backend failed: No Locator Service available\n"); + + return aResult; +} +// ---------------------------------------------------------------------------- + +static void copyUserData(uno::Reference< lang::XMultiServiceFactory > const & xImporterFactory, uno::Sequence< OUString > const & sUserDataLayers ) +{ + uno::Reference< task::XJob > xImporter( xImporterFactory->createInstance(OUSTRING(USERDATA_IMPORTER)), uno::UNO_QUERY); + + if (xImporter.is()) + { + uno::Sequence< beans::NamedValue > aArgs(3); + aArgs[0].Name = OUSTRING("LayerDataUrl"); + aArgs[1].Name = OUSTRING("OverwriteExisting"); + aArgs[1].Value <<= sal_False; + aArgs[2].Name = OUSTRING("ImporterService"); + aArgs[2].Value <<= OUSTRING(USERDATA_IMPORTSERVICE); + + for (sal_Int32 i=0; i < sUserDataLayers.getLength(); ++i) + { + aArgs[0].Value <<= sUserDataLayers[i]; + + xImporter->execute(aArgs); + } + // TODO: If org.openoffice.Setup was copied, refresh data in cache + } + else + OSL_TRACE("Configuration - Import of user settings into new backend failed: No Importer Service available\n"); +} +// ---------------------------------------------------------------------------- + +static void maybeCopyUserData( ConfigurationProvider const & xProvider ) +{ + OUString aUserDataSourceURL; + + // TODO: use "Context" property of xProvider to retrieve the information + { + static char const CONFIGRC[] = "$SYSBINDIR/" SAL_CONFIGFILE("configmgr"); + OUString sConfigIni = OUSTRING( CONFIGRC ); + rtl::Bootstrap::expandMacros(sConfigIni); + + rtl::Bootstrap aConfigInfo(sConfigIni); + + if (!aConfigInfo.getFrom( OUSTRING(INITUSERDATA_ENTRY), aUserDataSourceURL ) ) + return; + } + + if (aUserDataSourceURL.getLength() == 0) + return; + + uno::Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + + uno::Sequence< OUString > aDataUrls = locateUserData( xMSF, aUserDataSourceURL); + if (aDataUrls.getLength() == 0) + return; + + QueryBox aAskUser( NULL, ResId( QBX_CONFIG_IMPORTSETTINGS, Desktop::GetDesktopResManager() ) ); + setMsgBoxTitle(aAskUser); + + if (aAskUser.Execute() == RET_YES) + copyUserData(xMSF, aDataUrls); +} +// ---------------------------------------------------------------------------- + +static void initializeUserData( ConfigurationProvider const & xProvider ) +{ + OSL_ASSERT( xProvider.is() ); + + try + { + uno::Reference< beans::XPropertySet > xSettings( getConfigurationSettings(xProvider,true), uno::UNO_QUERY ); + if (xSettings.is()) + { + OUString const aSetting = OUSTRING(SETTING_DOIMPORT); + + sal_Bool bDoImport = false; + xSettings->getPropertyValue( aSetting ) >>= bDoImport; + + if ( bDoImport ) + { + maybeCopyUserData( xProvider ); + xSettings->setPropertyValue( aSetting, uno::makeAny(sal_False) ); + + uno::Reference< util::XChangesBatch > xCommitSettings(xSettings, uno::UNO_QUERY); + OSL_ENSURE(xCommitSettings.is(), "Missing interface to commit configuration change\n"); + if (xCommitSettings.is()) xCommitSettings->commitChanges(); + } + } + } + catch (uno::Exception & e) + { + OSL_TRACE( "Configuration - Import of user settings into new backend failed: %s\n", + OU2O(e.Message,ASCII_US).getStr() ); + } + +} +// ---------------------------------------------------------------------------- + +static uno::Reference< uno::XInterface > getConfigurationSettings( ConfigurationProvider const & xProvider, bool bUpdate ) +{ + if ( xProvider.is() ) + try + { + OUString sService = bUpdate ? OUSTRING(UPDATE_ACCESS) : OUSTRING(READONLY_ACCESS); + + OUString const sNodepath = OUSTRING(CONFIGURATION_SETTINGS); + + uno::Sequence< uno::Any > aArguments(1); + aArguments[0] <<= beans::NamedValue( OUSTRING("nodepath"), uno::makeAny(sNodepath) ); + + return xProvider->createInstanceWithArguments(sService,aArguments); + } + catch (uno::Exception & e) + { + OSL_TRACE( "Configuration - Cannot get settings for configuration service: %s\n", + OU2O(e.Message,ASCII_US).getStr() ); + + } + return uno::Reference< uno::XInterface >(); +} +// ---------------------------------------------------------------------------- + |