xref: /trunk/main/desktop/source/app/configinit.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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