Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <algorithm>
31 : :
32 : : #include "app.hxx"
33 : : #include "cmdlineargs.hxx"
34 : : #include "desktopresid.hxx"
35 : : #include "desktop.hrc"
36 : : #include <com/sun/star/registry/XSimpleRegistry.hpp>
37 : : #include <com/sun/star/lang/XComponent.hpp>
38 : : #include <com/sun/star/lang/XInitialization.hpp>
39 : : #include <com/sun/star/uno/Exception.hpp>
40 : : #include <com/sun/star/uno/XCurrentContext.hpp>
41 : : #include <com/sun/star/packages/zip/ZipIOException.hpp>
42 : :
43 : :
44 : : #include <com/sun/star/beans/XPropertySet.hpp>
45 : : #include <com/sun/star/ucb/XContentProviderManager.hpp>
46 : : #include <com/sun/star/ucb/XContentProviderFactory.hpp>
47 : : #include <uno/current_context.hxx>
48 : : #include <cppuhelper/servicefactory.hxx>
49 : : #include <cppuhelper/bootstrap.hxx>
50 : : #include <osl/file.hxx>
51 : : #include <osl/module.h>
52 : : #include <osl/security.hxx>
53 : : #include <rtl/uri.hxx>
54 : : #include <rtl/ustrbuf.hxx>
55 : : #include <rtl/bootstrap.hxx>
56 : : #include <ucbhelper/configurationkeys.hxx>
57 : :
58 : : #include <tools/rcid.h>
59 : :
60 : : #include <rtl/logfile.hxx>
61 : : #include <rtl/instance.hxx>
62 : : #include <comphelper/processfactory.hxx>
63 : : #include <unotools/localfilehelper.hxx>
64 : : #include <unotools/ucbhelper.hxx>
65 : : #include <unotools/tempfile.hxx>
66 : : #include <ucbhelper/contentbroker.hxx>
67 : : #include <vcl/svapp.hxx>
68 : : #include <unotools/startoptions.hxx>
69 : : #include <unotools/pathoptions.hxx>
70 : : #include <unotools/internaloptions.hxx>
71 : :
72 : :
73 : : using namespace desktop;
74 : : using namespace ::com::sun::star::uno;
75 : : using namespace ::com::sun::star::lang;
76 : : using namespace ::com::sun::star::beans;
77 : : using namespace ::com::sun::star::registry;
78 : : using namespace ::com::sun::star::ucb;
79 : :
80 : : using ::rtl::OUString;
81 : :
82 : : namespace desktop
83 : : {
84 : :
85 : : // -----------------------------------------------------------------------------
86 : :
87 : 158 : static bool configureUcb()
88 : : {
89 : : RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
90 : : Reference< XMultiServiceFactory >
91 [ + - ]: 158 : xServiceFactory( comphelper::getProcessServiceFactory() );
92 [ - + ]: 158 : if (!xServiceFactory.is())
93 : : {
94 : : OSL_FAIL("configureUcb(): No XMultiServiceFactory");
95 : 0 : return false;
96 : : }
97 : :
98 : 158 : rtl::OUString aPipe;
99 [ + - ][ + - ]: 158 : osl::Security().getUserIdent(aPipe);
[ + - ]
100 : :
101 : 158 : rtl::OUStringBuffer aPortal;
102 : :
103 [ + - ]: 158 : Sequence< Any > aArgs(2);
104 [ + - ]: 158 : aArgs[0]
105 [ + - ]: 316 : <<= rtl::OUString(UCB_CONFIGURATION_KEY1_LOCAL);
106 [ + - ]: 158 : aArgs[1]
107 [ + - ]: 316 : <<= rtl::OUString(UCB_CONFIGURATION_KEY2_OFFICE);
108 : :
109 : : bool ret =
110 [ + - ]: 158 : ::ucbhelper::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
111 : :
112 : : #ifdef GNOME_VFS_ENABLED
113 : : // register GnomeUCP if necessary
114 [ + - ]: 158 : ::ucbhelper::ContentBroker* cb = ::ucbhelper::ContentBroker::get();
115 [ + - ]: 158 : if(cb)
116 : : {
117 : : try
118 : : {
119 : : Reference< XCurrentContext > xCurrentContext(
120 [ + - ]: 158 : getCurrentContext());
121 [ + - ]: 158 : if (xCurrentContext.is())
122 : : {
123 [ + - ]: 158 : Any aValue = xCurrentContext->getValueByName(
124 : : rtl::OUString( "system.desktop-environment" )
125 [ + - ]: 158 : );
126 : 158 : rtl::OUString aDesktopEnvironment;
127 [ - + ][ - + ]: 158 : if ( (aValue >>= aDesktopEnvironment) && aDesktopEnvironment == "GNOME" )
[ + - ]
128 : : {
129 : : Reference<XContentProviderManager> xCPM =
130 [ # # ]: 0 : cb->getContentProviderManagerInterface();
131 : :
132 : :
133 : : //Instanciate GNOME-VFS-UCP in the thread that initialized
134 : : // GNOME in order to avoid a deadlock that may occure in case UCP gets initialized from
135 : : // a different thread. The latter may happen when calling the Office remotely via UNO.
136 : : // THIS IS NOT A FIX, JUST A WORKAROUND!
137 : :
138 : : try
139 : : {
140 : : Reference<XContentProvider> xCP(
141 [ # # ]: 0 : xServiceFactory->createInstance(
142 : : rtl::OUString(
143 : 0 : "com.sun.star.ucb.GnomeVFSContentProvider")),
144 [ # # ][ # # ]: 0 : UNO_QUERY);
145 [ # # ]: 0 : if(xCP.is())
146 [ # # ]: 0 : xCPM->registerContentProvider(
147 : : xCP,
148 : : rtl::OUString(".*"),
149 [ # # ]: 0 : false);
150 : : }
151 [ # # ]: 0 : catch (...)
152 : : {
153 : 0 : }
154 : 158 : }
155 [ # # ]: 158 : }
156 : : }
157 [ # # ]: 0 : catch (const RuntimeException &)
158 : : {
159 : : }
160 : : }
161 : : #endif // GNOME_VFS_ENABLED
162 : :
163 [ + - ]: 158 : return ret;
164 : : }
165 : :
166 : 158 : Reference< XMultiServiceFactory > Desktop::CreateApplicationServiceManager()
167 : : {
168 : : RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );
169 : :
170 : : #ifdef ANDROID
171 : : rtl::OUString aUnoRc( OUString( "file:///assets/program/unorc" ) );
172 : : return Reference<XMultiServiceFactory>(
173 : : cppu::defaultBootstrap_InitialComponentContext( aUnoRc )->getServiceManager(),
174 : : UNO_QUERY_THROW);
175 : : #else
176 : : return Reference<XMultiServiceFactory>(
177 [ + - ]: 316 : cppu::defaultBootstrap_InitialComponentContext()->getServiceManager(),
178 [ + - ][ + - ]: 316 : UNO_QUERY_THROW);
179 : : #endif
180 : : }
181 : :
182 : 158 : void Desktop::DestroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
183 : : {
184 [ + - ]: 158 : Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
185 [ + - ]: 158 : if ( xProps.is() )
186 : : {
187 : : try
188 : : {
189 : 158 : Reference< XComponent > xComp;
190 [ + - ][ + - ]: 158 : if (xProps->getPropertyValue( OUString( "DefaultContext" )) >>= xComp )
[ + - ][ + - ]
191 : : {
192 [ + - ][ + - ]: 158 : xComp->dispose();
193 [ # # ]: 158 : }
194 : : }
195 [ # # ]: 0 : catch (const UnknownPropertyException&)
196 : : {
197 : : }
198 : 158 : }
199 : 158 : }
200 : :
201 : 158 : void Desktop::RegisterServices()
202 : : {
203 [ + - ]: 158 : if( !m_bServicesRegistered )
204 : : {
205 : : RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );
206 : :
207 : : // read command line parameters
208 : 158 : sal_Bool bHeadlessMode = sal_False;
209 : :
210 : : // interpret command line arguments
211 [ + - ]: 158 : CommandLineArgs& rCmdLine = GetCommandLineArgs();
212 : :
213 : : // Headless mode for FAT Office
214 [ + - ]: 158 : bHeadlessMode = rCmdLine.IsHeadless();
215 [ + - ]: 158 : if ( bHeadlessMode )
216 [ + - ]: 158 : Application::EnableHeadlessMode(false);
217 : :
218 : : // read accept string from configuration
219 [ + - ][ + - ]: 158 : rtl::OUString conDcpCfg(SvtStartOptions().GetConnectionURL());
[ + - ]
220 [ - + ]: 158 : if (!conDcpCfg.isEmpty()) {
221 [ # # ]: 0 : createAcceptor(conDcpCfg);
222 : : }
223 : :
224 [ + - ]: 158 : std::vector< ::rtl::OUString > const & conDcp = rCmdLine.GetAccept();
225 [ + - ][ + + ]: 632 : for (std::vector< ::rtl::OUString >::const_iterator i(conDcp.begin());
226 : 316 : i != conDcp.end(); ++i)
227 : : {
228 [ + - ]: 158 : createAcceptor(*i);
229 : : }
230 : :
231 [ + - ][ - + ]: 158 : if ( !configureUcb() )
232 : : {
233 : : OSL_FAIL( "Can't configure UCB" );
234 [ # # ][ # # ]: 0 : throw com::sun::star::uno::Exception(rtl::OUString("RegisterServices, configureUcb"), NULL);
235 : : }
236 : :
237 [ + - ]: 158 : CreateTemporaryDirectory();
238 : 158 : m_bServicesRegistered = true;
239 : : }
240 : 158 : }
241 : :
242 : : namespace
243 : : {
244 : : struct acceptorMap : public rtl::Static< AcceptorMap, acceptorMap > {};
245 : : struct CurrentTempURL : public rtl::Static< String, CurrentTempURL > {};
246 : : }
247 : :
248 : : static sal_Bool bAccept = sal_False;
249 : :
250 : 158 : void Desktop::createAcceptor(const OUString& aAcceptString)
251 : : {
252 : : // check whether the requested acceptor already exists
253 [ + - ]: 158 : AcceptorMap &rMap = acceptorMap::get();
254 [ + - ]: 158 : AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
255 [ + - ]: 158 : if (pIter == rMap.end() )
256 : : {
257 [ + - ]: 158 : Sequence< Any > aSeq( 2 );
258 [ + - ][ + - ]: 158 : aSeq[0] <<= aAcceptString;
259 [ + - ][ + - ]: 158 : aSeq[1] <<= bAccept;
260 : : Reference<XInitialization> rAcceptor(
261 [ + - ][ + - ]: 316 : ::comphelper::getProcessServiceFactory()->createInstance(
262 [ + - ][ + - ]: 158 : OUString("com.sun.star.office.Acceptor" )), UNO_QUERY );
263 [ + - ]: 158 : if ( rAcceptor.is() )
264 : : {
265 : : try
266 : : {
267 [ + - ][ + - ]: 158 : rAcceptor->initialize( aSeq );
268 [ + - ][ + - ]: 158 : rMap.insert(AcceptorMap::value_type(aAcceptString, rAcceptor));
[ + - ][ # # ]
269 : : }
270 [ # # ]: 0 : catch (const com::sun::star::uno::Exception&)
271 : : {
272 : : // no error handling needed...
273 : : // acceptor just won't come up
274 : : OSL_FAIL("Acceptor could not be created.");
275 : : }
276 : : }
277 : : else
278 : : {
279 : : // there is already an acceptor with this description
280 : : OSL_FAIL("Acceptor already exists.");
281 [ + - ]: 158 : }
282 : : }
283 : 158 : }
284 : :
285 : 288 : class enable
286 : : {
287 : : private:
288 : : Sequence<Any> m_aSeq;
289 : : public:
290 : 96 : enable() : m_aSeq(1) {
291 [ + - ][ + - ]: 96 : m_aSeq[0] <<= sal_True;
292 : 96 : }
293 : 96 : void operator() (const AcceptorMap::value_type& val) {
294 [ + - ]: 96 : if (val.second.is()) {
295 : 96 : val.second->initialize(m_aSeq);
296 : : }
297 : 96 : }
298 : : };
299 : :
300 : 96 : void Desktop::enableAcceptors()
301 : : {
302 : : RTL_LOGFILE_CONTEXT(aLog, "desktop (lo119109) Desktop::enableAcceptors");
303 [ + - ]: 96 : if (!bAccept)
304 : : {
305 : : // from now on, all new acceptors are enabled
306 : 96 : bAccept = sal_True;
307 : : // enable existing acceptors by calling initialize(true)
308 : : // on all existing acceptors
309 : 96 : AcceptorMap &rMap = acceptorMap::get();
310 [ + - ][ + - ]: 96 : std::for_each(rMap.begin(), rMap.end(), enable());
311 : : }
312 : 96 : }
313 : :
314 : 0 : void Desktop::destroyAcceptor(const OUString& aAcceptString)
315 : : {
316 : : // special case stop all acceptors
317 : 0 : AcceptorMap &rMap = acceptorMap::get();
318 [ # # ]: 0 : if (aAcceptString.compareToAscii("all") == 0) {
319 : 0 : rMap.clear();
320 : :
321 : : } else {
322 : : // try to remove acceptor from map
323 [ # # ]: 0 : AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
324 [ # # ]: 0 : if (pIter != rMap.end() ) {
325 : : // remove reference from map
326 : : // this is the last reference and the acceptor will be destructed
327 [ # # ]: 0 : rMap.erase(aAcceptString);
328 : : } else {
329 : : OSL_FAIL("Found no acceptor to remove");
330 : : }
331 : : }
332 : 0 : }
333 : :
334 : :
335 : 158 : void Desktop::DeregisterServices()
336 : : {
337 : : // stop all acceptors by clearing the map
338 : 158 : acceptorMap::get().clear();
339 : 158 : }
340 : :
341 : 158 : void Desktop::CreateTemporaryDirectory()
342 : : {
343 : : RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );
344 : :
345 : 158 : ::rtl::OUString aTempBaseURL;
346 : : try
347 : : {
348 [ + - ]: 158 : SvtPathOptions aOpt;
349 [ + - ][ + - ]: 158 : aTempBaseURL = aOpt.GetTempPath();
[ + - ]
350 : : }
351 [ # # ]: 0 : catch (RuntimeException& e)
352 : : {
353 : : // Catch runtime exception here: We have to add language dependent info
354 : : // to the exception message. Fallback solution uses hard coded string.
355 : 0 : OUString aMsg;
356 [ # # ]: 0 : DesktopResId aResId( STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE );
357 : 0 : aResId.SetRT( RSC_STRING );
358 [ # # # # ]: 0 : if ( aResId.GetResMgr()->IsAvailable( aResId ))
359 [ # # # # : 0 : aMsg = String( aResId );
# # ]
360 : : else
361 : 0 : aMsg = OUString( "The path manager is not available.\n" );
362 : 0 : e.Message = aMsg + e.Message;
363 : 0 : throw;
364 : : }
365 : :
366 : : // remove possible old directory and base directory
367 [ + - ]: 158 : SvtInternalOptions aInternalOpt;
368 : :
369 : : // set temp base directory
370 : 158 : sal_Int32 nLength = aTempBaseURL.getLength();
371 [ - + ]: 158 : if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
372 : 0 : aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
373 : :
374 [ + - ][ + - ]: 158 : String aOldTempURL = aInternalOpt.GetCurrentTempURL();
375 [ - + ]: 158 : if ( aOldTempURL.Len() > 0 )
376 : : {
377 : : // remove old temporary directory
378 [ # # ][ # # ]: 0 : ::utl::UCBContentHelper::Kill( aOldTempURL );
379 : : }
380 : :
381 : 158 : ::rtl::OUString aRet;
382 : 158 : ::rtl::OUString aTempPath( aTempBaseURL );
383 : :
384 : : // create new current temporary directory
385 [ + - ]: 158 : ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
386 [ + - ]: 158 : ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
387 [ + - ][ + - ]: 158 : aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
[ + - ][ + - ]
[ + - ]
388 [ - + ]: 158 : if ( aTempPath.isEmpty() )
389 : : {
390 [ # # ]: 0 : ::osl::File::getTempDirURL( aTempBaseURL );
391 : :
392 : 0 : nLength = aTempBaseURL.getLength();
393 [ # # ]: 0 : if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
394 : 0 : aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
395 : :
396 : 0 : aTempPath = aTempBaseURL;
397 [ # # ]: 0 : ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
398 [ # # ][ # # ]: 0 : aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
[ # # ][ # # ]
[ # # ]
399 : : }
400 : :
401 : : // set new current temporary directory
402 [ + - ]: 158 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
403 [ + - ]: 158 : aInternalOpt.SetCurrentTempURL( aRet );
404 [ + - ][ + - ]: 158 : CurrentTempURL::get() = aRet;
[ + - ][ + - ]
405 : 158 : }
406 : :
407 : 158 : void Desktop::RemoveTemporaryDirectory()
408 : : {
409 : : RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );
410 : :
411 : : // remove current temporary directory
412 : 158 : String &rCurrentTempURL = CurrentTempURL::get();
413 [ + - ]: 158 : if ( rCurrentTempURL.Len() > 0 )
414 : : {
415 [ + - ][ + - ]: 158 : if ( ::utl::UCBContentHelper::Kill( rCurrentTempURL ) )
416 [ + - ][ + - ]: 158 : SvtInternalOptions().SetCurrentTempURL( String() );
[ + - ][ + - ]
417 : : }
418 : 158 : }
419 : :
420 : : } // namespace desktop
421 : :
422 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|