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 };
198
199 uno::Any SAL_CALL
getValueByName(OUString const & aName)200 SimpleCurrentContext::getValueByName( OUString const & aName)
201 {
202 return getChainedValueByName(aName);
203 }
204
205 }
206
207 // ----------------------------------------------------------------------------
208 class ConfigurationErrorHandler::Context : public SimpleCurrentContext
209 {
210 public:
Context()211 Context()
212 : SimpleCurrentContext( uno::getCurrentContext() )
213 {
214 }
215
~Context()216 ~Context()
217 {
218 }
219
220 // XCurrentContext
221 virtual uno::Any SAL_CALL
222 getValueByName( OUString const & aName);
223
224 private:
225 InteractionHandler m_xHandler;
226 };
227
228 //------------------------------------------------------------------------------
getValueByName(OUString const & aName)229 uno::Any SAL_CALL ConfigurationErrorHandler::Context::getValueByName( OUString const & aName)
230 {
231 if ( aName.equalsAscii( CONFIG_ERROR_HANDLER ) )
232 {
233 if ( !m_xHandler.is() )
234 m_xHandler = ConfigurationErrorHandler::getDefaultInteractionHandler();
235 return uno::Any( m_xHandler );
236 }
237 return SimpleCurrentContext::getValueByName( aName );
238 }
239
240 //------------------------------------------------------------------------------
~ConfigurationErrorHandler()241 ConfigurationErrorHandler::~ConfigurationErrorHandler()
242 {
243 deactivate();
244 }
245
246 //------------------------------------------------------------------------------
247 // installs the handler into the current context
activate()248 void ConfigurationErrorHandler::activate()
249 {
250 if (!m_pContext)
251 {
252 m_pContext = new Context;
253 m_pContext->acquire();
254 }
255 m_pContext->install();
256 }
257
258 //------------------------------------------------------------------------------
259 // deinstalls the handler from the current context, restoring the previous context
deactivate()260 void ConfigurationErrorHandler::deactivate()
261 {
262 if (m_pContext)
263 {
264 m_pContext->deinstall();
265 m_pContext->release();
266 m_pContext = 0;
267 }
268 }
269 //------------------------------------------------------------------------------
270
getDefaultInteractionHandler()271 ConfigurationErrorHandler::InteractionHandler ConfigurationErrorHandler::getDefaultInteractionHandler()
272 {
273 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
274
275 OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for ConfigurationErrorHandler");
276
277 InteractionHandler xHandler;
278
279 if (xServiceManager.is())
280 {
281 xHandler.set( xServiceManager->createInstance(k_ERRORHANDLER), UNO_QUERY );
282 }
283
284 return xHandler;
285 }
286
287 /* vim: set noet sw=4 ts=4: */
288