summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorJörg Barfurth <jb@openoffice.org>2002-09-18 14:31:05 +0000
committerJörg Barfurth <jb@openoffice.org>2002-09-18 14:31:05 +0000
commit05bd6162e3ab941b7ddd591031301a13085931c7 (patch)
tree1570520957ca3e79a1ad0157c0da71a6b3ac3102 /desktop
parentcd91c00c69189d51f6962bbc808c93ce613208e1 (diff)
#102850# Error handling for configuration bootstrap failures
Diffstat (limited to 'desktop')
-rw-r--r--desktop/source/app/configinit.cxx402
-rw-r--r--desktop/source/app/configinit.hxx44
2 files changed, 446 insertions, 0 deletions
diff --git a/desktop/source/app/configinit.cxx b/desktop/source/app/configinit.cxx
new file mode 100644
index 000000000000..8b6c4a5e00e4
--- /dev/null
+++ b/desktop/source/app/configinit.cxx
@@ -0,0 +1,402 @@
+
+#include "configinit.hxx"
+#include "ssoinit.hxx"
+
+#include "desktop.hrc"
+#include "app.hxx"
+
+#ifndef _SV_MSGBOX_HXX
+#include <vcl/msgbox.hxx>
+#endif
+#ifndef _CPPUHELPER_COMPONENT_CONTEXT_HXX_
+#include <cppuhelper/component_context.hxx>
+#endif
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/processfactory.hxx>
+#endif
+#ifndef _UTL_BOOTSTRAP_HXX
+#include <unotools/bootstrap.hxx>
+#endif
+#ifndef _RTL_USTRBUF_HXX_
+#include <rtl/ustrbuf.hxx>
+#endif
+#ifndef _OSL_DIAGNOSE_H_
+#include <osl/diagnose.h>
+#endif
+#include <stdio.h>
+
+#ifndef _COM_SUN_STAR_LANG_SERVICENOTREGISTEREDEXCEPTION_HPP_
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.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>
+#include <drafts/com/sun/star/configuration/backend/AuthenticationFailedException.hpp>
+#include <drafts/com/sun/star/configuration/backend/InvalidAuthenticationMechanismException.hpp>
+#include <drafts/com/sun/star/configuration/backend/CannotConnectException.hpp>
+#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 configuration = ::com::sun::star::configuration;
+namespace backend = drafts::com::sun::star::configuration::backend;
+using rtl::OUString;
+using uno::UNO_QUERY;
+
+// ----------------------------------------------------------------------------
+static char const CONFIGURATION_PROVIDER[] = "com.sun.star.configuration.ConfigurationProvider";
+static char const LOCAL_BACKEND[] = "com.sun.star.configuration.backend.LocalSingleBackend";
+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 OFFLINE_ENTRY[] = CFG_PREFIX "Offline";
+static char const SERVICE_ENTRY[] = CFG_PREFIX "BackendService";
+static char const WRAPPER_ENTRY[] = CFG_PREFIX "BackendWrapper";
+
+// ----------------------------------------------------------------------------
+#define arraysize( arr ) ( sizeof (arr)/sizeof *(arr) )
+
+typedef uno::Reference< lang::XMultiServiceFactory > ConfigurationProvider;
+
+#define OUSTRING( constascii ) OUString( RTL_CONSTASCII_USTRINGPARAM( constascii ) )
+
+#define OU2O( ustr, enc ) rtl::OUStringToOString( (ustr), RTL_TEXTENCODING_ ## enc )
+
+#define k_PROVIDER OUSTRING( CONFIGURATION_PROVIDER )
+#define k_LOCALBE OUSTRING( LOCAL_BACKEND )
+#define k_SIMPLEWRAPPER OUSTRING( SIMPLE_BACKEND_WRAPPER )
+#define k_OFFLINEWRAPPER OUSTRING( OFFLINE_BACKEND_WRAPPER )
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available. Adapted from Desktop::GetMsgString()
+
+OUString getMsgString( USHORT nId, char const * aFallBackMsg )
+{
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( !pResMgr || !nId )
+ return OUString::createFromAscii(aFallBackMsg);
+ else
+ return OUString( ResId( nId, pResMgr ));
+}
+// ----------------------------------------------------------------------------
+
+/// @attention Must be called (directly or indirectly) from within a catch block
+static
+bool showFallbackMsg( OUString const & sFallbackMsg )
+{
+ rtl::OUStringBuffer sMsg( CreateErrorMessageForCurrentConfigurationException() );
+
+ sMsg.appendAscii("\n").append( sFallbackMsg );
+
+ if ( Application::IsRemoteServer() )
+ {
+ rtl::OString aTmpStr = rtl::OUStringToOString( sMsg.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US );
+ fprintf( stderr, aTmpStr.getStr() );
+ return true;
+ }
+ else
+ {
+ WarningBox aMsgBox( NULL, WB_OK_CANCEL | WB_DEF_OK, sMsg.makeStringAndClear() );
+ return (aMsgBox.Execute() == RET_OK);
+ }
+}
+// ----------------------------------------------------------------------------
+
+/// @attention Must be called (directly or indirectly) from within a catch block
+static
+void showOfflineFallbackMsg( ConfigurationProvider & rxOfflineProvider )
+{
+ OSL_PRECOND( rxOfflineProvider.is(), "Reporting fallback to provider that could not be created" );
+
+ rtl::OUStringBuffer aFallbackMsg( getMsgString(STR_CONFIG_WARN_LOCAL_FALLBACK,
+ "StarOffice will continue the startup using your locally stored personal settings.") );
+
+ aFallbackMsg.appendAscii("\n").append( getMsgString(STR_CONFIG_WARN_OFFLINE,
+ "The changes you have made to your personal settings will be stored locally and "
+ "synchronized the next time you start StarOffice.") );
+
+ if (! showFallbackMsg( aFallbackMsg.makeStringAndClear() ) )
+ rxOfflineProvider.clear();
+}
+// ----------------------------------------------------------------------------
+
+/// @attention Must be called (directly or indirectly) from within a catch block
+static
+void showLocalFallbackMsg( ConfigurationProvider & rxLocalProvider )
+{
+ OSL_PRECOND( rxLocalProvider.is(), "Reporting fallback to provider that could not be created" );
+
+ rtl::OUString aFallbackMsg( getMsgString(STR_CONFIG_WARN_LOCAL_FALLBACK,
+ "StarOffice will continue the startup using your locally stored personal settings.") );
+
+ if (! showFallbackMsg( aFallbackMsg ) )
+ rxLocalProvider.clear();
+}
+// ----------------------------------------------------------------------------
+
+/** Called after authentication failures to allow re-login
+*/
+static
+sal_Bool relogin()
+{
+ rtl::OUStringBuffer sMsg( getMsgString( STR_CONFIG_ERR_LOGIN_FAILED,
+ "Your login to the central configuration was not successful. "
+ "Either the user name or password is invalid. ") );
+
+ sMsg.appendAscii("\n").append( getMsgString( STR_SSO_RELOGIN, "Please log in again.") );
+
+ ErrorBox aMsgBox( NULL, WB_RETRY_CANCEL | WB_DEF_RETRY, sMsg.makeStringAndClear() );
+
+ if (aMsgBox.Execute() == RET_RETRY)
+ {
+ return InitSSO( true );
+ }
+ else
+ return false;
+}
+// ----------------------------------------------------------------------------
+
+/** Creates the normal configuration provider.
+
+ <p> If creation fails because of invalid authentication,
+ offers the opportunity to re-login where applicable.
+ </p>
+*/
+static
+ConfigurationProvider createDefaultConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for CreateApplicationConfigurationProvider");
+
+ ConfigurationProvider xProvider;
+
+ if (xServiceManager.is())
+ {
+ retry:
+ try
+ {
+ xProvider.set( xServiceManager->createInstance(k_PROVIDER), UNO_QUERY);
+ }
+ catch (backend::AuthenticationFailedException & e)
+ {
+
+ OSL_TRACE( "Configuration: Authentication failed: %s\n",
+ OU2O(e.Message,ASCII_US).getStr() );
+
+ if (!NeedsLogin())
+ throw;
+
+ if (!relogin())
+ {
+ // canceled
+ OSL_ASSERT( !xProvider.is() );
+ return xProvider;
+ }
+
+ goto retry;
+ }
+ }
+
+ if (!xProvider.is())
+ {
+ OUString const sMsg = OUSTRING("Service \"") + k_PROVIDER +
+ OUSTRING("\" is not available at the service manager.");
+
+ throw lang::ServiceNotRegisteredException(sMsg, xServiceManager);
+ }
+
+ return 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);
+}
+// ----------------------------------------------------------------------------
+
+static
+sal_Bool tryCreateConfigurationWithContext( ConfigurationProvider & rxProvider, uno::Reference< uno::XComponentContext > const & xContext )
+{
+ OSL_PRECOND( xContext.is(), "NULL context" );
+ OSL_PRECOND( !rxProvider.is(), "Provider already set" );
+
+ try
+ {
+ uno::Reference< lang::XMultiComponentFactory > xFactory = xContext->getServiceManager();
+ OSL_ENSURE( xFactory.is(), "Context has no service factory !" );
+
+ if (xFactory.is())
+ rxProvider.set( xFactory->createInstanceWithContext( k_PROVIDER, xContext ), UNO_QUERY );
+ }
+ catch (uno::Exception & )
+ {
+ }
+
+ return rxProvider.is();
+}
+// ----------------------------------------------------------------------------
+
+static
+inline
+cppu::ContextEntry_Init defineContextEntry( OUString const & name, uno::Any const & value)
+{
+ cppu::ContextEntry_Init entry;
+ entry.bLateInitService = false;
+ entry.name = name;
+ entry.value = value;
+ return entry;
+}
+// ----------------------------------------------------------------------------
+
+static
+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) )
+ };
+ return tryCreateConfigurationWithContext( rxProvider, wrapContext(aEntries, arraysize( aEntries )) );
+}
+// ----------------------------------------------------------------------------
+
+static
+sal_Bool tryCreateLocalConfiguration( ConfigurationProvider & rxProvider )
+{
+ cppu::ContextEntry_Init aEntries[] =
+ {
+ defineContextEntry( OUSTRING( SERVICE_ENTRY ), uno::makeAny<OUString>( k_LOCALBE ) ),
+ defineContextEntry( OUSTRING( WRAPPER_ENTRY ), uno::makeAny<OUString>( k_SIMPLEWRAPPER ) ),
+ defineContextEntry( OUSTRING( OFFLINE_ENTRY ), uno::Any() )
+ };
+ return tryCreateConfigurationWithContext( rxProvider, wrapContext(aEntries, arraysize( aEntries )) );
+}
+// ----------------------------------------------------------------------------
+
+uno::Reference< lang::XMultiServiceFactory > CreateApplicationConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xProvider;
+
+ try
+ {
+ xProvider = createDefaultConfigurationProvider( );
+ }
+ catch (backend::CannotConnectException & )
+ {
+ if ( tryCreateOfflineConfiguration(xProvider) )
+ showOfflineFallbackMsg( xProvider );
+
+ else if ( tryCreateLocalConfiguration(xProvider) )
+ showLocalFallbackMsg( xProvider );
+
+ else
+ throw;
+ }
+ catch (backend::BackendAccessException & )
+ {
+ if ( tryCreateOfflineConfiguration(xProvider) )
+ showOfflineFallbackMsg( xProvider );
+
+ else if ( tryCreateLocalConfiguration(xProvider) )
+ showLocalFallbackMsg( xProvider );
+
+ else
+ throw;
+ }
+ catch (uno::Exception & )
+ {
+ if ( tryCreateLocalConfiguration(xProvider) )
+ showLocalFallbackMsg( xProvider );
+
+ else
+ throw;
+ }
+
+ return xProvider;
+}
+// ----------------------------------------------------------------------------
+OUString CreateErrorMessageForCurrentConfigurationException()
+{
+ try
+ {
+ throw;
+ }
+ catch (configuration::InvalidBootstrapFileException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_SETTINGS_INCOMPLETE,
+ "The startup settings for accessing the central configuration are incomplete. ");
+ }
+ catch (backend::InvalidAuthenticationMechanismException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_MECHANISM_INVALID,
+ "The specified authentication method to access the central configuration is not supported. ");
+ }
+ catch (backend::AuthenticationFailedException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_LOGIN_FAILED,
+ "Your login to the central configuration was not successful. "
+ "Either the user name or password is invalid. ");
+ }
+ catch (backend::CannotConnectException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to the central configuration could not be established. ");
+ }
+ catch (backend::InsufficientAccessRightsException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_RIGHTS_MISSING,
+ "You cannot access the central configuration because of missing access rights. ");
+ }
+ catch (backend::BackendAccessException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ "A general access error occurred while accessing your central configuration.");
+ }
+ catch (backend::BackendSetupException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to the central configuration could not be established. ");
+ }
+ catch (configuration::CannotLoadConfigurationException & )
+ {
+ return getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to the central configuration could not be established. ");
+ }
+ catch (uno::Exception & )
+ {
+ return getMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ "A general error occurred while accessing your central configuration.");
+ }
+}
+
+// ----------------------------------------------------------------------------
diff --git a/desktop/source/app/configinit.hxx b/desktop/source/app/configinit.hxx
new file mode 100644
index 000000000000..d53a2c3366ac
--- /dev/null
+++ b/desktop/source/app/configinit.hxx
@@ -0,0 +1,44 @@
+#ifndef _DESKTOP_CONFIGINIT_HXX_
+#define _DESKTOP_CONFIGINIT_HXX_
+
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+/** creates a ConfigurationProvider instance
+
+ @return
+ The default configuration provider for the application or<br/>
+ <NULL/>, if startup was canceled
+
+ @throw com::sun::star::configuration::CannotLoadConfigurationException
+ if the configuration provider can't be created
+
+ @throw com::sun::star::lang::ServiceNotRegisteredException
+ if the ConfigurationProvider service is unknwon
+
+ @throw com::sun::star::lang::WrappedTargetException
+ if the configuration backend could be created,
+ but incurred a failure later
+
+*/
+extern
+com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ CreateApplicationConfigurationProvider( );
+
+/** returns an error message for the exception currently being processed
+
+ <p>Can deal with the exceptions that can occur during configuration creation.</p>
+
+ @attention Must be called from within a catch block !
+ @attention Must be called only once from a given catch block.
+ @attention After calling this, the exception can't be rethrown any more.
+*/
+extern
+rtl::OUString CreateErrorMessageForCurrentConfigurationException();
+
+#endif