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
getMsgString(sal_uInt16 nId,char const * aFallBackMsg)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
createDefaultConfigurationProvider()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!
handleGeneralException(uno::Exception & aException,const rtl::OUString & aMessage)118 static void handleGeneralException(uno::Exception& aException,
119 const rtl::OUString& aMessage)
120 {
121 aException.Message = aMessage ;
122 throw ;
123 }
124 // ----------------------------------------------------------------------------
125
CreateApplicationConfigurationProvider()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
SimpleCurrentContext(const CurrentContext & xChainedContext)186 SimpleCurrentContext(const CurrentContext & xChainedContext)
187 : m_xChainedContext(xChainedContext)
188 {}
189
install()190 void install() { uno::setCurrentContext(this); }
deinstall()191 void deinstall() { uno::setCurrentContext(m_xChainedContext); }
192
getChainedValueByName(OUString const & aName) const193 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
getValueByName(OUString const & aName)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:
Context()219 Context()
220 : SimpleCurrentContext( uno::getCurrentContext() )
221 {
222 }
223
~Context()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 //------------------------------------------------------------------------------
getValueByName(OUString const & aName)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 //------------------------------------------------------------------------------
~ConfigurationErrorHandler()251 ConfigurationErrorHandler::~ConfigurationErrorHandler()
252 {
253 deactivate();
254 }
255
256 //------------------------------------------------------------------------------
257 /// installs the handler into the current context
activate()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
deactivate()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
getDefaultInteractionHandler()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