xref: /trunk/main/desktop/source/app/configinit.cxx (revision a3cdc23e488c57f3433f22cd4458e65c27aa499c)
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 
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
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!
115 static void handleGeneralException(uno::Exception& aException,
116                                    const rtl::OUString& aMessage)
117 {
118     aException.Message = aMessage ;
119     throw ;
120 }
121 // ----------------------------------------------------------------------------
122 
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
180         SimpleCurrentContext(const CurrentContext & xChainedContext)
181         : m_xChainedContext(xChainedContext)
182         {}
183 
184         void install()      { uno::setCurrentContext(this); }
185         void deinstall()    { uno::setCurrentContext(m_xChainedContext); }
186 
187         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
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:
213     Context()
214     : SimpleCurrentContext( uno::getCurrentContext() )
215     {
216     }
217 
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 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
245 ConfigurationErrorHandler::~ConfigurationErrorHandler()
246 {
247     deactivate();
248 }
249 
250 //------------------------------------------------------------------------------
251 // installs the handler into the current context
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
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 
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