Update ooo320-m1
[ooovba.git] / desktop / source / app / appinit.cxx
blob23f6263bf799ce6c36e5305e1261d780ab753007
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: appinit.cxx,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include <algorithm>
36 #include "app.hxx"
37 #include "cmdlineargs.hxx"
38 #include "desktopresid.hxx"
39 #include "desktop.hrc"
40 #include <com/sun/star/registry/XSimpleRegistry.hpp>
41 #include <com/sun/star/lang/XComponent.hpp>
42 #include <com/sun/star/lang/XInitialization.hpp>
43 #include <com/sun/star/uno/Exception.hpp>
44 #include <com/sun/star/uno/XCurrentContext.hpp>
45 #include <com/sun/star/packages/zip/ZipIOException.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
50 #include <com/sun/star/ucb/XContentProviderManager.hpp>
51 #include <com/sun/star/ucb/XContentProviderFactory.hpp>
52 #include <uno/current_context.hxx>
53 #include <cppuhelper/servicefactory.hxx>
54 #include <cppuhelper/bootstrap.hxx>
55 #include <osl/file.hxx>
56 #include <osl/module.h>
57 #include <vos/process.hxx>
58 #include <rtl/uri.hxx>
59 #include <rtl/ustrbuf.hxx>
60 #include <rtl/bootstrap.hxx>
61 #include <comphelper/regpathhelper.hxx>
62 #include <tools/debug.hxx>
63 #include <tools/tempfile.hxx>
64 #include <ucbhelper/configurationkeys.hxx>
66 #include <cppuhelper/bootstrap.hxx>
67 #include <tools/urlobj.hxx>
68 #include <tools/rcid.h>
70 #include <rtl/logfile.hxx>
71 #include <rtl/instance.hxx>
72 #include <comphelper/processfactory.hxx>
73 #include <unotools/localfilehelper.hxx>
74 #include <unotools/ucbhelper.hxx>
75 #include <unotools/tempfile.hxx>
76 #include <ucbhelper/contentbroker.hxx>
77 #include <vcl/svapp.hxx>
78 #include <svtools/startoptions.hxx>
79 #include <svtools/pathoptions.hxx>
80 #include <svtools/internaloptions.hxx>
83 #define DEFINE_CONST_OUSTRING(CONSTASCII) OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
85 #define DESKTOP_TEMPDIRNAME "soffice.tmp"
87 using namespace rtl;
88 using namespace vos;
89 using namespace desktop;
90 using namespace ::com::sun::star::uno;
91 using namespace ::com::sun::star::lang;
92 using namespace ::com::sun::star::beans;
93 using namespace ::com::sun::star::registry;
94 using namespace ::com::sun::star::ucb;
96 namespace desktop
99 // -----------------------------------------------------------------------------
101 static bool configureUcb(bool bServer, rtl::OUString const & rPortalConnect)
103 RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
104 Reference< XMultiServiceFactory >
105 xServiceFactory( comphelper::getProcessServiceFactory() );
106 if (!xServiceFactory.is())
108 DBG_ERROR("configureUcb(): No XMultiServiceFactory");
109 return false;
112 rtl::OUString aPipe;
113 vos::OSecurity().getUserIdent(aPipe);
115 rtl::OUStringBuffer aPortal;
116 if (rPortalConnect.getLength() != 0)
118 aPortal.append(sal_Unicode(','));
119 aPortal.append(rPortalConnect);
122 Sequence< Any > aArgs(6);
123 aArgs[0]
124 <<= rtl::OUString::createFromAscii(bServer ?
125 UCB_CONFIGURATION_KEY1_SERVER :
126 UCB_CONFIGURATION_KEY1_LOCAL);
127 aArgs[1]
128 <<= rtl::OUString::createFromAscii(UCB_CONFIGURATION_KEY2_OFFICE);
129 aArgs[2] <<= rtl::OUString::createFromAscii("PIPE");
130 aArgs[3] <<= aPipe;
131 aArgs[4] <<= rtl::OUString::createFromAscii("PORTAL");
132 aArgs[5] <<= aPortal.makeStringAndClear();
134 bool ret =
135 ::ucbhelper::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
137 #ifdef GNOME_VFS_ENABLED
138 // register GnomeUCP if necessary
139 ::ucbhelper::ContentBroker* cb = ::ucbhelper::ContentBroker::get();
140 if(cb) {
141 try {
142 Reference< XCurrentContext > xCurrentContext(
143 getCurrentContext());
144 if (xCurrentContext.is())
146 Any aValue = xCurrentContext->getValueByName(
147 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
148 "system.desktop-environment" ) )
150 rtl::OUString aDesktopEnvironment;
151 if ((aValue >>= aDesktopEnvironment)
152 && (aDesktopEnvironment.equalsAscii("GNOME") ||
153 aDesktopEnvironment.equalsAscii("KDE")))
155 Reference<XContentProviderManager> xCPM =
156 cb->getContentProviderManagerInterface();
161 Reference<XContentProviderFactory> xCPF(
162 xServiceFactory->createInstance(
163 rtl::OUString::createFromAscii(
164 "com.sun.star.ucb.ContentProviderProxyFactory")),
165 UNO_QUERY);
166 if(xCPF.is())
167 xCPM->registerContentProvider(
168 xCPF->createContentProvider(
169 rtl::OUString::createFromAscii(
170 "com.sun.star.ucb.GnomeVFSContentProvider"
173 rtl::OUString::createFromAscii(".*"),
174 false);
175 } catch (...)
180 } catch (RuntimeException e) {
183 #endif // GNOME_VFS_ENABLED
185 return ret;;
188 Reference< XMultiServiceFactory > Desktop::CreateApplicationServiceManager()
190 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );
194 Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
195 Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);
197 return xMS;
199 catch( ::com::sun::star::uno::Exception& )
203 return Reference< XMultiServiceFactory >();
206 void Desktop::DestroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
208 Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
209 if ( xProps.is() )
213 Reference< XComponent > xComp;
214 if (xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp )
216 xComp->dispose();
219 catch ( UnknownPropertyException& )
225 void Desktop::RegisterServices( Reference< XMultiServiceFactory >& xSMgr )
227 if( !m_bServicesRegistered )
229 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );
231 // read command line parameters
232 ::rtl::OUString conDcp;
233 ::rtl::OUString aClientDisplay;
234 ::rtl::OUString aTmpString;
235 sal_Bool bHeadlessMode = sal_False;
237 // interpret command line arguments
238 CommandLineArgs* pCmdLine = GetCommandLineArgs();
240 // read accept string from configuration
241 conDcp = SvtStartOptions().GetConnectionURL();
243 if ( pCmdLine->GetAcceptString( aTmpString ))
244 conDcp = aTmpString;
246 // Headless mode for FAT Office
247 bHeadlessMode = pCmdLine->IsHeadless();
248 if ( bHeadlessMode )
249 Application::EnableHeadlessMode();
251 if ( conDcp.getLength() > 0 )
253 // accept incoming connections (scripting and one rvp)
254 RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) desktop::Desktop::createAcceptor()" );
255 createAcceptor(conDcp);
258 // improves parallel processing on Sun ONE Webtop
259 // servicemanager up -> copy user installation
260 if ( pCmdLine->IsServer() )
262 // Check some mandatory environment states if "-server" is possible. Otherwise ignore
263 // this parameter.
264 Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
265 if( rContent.is() )
267 OUString sPortalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.portal.InstallUser" ) );
268 Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sPortalService );
269 if ( !rEnum.is() )
271 // Reset server parameter so it is ignored in the furthermore startup process
272 pCmdLine->SetBoolParam( CommandLineArgs::CMD_BOOLPARAM_SERVER, sal_False );
277 ::rtl::OUString aPortalConnect;
278 bool bServer = (bool)pCmdLine->IsServer();
280 pCmdLine->GetPortalConnectString( aPortalConnect );
281 if ( !configureUcb( bServer, aPortalConnect ) )
283 DBG_ERROR( "Can't configure UCB" );
284 throw com::sun::star::uno::Exception(rtl::OUString::createFromAscii("RegisterServices, configureUcb"), NULL);
287 CreateTemporaryDirectory();
288 m_bServicesRegistered = true;
292 namespace
294 struct acceptorMap : public rtl::Static< AcceptorMap, acceptorMap > {};
295 struct mtxAccMap : public rtl::Static< osl::Mutex, mtxAccMap > {};
296 struct CurrentTempURL : public rtl::Static< String, CurrentTempURL > {};
299 static sal_Bool bAccept = sal_False;
301 void Desktop::createAcceptor(const OUString& aAcceptString)
303 // make sure nobody adds an acceptor whle we create one...
304 osl::MutexGuard aGuard(mtxAccMap::get());
305 // check whether the requested acceptor already exists
306 AcceptorMap &rMap = acceptorMap::get();
307 AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
308 if (pIter == rMap.end() ) {
310 Sequence< Any > aSeq( 2 );
311 aSeq[0] <<= aAcceptString;
312 aSeq[1] <<= bAccept;
313 Reference<XInitialization> rAcceptor(
314 ::comphelper::getProcessServiceFactory()->createInstance(
315 OUString::createFromAscii( "com.sun.star.office.Acceptor" )), UNO_QUERY );
316 if ( rAcceptor.is() ) {
317 try{
318 rAcceptor->initialize( aSeq );
319 rMap.insert(AcceptorMap::value_type(aAcceptString, rAcceptor));
320 } catch (com::sun::star::uno::Exception&) {
321 // no error handling needed...
322 // acceptor just won't come up
323 OSL_ENSURE(sal_False, "Acceptor could not be created.");
325 } else {
326 // there is already an acceptor with this description
327 OSL_ENSURE(sal_False, "Acceptor already exists.");
333 class enable
335 private:
336 Sequence<Any> m_aSeq;
337 public:
338 enable() : m_aSeq(1) {
339 m_aSeq[0] <<= sal_True;
341 void operator() (const AcceptorMap::value_type& val) {
342 if (val.second.is()) {
343 val.second->initialize(m_aSeq);
348 void Desktop::enableAcceptors()
350 RTL_LOGFILE_CONTEXT(aLog, "desktop (lo119109) Desktop::enableAcceptors");
351 osl::MutexGuard aGuard(mtxAccMap::get());
352 if (!bAccept)
354 // from now on, all new acceptors are enabled
355 bAccept = sal_True;
356 // enable existing acceptors by calling initialize(true)
357 // on all existing acceptors
358 AcceptorMap &rMap = acceptorMap::get();
359 std::for_each(rMap.begin(), rMap.end(), enable());
363 void Desktop::destroyAcceptor(const OUString& aAcceptString)
365 osl::MutexGuard aGuard(mtxAccMap::get());
366 // special case stop all acceptors
367 AcceptorMap &rMap = acceptorMap::get();
368 if (aAcceptString.compareToAscii("all") == 0) {
369 rMap.clear();
371 } else {
372 // try to remove acceptor from map
373 AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
374 if (pIter != rMap.end() ) {
375 // remove reference from map
376 // this is the last reference and the acceptor will be destructed
377 rMap.erase(aAcceptString);
378 } else {
379 OSL_ENSURE(sal_False, "Found no acceptor to remove");
385 void Desktop::DeregisterServices()
387 // stop all acceptors by clearing the map
388 acceptorMap::get().clear();
391 void Desktop::CreateTemporaryDirectory()
393 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );
395 ::rtl::OUString aTempBaseURL;
398 SvtPathOptions aOpt;
399 aTempBaseURL = aOpt.GetTempPath();
401 catch ( RuntimeException& e )
403 // Catch runtime exception here: We have to add language dependent info
404 // to the exception message. Fallback solution uses hard coded string.
405 OUString aMsg;
406 DesktopResId aResId( STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE );
407 aResId.SetRT( RSC_STRING );
408 if ( aResId.GetResMgr()->IsAvailable( aResId ))
409 aMsg = String( aResId );
410 else
411 aMsg = OUString( RTL_CONSTASCII_USTRINGPARAM( "The path manager is not available.\n" ));
412 e.Message = aMsg + e.Message;
413 throw e;
416 // remove possible old directory and base directory
417 SvtInternalOptions aInternalOpt;
419 // set temp base directory
420 sal_Int32 nLength = aTempBaseURL.getLength();
421 if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
422 aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
424 String aOldTempURL = aInternalOpt.GetCurrentTempURL();
425 if ( aOldTempURL.Len() > 0 )
427 // remove old temporary directory
428 ::utl::UCBContentHelper::Kill( aOldTempURL );
431 String aRet;
432 ::rtl::OUString aTempPath( aTempBaseURL );
434 // create new current temporary directory
435 ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
436 ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
437 aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
438 if ( !aTempPath.getLength() )
440 ::osl::File::getTempDirURL( aTempBaseURL );
442 nLength = aTempBaseURL.getLength();
443 if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
444 aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
446 aTempPath = aTempBaseURL;
447 ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
448 aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
451 // set new current temporary directory
452 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
453 aInternalOpt.SetCurrentTempURL( aRet );
454 CurrentTempURL::get() = aRet;
457 void Desktop::RemoveTemporaryDirectory()
459 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );
461 // remove current temporary directory
462 String &rCurrentTempURL = CurrentTempURL::get();
463 if ( rCurrentTempURL.Len() > 0 )
465 if ( ::utl::UCBContentHelper::Kill( rCurrentTempURL ) )
466 SvtInternalOptions().SetCurrentTempURL( String() );
470 } // namespace desktop