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