1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: appinit.cxx,v $
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"
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"
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
;
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");
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);
124 <<= rtl::OUString::createFromAscii(bServer
?
125 UCB_CONFIGURATION_KEY1_SERVER
:
126 UCB_CONFIGURATION_KEY1_LOCAL
);
128 <<= rtl::OUString::createFromAscii(UCB_CONFIGURATION_KEY2_OFFICE
);
129 aArgs
[2] <<= rtl::OUString::createFromAscii("PIPE");
131 aArgs
[4] <<= rtl::OUString::createFromAscii("PORTAL");
132 aArgs
[5] <<= aPortal
.makeStringAndClear();
135 ::ucbhelper::ContentBroker::initialize( xServiceFactory
, aArgs
) != false;
137 #ifdef GNOME_VFS_ENABLED
138 // register GnomeUCP if necessary
139 ::ucbhelper::ContentBroker
* cb
= ::ucbhelper::ContentBroker::get();
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")),
167 xCPM
->registerContentProvider(
168 xCPF
->createContentProvider(
169 rtl::OUString::createFromAscii(
170 "com.sun.star.ucb.GnomeVFSContentProvider"
173 rtl::OUString::createFromAscii(".*"),
180 } catch (RuntimeException e
) {
183 #endif // GNOME_VFS_ENABLED
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
);
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
);
213 Reference
< XComponent
> xComp
;
214 if (xProps
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp
)
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
))
246 // Headless mode for FAT Office
247 bHeadlessMode
= pCmdLine
->IsHeadless();
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
264 Reference
< com::sun::star::container::XContentEnumerationAccess
> rContent( xSMgr
, UNO_QUERY
);
267 OUString sPortalService
= OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.portal.InstallUser" ) );
268 Reference
< com::sun::star::container::XEnumeration
> rEnum
= rContent
->createContentEnumeration( sPortalService
);
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;
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
;
313 Reference
<XInitialization
> rAcceptor(
314 ::comphelper::getProcessServiceFactory()->createInstance(
315 OUString::createFromAscii( "com.sun.star.office.Acceptor" )), UNO_QUERY
);
316 if ( rAcceptor
.is() ) {
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.");
326 // there is already an acceptor with this description
327 OSL_ENSURE(sal_False
, "Acceptor already exists.");
336 Sequence
<Any
> m_aSeq
;
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());
354 // from now on, all new acceptors are enabled
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) {
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
);
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
;
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.
406 DesktopResId
aResId( STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE
);
407 aResId
.SetRT( RSC_STRING
);
408 if ( aResId
.GetResMgr()->IsAvailable( aResId
))
409 aMsg
= String( aResId
);
411 aMsg
= OUString( RTL_CONSTASCII_USTRINGPARAM( "The path manager is not available.\n" ));
412 e
.Message
= aMsg
+ e
.Message
;
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
);
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