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