1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 // MARKER(update_precomp.py): autogen include statement, do not remove 30 #include "precompiled_desktop.hxx" 31 32 #include "configinit.hxx" 33 34 #include "desktop.hrc" 35 #include "app.hxx" 36 #include <comphelper/processfactory.hxx> 37 #include <uno/current_context.hxx> 38 #include <cppuhelper/implbase1.hxx> 39 #include <rtl/ustrbuf.hxx> 40 #include <osl/diagnose.h> 41 #include <stdio.h> 42 #include <map> 43 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp> 44 #include <com/sun/star/configuration/CannotLoadConfigurationException.hpp> 45 #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp> 46 #include <com/sun/star/configuration/backend/BackendSetupException.hpp> 47 #include <com/sun/star/configuration/backend/CannotConnectException.hpp> 48 49 // ---------------------------------------------------------------------------- 50 51 namespace uno = ::com::sun::star::uno; 52 namespace lang = ::com::sun::star::lang; 53 namespace configuration = ::com::sun::star::configuration; 54 namespace backend = ::com::sun::star::configuration::backend; 55 using rtl::OUString; 56 using uno::UNO_QUERY; 57 using desktop::Desktop; 58 59 // ---------------------------------------------------------------------------- 60 static char const CONFIGURATION_PROVIDER[] = "com.sun.star.configuration.ConfigurationProvider"; 61 62 static char const CONFIGURATION_ERROR_HANDLER[] = "com.sun.star.configuration.backend.InteractionHandler"; 63 64 // must be aligned with configmgr/source/misc/configinteractionhandler 65 static char const CONFIG_ERROR_HANDLER[] = "configuration.interaction-handler"; 66 // ---------------------------------------------------------------------------- 67 68 // ---------------------------------------------------------------------------- 69 #define arraysize( arr ) ( sizeof (arr)/sizeof *(arr) ) 70 71 typedef uno::Reference< lang::XMultiServiceFactory > ConfigurationProvider; 72 73 #define OUSTRING( constascii ) OUString( RTL_CONSTASCII_USTRINGPARAM( constascii ) ) 74 75 #define OU2O( ustr, enc ) rtl::OUStringToOString( (ustr), RTL_TEXTENCODING_ ## enc ) 76 77 #define k_PROVIDER OUSTRING( CONFIGURATION_PROVIDER ) 78 #define k_ERRORHANDLER OUSTRING( CONFIGURATION_ERROR_HANDLER ) 79 // ---------------------------------------------------------------------------- 80 // Get a message string securely. There is a fallback string if the resource 81 // is not available. Adapted from Desktop::GetMsgString() 82 83 OUString getMsgString( sal_uInt16 nId, char const * aFallBackMsg ) 84 { 85 ResMgr* pResMgr = Desktop::GetDesktopResManager(); 86 if ( !pResMgr || !nId ) 87 return OUString::createFromAscii(aFallBackMsg); 88 else 89 return OUString( String(ResId( nId, *pResMgr ))); 90 } 91 // ---------------------------------------------------------------------------- 92 /** Creates the normal configuration provider. 93 94 */ 95 static 96 ConfigurationProvider createDefaultConfigurationProvider( ) 97 { 98 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); 99 100 OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for CreateApplicationConfigurationProvider"); 101 102 ConfigurationProvider xProvider; 103 104 if (xServiceManager.is()) 105 { 106 107 xProvider.set( xServiceManager->createInstance(k_PROVIDER), UNO_QUERY); 108 } 109 110 if (!xProvider.is()) 111 { 112 OUString const sMsg = OUSTRING("Service \"") + k_PROVIDER + 113 OUSTRING("\" is not available at the service manager."); 114 115 throw lang::ServiceNotRegisteredException(sMsg, xServiceManager); 116 } 117 118 return xProvider; 119 } 120 // ---------------------------------------------------------------------------- 121 /// @attention this method must be called from a catch statement! 122 static void handleGeneralException(uno::Exception& aException, 123 const rtl::OUString& aMessage) 124 { 125 aException.Message = aMessage ; 126 throw ; 127 } 128 // ---------------------------------------------------------------------------- 129 130 uno::Reference< lang::XMultiServiceFactory > CreateApplicationConfigurationProvider( ) 131 { 132 uno::Reference< lang::XMultiServiceFactory > xProvider; 133 134 try 135 { 136 xProvider = createDefaultConfigurationProvider( ); 137 } 138 catch (configuration::InvalidBootstrapFileException & exception) 139 { 140 handleGeneralException(exception, 141 getMsgString( STR_CONFIG_ERR_SETTINGS_INCOMPLETE, 142 "The startup settings for your configuration settings are incomplete. ")); 143 } 144 catch (backend::CannotConnectException & exception) 145 { 146 handleGeneralException(exception, 147 getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT, 148 "A connection to your configuration settings could not be established. ")); 149 } 150 catch (backend::BackendSetupException & exception) 151 { 152 handleGeneralException(exception, 153 getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT, 154 "A connection to your configuration settings could not be established. ")); 155 } 156 catch (configuration::CannotLoadConfigurationException & exception) 157 { 158 handleGeneralException(exception, 159 getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT, 160 "A connection to your configuration settings could not be established. ")); 161 } 162 catch (uno::Exception & exception) 163 { 164 handleGeneralException(exception, 165 getMsgString( STR_CONFIG_ERR_ACCESS_GENERAL, 166 "A general error occurred while accessing your configuration settings.")); 167 } 168 169 170 return xProvider ; 171 } 172 // ---------------------------------------------------------------------------- 173 174 175 176 177 // ---------------------------------------------------------------------------- 178 // ---------------------------------------------------------------------------- 179 // ConfigurationErrorHandler 180 // ---------------------------------------------------------------------------- 181 182 namespace 183 { 184 typedef uno::Reference< uno::XCurrentContext > CurrentContext; 185 class SimpleCurrentContext : public cppu::WeakImplHelper1< uno::XCurrentContext > 186 { 187 CurrentContext m_xChainedContext; 188 public: 189 explicit 190 SimpleCurrentContext(const CurrentContext & xChainedContext) 191 : m_xChainedContext(xChainedContext) 192 {} 193 194 void install() { uno::setCurrentContext(this); } 195 void deinstall() { uno::setCurrentContext(m_xChainedContext); } 196 197 uno::Any getChainedValueByName( OUString const & aName) const 198 { 199 return m_xChainedContext.is() 200 ? m_xChainedContext->getValueByName(aName) 201 : uno::Any(); 202 } 203 204 // XCurrentContext 205 virtual uno::Any SAL_CALL 206 getValueByName( OUString const & aName) 207 throw (uno::RuntimeException); 208 }; 209 210 uno::Any SAL_CALL 211 SimpleCurrentContext::getValueByName( OUString const & aName) 212 throw (uno::RuntimeException) 213 { 214 return getChainedValueByName(aName); 215 } 216 217 } 218 219 // ---------------------------------------------------------------------------- 220 class ConfigurationErrorHandler::Context : public SimpleCurrentContext 221 { 222 public: 223 Context() 224 : SimpleCurrentContext( uno::getCurrentContext() ) 225 { 226 } 227 228 ~Context() 229 { 230 } 231 232 // XCurrentContext 233 virtual uno::Any SAL_CALL 234 getValueByName( OUString const & aName) 235 throw (uno::RuntimeException); 236 237 private: 238 InteractionHandler m_xHandler; 239 }; 240 241 //------------------------------------------------------------------------------ 242 uno::Any SAL_CALL ConfigurationErrorHandler::Context::getValueByName( OUString const & aName) 243 throw (uno::RuntimeException) 244 { 245 if ( aName.equalsAscii( CONFIG_ERROR_HANDLER ) ) 246 { 247 if ( !m_xHandler.is() ) 248 m_xHandler = ConfigurationErrorHandler::getDefaultInteractionHandler(); 249 return uno::Any( m_xHandler ); 250 } 251 return SimpleCurrentContext::getValueByName( aName ); 252 } 253 254 //------------------------------------------------------------------------------ 255 ConfigurationErrorHandler::~ConfigurationErrorHandler() 256 { 257 deactivate(); 258 } 259 260 //------------------------------------------------------------------------------ 261 /// installs the handler into the current context 262 void ConfigurationErrorHandler::activate() 263 { 264 if (!m_pContext) 265 { 266 m_pContext = new Context; 267 m_pContext->acquire(); 268 } 269 m_pContext->install(); 270 } 271 272 //------------------------------------------------------------------------------ 273 /// deinstalls the handler from the current context, restoring the previous context 274 void ConfigurationErrorHandler::deactivate() 275 { 276 if (m_pContext) 277 { 278 m_pContext->deinstall(); 279 m_pContext->release(); 280 m_pContext = 0; 281 } 282 } 283 //------------------------------------------------------------------------------ 284 285 ConfigurationErrorHandler::InteractionHandler ConfigurationErrorHandler::getDefaultInteractionHandler() 286 { 287 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); 288 289 OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for ConfigurationErrorHandler"); 290 291 InteractionHandler xHandler; 292 293 if (xServiceManager.is()) 294 { 295 xHandler.set( xServiceManager->createInstance(k_ERRORHANDLER), UNO_QUERY ); 296 } 297 298 return xHandler; 299 } 300 //------------------------------------------------------------------------------ 301 302 303 304