1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "dp_component.hrc"
22 #include "dp_backend.h"
23 #include "dp_platform.hxx"
25 #include "rtl/string.hxx"
26 #include "rtl/strbuf.hxx"
27 #include "rtl/ustrbuf.hxx"
28 #include "rtl/uri.hxx"
29 #include "cppuhelper/exc_hlp.hxx"
30 #include "ucbhelper/content.hxx"
31 #include "comphelper/anytostring.hxx"
32 #include "comphelper/servicedecl.hxx"
33 #include "comphelper/sequence.hxx"
34 #include "xmlscript/xml_helper.hxx"
35 #include "svl/inettype.hxx"
36 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
37 #include "com/sun/star/container/XNameContainer.hpp"
38 #include "com/sun/star/container/XSet.hpp"
39 #include "com/sun/star/registry/XSimpleRegistry.hpp"
40 #include "com/sun/star/registry/XImplementationRegistration.hpp"
41 #include "com/sun/star/loader/XImplementationLoader.hpp"
42 #include "com/sun/star/io/XInputStream.hpp"
43 #include "com/sun/star/ucb/NameClash.hpp"
44 #include "com/sun/star/util/theMacroExpander.hpp"
46 #include <boost/unordered_map.hpp>
50 #include "dp_compbackenddb.hxx"
52 using namespace ::dp_misc
;
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::ucb
;
57 namespace dp_registry
{
62 typedef ::std::list
<OUString
> t_stringlist
;
63 typedef ::std::vector
< ::std::pair
<OUString
, OUString
> > t_stringpairvec
;
65 #define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
67 /** return a vector of bootstrap variables which have been provided
70 ::std::vector
<OUString
> getCmdBootstrapVariables()
72 ::std::vector
<OUString
> ret
;
73 sal_uInt32 count
= osl_getCommandArgCount();
74 for (sal_uInt32 i
= 0; i
< count
; i
++)
77 osl_getCommandArg(i
, &arg
.pData
);
78 if (arg
.match("-env:"))
84 bool jarManifestHeaderPresent(
85 OUString
const & url
, OUString
const & name
,
86 Reference
<XCommandEnvironment
> const & xCmdEnv
)
89 buf
.appendAscii( "vnd.sun.star.zip://" );
92 url
, rtl_UriCharClassRegName
, rtl_UriEncodeIgnoreEscapes
,
93 RTL_TEXTENCODING_UTF8
) );
94 buf
.appendAscii( "/META-INF/MANIFEST.MF" );
95 ::ucbhelper::Content manifestContent
;
99 &manifestContent
, buf
.makeStringAndClear(), xCmdEnv
,
100 false /* no throw */ )
101 && readLine( &line
, name
, manifestContent
, RTL_TEXTENCODING_ASCII_US
);
104 //==============================================================================
105 class BackendImpl
: public ::dp_registry::backend::PackageRegistryBackend
107 class ComponentPackageImpl
: public ::dp_registry::backend::Package
109 BackendImpl
* getMyBackend() const;
111 const OUString m_loader
;
114 REG_UNINIT
, REG_VOID
, REG_REGISTERED
, REG_NOT_REGISTERED
, REG_MAYBE_REGISTERED
117 void getComponentInfo(
118 ComponentBackendDb::Data
* data
,
119 std::vector
< css::uno::Reference
< css::uno::XInterface
> > *
121 Reference
<XComponentContext
> const & xContext
);
123 void componentLiveInsertion(
124 ComponentBackendDb::Data
const & data
,
125 std::vector
< css::uno::Reference
< css::uno::XInterface
> > const &
128 void componentLiveRemoval(ComponentBackendDb::Data
const & data
);
130 virtual void SAL_CALL
disposing();
133 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
134 ::osl::ResettableMutexGuard
& guard
,
135 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
136 Reference
<XCommandEnvironment
> const & xCmdEnv
);
137 virtual void processPackage_(
138 ::osl::ResettableMutexGuard
& guard
,
139 bool registerPackage
,
141 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
142 Reference
<XCommandEnvironment
> const & xCmdEnv
);
144 const Reference
<registry::XSimpleRegistry
> getRDB() const;
147 ComponentPackageImpl(
148 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
149 OUString
const & url
, OUString
const & name
,
150 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
151 OUString
const & loader
, bool bRemoved
,
152 OUString
const & identifier
);
154 friend class ComponentPackageImpl
;
156 class ComponentsPackageImpl
: public ::dp_registry::backend::Package
158 BackendImpl
* getMyBackend() const;
161 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
162 ::osl::ResettableMutexGuard
& guard
,
163 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
164 Reference
<XCommandEnvironment
> const & xCmdEnv
);
165 virtual void processPackage_(
166 ::osl::ResettableMutexGuard
& guard
,
167 bool registerPackage
,
169 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
170 Reference
<XCommandEnvironment
> const & xCmdEnv
);
172 ComponentsPackageImpl(
173 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
174 OUString
const & url
, OUString
const & name
,
175 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
176 bool bRemoved
, OUString
const & identifier
);
178 friend class ComponentsPackageImpl
;
180 class TypelibraryPackageImpl
: public ::dp_registry::backend::Package
182 BackendImpl
* getMyBackend() const;
184 const bool m_jarFile
;
186 virtual void SAL_CALL
disposing();
189 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
190 ::osl::ResettableMutexGuard
& guard
,
191 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
192 Reference
<XCommandEnvironment
> const & xCmdEnv
);
193 virtual void processPackage_(
194 ::osl::ResettableMutexGuard
& guard
,
195 bool registerPackage
,
197 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
198 Reference
<XCommandEnvironment
> const & xCmdEnv
);
201 TypelibraryPackageImpl(
202 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
203 OUString
const & url
, OUString
const & name
,
204 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
205 bool jarFile
, bool bRemoved
,
206 OUString
const & identifier
);
208 friend class TypelibraryPackageImpl
;
210 /** Serves for unregistering packages that were registered on a
211 different platform. This can happen if one has remotely mounted
214 class OtherPlatformPackageImpl
: public ::dp_registry::backend::Package
217 OtherPlatformPackageImpl(
218 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
219 OUString
const & url
, OUString
const & name
,
220 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
221 bool bRemoved
, OUString
const & identifier
, OUString
const& rPlatform
);
224 BackendImpl
* getMyBackend() const;
226 const Reference
<registry::XSimpleRegistry
> impl_openRDB() const;
227 const Reference
<XInterface
> impl_createInstance(OUString
const& rService
) const;
230 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
231 ::osl::ResettableMutexGuard
& guard
,
232 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
233 Reference
<XCommandEnvironment
> const & xCmdEnv
);
234 virtual void processPackage_(
235 ::osl::ResettableMutexGuard
& guard
,
236 bool registerPackage
,
238 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
239 Reference
<XCommandEnvironment
> const & xCmdEnv
);
242 OUString
const m_aPlatform
;
244 friend class OtherPlatformPackageImpl
;
246 t_stringlist m_jar_typelibs
;
247 t_stringlist m_rdb_typelibs
;
248 t_stringlist m_components
;
250 enum RcItem
{ RCITEM_JAR_TYPELIB
, RCITEM_RDB_TYPELIB
, RCITEM_COMPONENTS
};
252 t_stringlist
& getRcItemList( RcItem kind
) {
255 case RCITEM_JAR_TYPELIB
:
256 return m_jar_typelibs
;
257 case RCITEM_RDB_TYPELIB
:
258 return m_rdb_typelibs
;
259 default: // case RCITEM_COMPONENTS
265 bool m_unorc_modified
;
266 bool bSwitchedRdbFiles
;
268 typedef ::boost::unordered_map
< OUString
, Reference
<XInterface
>,
269 OUStringHash
> t_string2object
;
270 t_string2object m_backendObjects
;
272 // PackageRegistryBackend
273 virtual Reference
<deployment::XPackage
> bindPackage_(
274 OUString
const & url
, OUString
const & mediaType
,
275 sal_Bool bRemoved
, OUString
const & identifier
,
276 Reference
<XCommandEnvironment
> const & xCmdEnv
);
278 virtual void SAL_CALL
disposing();
280 const Reference
<deployment::XPackageTypeInfo
> m_xDynComponentTypeInfo
;
281 const Reference
<deployment::XPackageTypeInfo
> m_xJavaComponentTypeInfo
;
282 const Reference
<deployment::XPackageTypeInfo
> m_xPythonComponentTypeInfo
;
283 const Reference
<deployment::XPackageTypeInfo
> m_xComponentsTypeInfo
;
284 const Reference
<deployment::XPackageTypeInfo
> m_xRDBTypelibTypeInfo
;
285 const Reference
<deployment::XPackageTypeInfo
> m_xJavaTypelibTypeInfo
;
286 Sequence
< Reference
<deployment::XPackageTypeInfo
> > m_typeInfos
;
288 OUString m_commonRDB
;
289 OUString m_nativeRDB
;
291 //URLs of the original rdbs (before any switching):
292 OUString m_commonRDB_orig
;
293 OUString m_nativeRDB_orig
;
295 std::auto_ptr
<ComponentBackendDb
> m_backendDb
;
297 void addDataToDb(OUString
const & url
, ComponentBackendDb::Data
const & data
);
298 ComponentBackendDb::Data
readDataFromDb(OUString
const & url
);
299 void revokeEntryFromDb(OUString
const & url
);
301 Reference
<registry::XSimpleRegistry
> m_xCommonRDB
;
302 Reference
<registry::XSimpleRegistry
> m_xNativeRDB
;
304 void unorc_verify_init( Reference
<XCommandEnvironment
> const & xCmdEnv
);
305 void unorc_flush( Reference
<XCommandEnvironment
> const & xCmdEnv
);
307 Reference
<XInterface
> getObject( OUString
const & id
);
308 Reference
<XInterface
> insertObject(
309 OUString
const & id
, Reference
<XInterface
> const & xObject
);
310 void releaseObject( OUString
const & id
);
312 bool addToUnoRc( RcItem kind
, OUString
const & url
,
313 Reference
<XCommandEnvironment
> const & xCmdEnv
);
314 bool removeFromUnoRc( RcItem kind
, OUString
const & url
,
315 Reference
<XCommandEnvironment
> const & xCmdEnv
);
316 bool hasInUnoRc( RcItem kind
, OUString
const & url
);
318 css::uno::Reference
< css::uno::XComponentContext
> getRootContext() const;
321 BackendImpl( Sequence
<Any
> const & args
,
322 Reference
<XComponentContext
> const & xComponentContext
);
325 virtual Sequence
< Reference
<deployment::XPackageTypeInfo
> > SAL_CALL
326 getSupportedPackageTypes() throw (RuntimeException
);
328 virtual void SAL_CALL
packageRemoved(OUString
const & url
, OUString
const & mediaType
)
329 throw (deployment::DeploymentException
,
330 uno::RuntimeException
);
332 using PackageRegistryBackend::disposing
;
334 //Will be called from ComponentPackageImpl
335 void initServiceRdbFiles();
338 //______________________________________________________________________________
340 BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
341 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
342 OUString
const & url
, OUString
const & name
,
343 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
344 OUString
const & loader
, bool bRemoved
,
345 OUString
const & identifier
)
346 : Package( myBackend
, url
, name
, name
/* display-name */,
347 xPackageType
, bRemoved
, identifier
),
349 m_registered( REG_UNINIT
)
352 const Reference
<registry::XSimpleRegistry
>
353 BackendImpl::ComponentPackageImpl::getRDB() const
355 BackendImpl
* that
= getMyBackend();
357 //Late "initialization" of the services rdb files
358 //This is to prevent problems when running several
359 //instances of OOo with root rights in parallel. This
360 //would otherwise cause problems when copying the rdbs.
361 //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
363 const ::osl::MutexGuard
guard( getMutex() );
364 if (!that
->bSwitchedRdbFiles
)
366 that
->bSwitchedRdbFiles
= true;
367 that
->initServiceRdbFiles();
370 if ( m_loader
== "com.sun.star.loader.SharedLibrary" )
371 return that
->m_xNativeRDB
;
373 return that
->m_xCommonRDB
;
376 BackendImpl
* BackendImpl::ComponentPackageImpl::getMyBackend() const
378 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
379 if (NULL
== pBackend
)
381 //Throws a DisposedException
383 //We should never get here...
384 throw RuntimeException(
385 "Failed to get the BackendImpl",
386 static_cast<OWeakObject
*>(const_cast<ComponentPackageImpl
*>(this)));
392 //______________________________________________________________________________
393 void BackendImpl::ComponentPackageImpl::disposing()
395 Package::disposing();
398 //______________________________________________________________________________
399 void BackendImpl::TypelibraryPackageImpl::disposing()
401 Package::disposing();
404 //______________________________________________________________________________
405 void BackendImpl::disposing()
408 m_backendObjects
= t_string2object();
409 if (m_xNativeRDB
.is()) {
410 m_xNativeRDB
->close();
411 m_xNativeRDB
.clear();
413 if (m_xCommonRDB
.is()) {
414 m_xCommonRDB
->close();
415 m_xCommonRDB
.clear();
417 unorc_flush( Reference
<XCommandEnvironment
>() );
419 PackageRegistryBackend::disposing();
421 catch (const RuntimeException
&) {
424 catch (const Exception
&) {
425 Any
exc( ::cppu::getCaughtException() );
426 throw lang::WrappedTargetRuntimeException(
427 "caught unexpected exception while disposing...",
428 static_cast<OWeakObject
*>(this), exc
);
433 void BackendImpl::initServiceRdbFiles()
435 const Reference
<XCommandEnvironment
> xCmdEnv
;
437 ::ucbhelper::Content
cacheDir( getCachePath(), xCmdEnv
, m_xComponentContext
);
438 ::ucbhelper::Content oldRDB
;
439 // switch common rdb:
440 if (!m_commonRDB_orig
.isEmpty())
443 &oldRDB
, makeURL( getCachePath(), m_commonRDB_orig
),
444 xCmdEnv
, false /* no throw */ );
446 m_commonRDB
= m_commonRDB_orig
== "common.rdb" ? OUString("common_.rdb") : OUString("common.rdb");
447 if (oldRDB
.get().is())
449 if (! cacheDir
.transferContent(
450 oldRDB
, ::ucbhelper::InsertOperation_COPY
,
451 m_commonRDB
, NameClash::OVERWRITE
))
454 throw RuntimeException( "UCB transferContent() failed!", 0 );
456 oldRDB
= ::ucbhelper::Content();
458 // switch native rdb:
459 if (!m_nativeRDB_orig
.isEmpty())
462 &oldRDB
, makeURL(getCachePath(), m_nativeRDB_orig
),
463 xCmdEnv
, false /* no throw */ );
465 const OUString
plt_rdb( getPlatformString() + ".rdb" );
466 const OUString
plt_rdb_( getPlatformString() + "_.rdb" );
467 m_nativeRDB
= (m_nativeRDB_orig
== plt_rdb
) ? plt_rdb_
: plt_rdb
;
468 if (oldRDB
.get().is())
470 if (! cacheDir
.transferContent(
471 oldRDB
, ::ucbhelper::InsertOperation_COPY
,
472 m_nativeRDB
, NameClash::OVERWRITE
))
473 throw RuntimeException( "UCB transferContent() failed!", 0 );
476 // UNO is bootstrapped, flush for next process start:
477 m_unorc_modified
= true;
478 unorc_flush( Reference
<XCommandEnvironment
>() );
481 // common rdb for java, native rdb for shared lib components
482 if (!m_commonRDB
.isEmpty()) {
484 m_xComponentContext
->getServiceManager()
485 ->createInstanceWithContext(
486 "com.sun.star.registry.SimpleRegistry",
487 m_xComponentContext
), UNO_QUERY_THROW
);
489 makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB
),
492 if (!m_nativeRDB
.isEmpty()) {
494 m_xComponentContext
->getServiceManager()
495 ->createInstanceWithContext(
496 "com.sun.star.registry.SimpleRegistry",
497 m_xComponentContext
), UNO_QUERY_THROW
);
499 makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB
),
504 BackendImpl::BackendImpl(
505 Sequence
<Any
> const & args
,
506 Reference
<XComponentContext
> const & xComponentContext
)
507 : PackageRegistryBackend( args
, xComponentContext
),
508 m_unorc_inited( false ),
509 m_unorc_modified( false ),
510 bSwitchedRdbFiles(false),
511 m_xDynComponentTypeInfo( new Package::TypeInfo(
512 "application/vnd.sun.star.uno-component;type=native;platform=" +
514 OUString("*") + OUString(SAL_DLLEXTENSION
),
515 getResourceString(RID_STR_DYN_COMPONENT
),
516 RID_IMG_COMPONENT
) ),
517 m_xJavaComponentTypeInfo( new Package::TypeInfo(
518 "application/vnd.sun.star.uno-component;type=Java",
520 getResourceString(RID_STR_JAVA_COMPONENT
),
521 RID_IMG_JAVA_COMPONENT
) ),
522 m_xPythonComponentTypeInfo( new Package::TypeInfo(
523 "application/vnd.sun.star.uno-component;type=Python",
526 RID_STR_PYTHON_COMPONENT
),
527 RID_IMG_COMPONENT
) ),
528 m_xComponentsTypeInfo( new Package::TypeInfo(
529 "application/vnd.sun.star.uno-components",
531 getResourceString(RID_STR_COMPONENTS
),
532 RID_IMG_COMPONENT
) ),
533 m_xRDBTypelibTypeInfo( new Package::TypeInfo(
534 "application/vnd.sun.star.uno-typelibrary;type=RDB",
536 getResourceString(RID_STR_RDB_TYPELIB
),
538 m_xJavaTypelibTypeInfo( new Package::TypeInfo(
539 "application/vnd.sun.star.uno-typelibrary;type=Java",
541 getResourceString(RID_STR_JAVA_TYPELIB
),
542 RID_IMG_JAVA_TYPELIB
) ),
545 m_typeInfos
[ 0 ] = m_xDynComponentTypeInfo
;
546 m_typeInfos
[ 1 ] = m_xJavaComponentTypeInfo
;
547 m_typeInfos
[ 2 ] = m_xPythonComponentTypeInfo
;
548 m_typeInfos
[ 3 ] = m_xComponentsTypeInfo
;
549 m_typeInfos
[ 4 ] = m_xRDBTypelibTypeInfo
;
550 m_typeInfos
[ 5 ] = m_xJavaTypelibTypeInfo
;
552 const Reference
<XCommandEnvironment
> xCmdEnv
;
557 // common rdb for java, native rdb for shared lib components
559 xComponentContext
->getServiceManager()->createInstanceWithContext(
560 "com.sun.star.registry.SimpleRegistry",
561 xComponentContext
), UNO_QUERY_THROW
);
562 m_xCommonRDB
->open( OUString() /* in-mem */,
563 false /* ! read-only */, true /* create */ );
565 xComponentContext
->getServiceManager()->createInstanceWithContext(
566 "com.sun.star.registry.SimpleRegistry",
567 xComponentContext
), UNO_QUERY_THROW
);
568 m_xNativeRDB
->open( OUString() /* in-mem */,
569 false /* ! read-only */, true /* create */ );
573 unorc_verify_init( xCmdEnv
);
574 OUString dbFile
= makeURL(getCachePath(), "backenddb.xml");
576 new ComponentBackendDb(getComponentContext(), dbFile
));
580 void BackendImpl::addDataToDb(
581 OUString
const & url
, ComponentBackendDb::Data
const & data
)
583 if (m_backendDb
.get())
584 m_backendDb
->addEntry(url
, data
);
587 ComponentBackendDb::Data
BackendImpl::readDataFromDb(OUString
const & url
)
589 ComponentBackendDb::Data data
;
590 if (m_backendDb
.get())
591 data
= m_backendDb
->getEntry(url
);
595 void BackendImpl::revokeEntryFromDb(OUString
const & url
)
597 if (m_backendDb
.get())
598 m_backendDb
->revokeEntry(url
);
602 //______________________________________________________________________________
603 Sequence
< Reference
<deployment::XPackageTypeInfo
> >
604 BackendImpl::getSupportedPackageTypes() throw (RuntimeException
)
609 void BackendImpl::packageRemoved(OUString
const & url
, OUString
const & /*mediaType*/)
610 throw (deployment::DeploymentException
,
611 uno::RuntimeException
)
613 if (m_backendDb
.get())
614 m_backendDb
->removeEntry(url
);
617 // PackageRegistryBackend
618 //______________________________________________________________________________
619 Reference
<deployment::XPackage
> BackendImpl::bindPackage_(
620 OUString
const & url
, OUString
const & mediaType_
,
621 sal_Bool bRemoved
, OUString
const & identifier
,
622 Reference
<XCommandEnvironment
> const & xCmdEnv
)
624 OUString
mediaType(mediaType_
);
625 if ( mediaType
.isEmpty() || mediaType
== "application/vnd.sun.star.uno-component" || mediaType
== "application/vnd.sun.star.uno-typelibrary" )
627 // detect exact media-type:
628 ::ucbhelper::Content ucbContent
;
629 if (create_ucb_content( &ucbContent
, url
, xCmdEnv
)) {
630 const OUString
title( StrTitle::getTitle( ucbContent
) );
631 if (title
.endsWithIgnoreAsciiCase(SAL_DLLEXTENSION
))
633 mediaType
= "application/vnd.sun.star.uno-component;type=native;platform=" +
636 else if (title
.endsWithIgnoreAsciiCase(".jar"))
638 if (jarManifestHeaderPresent(
639 url
, "RegistrationClassName", xCmdEnv
))
640 mediaType
= "application/vnd.sun.star.uno-component;type=Java";
641 if (mediaType
.isEmpty())
642 mediaType
= "application/vnd.sun.star.uno-typelibrary;type=Java";
644 else if (title
.endsWithIgnoreAsciiCase(".py"))
645 mediaType
= "application/vnd.sun.star.uno-component;type=Python";
646 else if (title
.endsWithIgnoreAsciiCase(".rdb"))
647 mediaType
= "application/vnd.sun.star.uno-typelibrary;type=RDB";
649 if (mediaType
.isEmpty())
650 throw lang::IllegalArgumentException(
651 StrCannotDetectMediaType::get() + url
,
652 static_cast<OWeakObject
*>(this), static_cast<sal_Int16
>(-1) );
655 OUString type
, subType
;
656 INetContentTypeParameterList params
;
657 if (INetContentTypes::parse( mediaType
, type
, subType
, ¶ms
))
659 if (type
.equalsIgnoreAsciiCase("application"))
664 ::ucbhelper::Content
ucbContent( url
, xCmdEnv
, m_xComponentContext
);
665 name
= StrTitle::getTitle( ucbContent
);
668 if (subType
.equalsIgnoreAsciiCase("vnd.sun.star.uno-component"))
670 // xxx todo: probe and evaluate component xml description
672 INetContentTypeParameter
const * param
= params
.find(OString("platform"));
673 bool bPlatformFits(param
== 0);
675 if (!bPlatformFits
) // platform is specified, we have to check
677 aPlatform
= param
->m_sValue
;
678 bPlatformFits
= platform_fits(aPlatform
);
680 // If the package is being removed, do not care whether
681 // platform fits. We won't be using it anyway.
682 if (bPlatformFits
|| bRemoved
) {
683 param
= params
.find(OString("type"));
686 String
const & value
= param
->m_sValue
;
687 if (value
.EqualsIgnoreCaseAscii("native")) {
689 return new BackendImpl::ComponentPackageImpl(
690 this, url
, name
, m_xDynComponentTypeInfo
,
691 "com.sun.star.loader.SharedLibrary",
692 bRemoved
, identifier
);
694 return new BackendImpl::OtherPlatformPackageImpl(
695 this, url
, name
, m_xDynComponentTypeInfo
,
696 bRemoved
, identifier
, aPlatform
);
698 if (value
.EqualsIgnoreCaseAscii("Java")) {
699 return new BackendImpl::ComponentPackageImpl(
700 this, url
, name
, m_xJavaComponentTypeInfo
,
701 "com.sun.star.loader.Java2",
702 bRemoved
, identifier
);
704 if (value
.EqualsIgnoreCaseAscii("Python")) {
705 return new BackendImpl::ComponentPackageImpl(
706 this, url
, name
, m_xPythonComponentTypeInfo
,
707 "com.sun.star.loader.Python",
708 bRemoved
, identifier
);
713 else if (subType
.equalsIgnoreAsciiCase("vnd.sun.star.uno-components"))
715 INetContentTypeParameter
const * param
= params
.find(OString("platform"));
716 if (param
== 0 || platform_fits( param
->m_sValue
)) {
717 return new BackendImpl::ComponentsPackageImpl(
718 this, url
, name
, m_xComponentsTypeInfo
, bRemoved
,
722 else if (subType
.equalsIgnoreAsciiCase( "vnd.sun.star.uno-typelibrary"))
724 INetContentTypeParameter
const * param
= params
.find(OString("type"));
726 String
const & value
= param
->m_sValue
;
727 if (value
.EqualsIgnoreCaseAscii("RDB"))
729 return new BackendImpl::TypelibraryPackageImpl(
730 this, url
, name
, m_xRDBTypelibTypeInfo
,
731 false /* rdb */, bRemoved
, identifier
);
733 if (value
.EqualsIgnoreCaseAscii("Java")) {
734 return new BackendImpl::TypelibraryPackageImpl(
735 this, url
, name
, m_xJavaTypelibTypeInfo
,
736 true /* jar */, bRemoved
, identifier
);
742 throw lang::IllegalArgumentException(
743 StrUnsupportedMediaType::get() + mediaType
,
744 static_cast<OWeakObject
*>(this),
745 static_cast<sal_Int16
>(-1) );
749 //______________________________________________________________________________
750 void BackendImpl::unorc_verify_init(
751 Reference
<XCommandEnvironment
> const & xCmdEnv
)
755 const ::osl::MutexGuard
guard( getMutex() );
756 if (! m_unorc_inited
)
759 ::ucbhelper::Content ucb_content
;
760 if (create_ucb_content(
762 makeURL( getCachePath(), "unorc" ),
763 xCmdEnv
, false /* no throw */ ))
766 if (readLine( &line
, "UNO_JAVA_CLASSPATH=", ucb_content
,
767 RTL_TEXTENCODING_UTF8
))
769 sal_Int32 index
= sizeof ("UNO_JAVA_CLASSPATH=") - 1;
771 OUString
token( line
.getToken( 0, ' ', index
).trim() );
772 if (!token
.isEmpty())
774 if (create_ucb_content(
775 0, expandUnoRcTerm(token
), xCmdEnv
,
776 false /* no throw */ ))
778 //The jar file may not exist anymore if a shared or bundled
779 //extension was removed, but it can still be in the unorc
780 //After running XExtensionManager::synchronize, the unorc is
782 m_jar_typelibs
.push_back( token
);
788 if (readLine( &line
, "UNO_TYPES=", ucb_content
,
789 RTL_TEXTENCODING_UTF8
)) {
790 sal_Int32 index
= sizeof ("UNO_TYPES=") - 1;
792 OUString
token( line
.getToken( 0, ' ', index
).trim() );
793 if (!token
.isEmpty())
795 if (token
[ 0 ] == '?')
796 token
= token
.copy( 1 );
797 if (create_ucb_content(
798 0, expandUnoRcTerm(token
), xCmdEnv
,
799 false /* no throw */ ))
801 //The RDB file may not exist anymore if a shared or bundled
802 //extension was removed, but it can still be in the unorc.
803 //After running XExtensionManager::synchronize, the unorc is
805 m_rdb_typelibs
.push_back( token
);
811 if (readLine( &line
, "UNO_SERVICES=", ucb_content
,
812 RTL_TEXTENCODING_UTF8
))
814 // The UNO_SERVICES line always has the BNF form
816 // ("?$ORIGIN/" <common-rdb>)? -- first
817 // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second
818 // ("?" ("BUNDLED_EXTENSIONS" | -- third
819 // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
821 // so can unambiguously be split into its thre parts:
823 for (sal_Int32 i
= RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
826 OUString
token(line
.getToken(0, ' ', i
));
827 if (!token
.isEmpty())
829 if (state
== 1 && token
.match("?$ORIGIN/"))
831 m_commonRDB_orig
= token
.copy(
832 RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
835 else if ( state
<= 2 && token
== "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" )
843 token
= token
.copy(1);
845 m_components
.push_back(token
);
853 if (create_ucb_content(
855 makeURL( getCachePath(), getPlatformString() + "rc"),
856 xCmdEnv
, false /* no throw */ )) {
857 if (readLine( &line
, "UNO_SERVICES=", ucb_content
,
858 RTL_TEXTENCODING_UTF8
)) {
859 m_nativeRDB_orig
= line
.copy(
860 sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
864 m_unorc_modified
= false;
865 m_unorc_inited
= true;
869 //______________________________________________________________________________
870 void BackendImpl::unorc_flush( Reference
<XCommandEnvironment
> const & xCmdEnv
)
874 if (!m_unorc_inited
|| !m_unorc_modified
)
879 buf
.append("ORIGIN=");
880 OUString sOrigin
= dp_misc::makeRcTerm(m_cachePath
);
881 OString osOrigin
= OUStringToOString(sOrigin
, RTL_TEXTENCODING_UTF8
);
882 buf
.append(osOrigin
);
885 if (! m_jar_typelibs
.empty())
887 t_stringlist::const_iterator
iPos( m_jar_typelibs
.begin() );
888 t_stringlist::const_iterator
const iEnd( m_jar_typelibs
.end() );
889 buf
.append( "UNO_JAVA_CLASSPATH=" );
890 while (iPos
!= iEnd
) {
891 // encoded ASCII file-urls:
893 OUStringToOString( *iPos
, RTL_TEXTENCODING_ASCII_US
) );
901 if (! m_rdb_typelibs
.empty())
903 t_stringlist::const_iterator
iPos( m_rdb_typelibs
.begin() );
904 t_stringlist::const_iterator
const iEnd( m_rdb_typelibs
.end() );
905 buf
.append( "UNO_TYPES=" );
906 while (iPos
!= iEnd
) {
908 // encoded ASCII file-urls:
910 OUStringToOString( *iPos
, RTL_TEXTENCODING_ASCII_US
) );
919 // If we duplicated the common or native rdb then we must use those urls
920 //otherwise we use those of the original files. That is, m_commonRDB_orig
921 //and m_nativeRDB_orig;
922 OUString
sCommonRDB(m_commonRDB
.isEmpty() ? m_commonRDB_orig
: m_commonRDB
);
923 OUString
sNativeRDB(m_nativeRDB
.isEmpty() ? m_nativeRDB_orig
: m_nativeRDB
);
925 if (!sCommonRDB
.isEmpty() || !sNativeRDB
.isEmpty() ||
926 !m_components
.empty())
928 buf
.append( "UNO_SERVICES=" );
930 if (!sCommonRDB
.isEmpty())
932 buf
.append( "?$ORIGIN/" );
933 buf
.append( OUStringToOString(
934 sCommonRDB
, RTL_TEXTENCODING_ASCII_US
) );
937 if (!sNativeRDB
.isEmpty())
943 buf
.append( "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" );
948 buf2
.append("ORIGIN=");
949 buf2
.append(osOrigin
);
951 buf2
.append( "UNO_SERVICES=?$ORIGIN/" );
952 buf2
.append( OUStringToOString(
953 sNativeRDB
, RTL_TEXTENCODING_ASCII_US
) );
956 const Reference
<io::XInputStream
> xData(
957 ::xmlscript::createInputStream(
959 reinterpret_cast<sal_Int8
const *>(buf2
.getStr()),
960 buf2
.getLength() ) ) );
961 ::ucbhelper::Content
ucb_content(
962 makeURL( getCachePath(), getPlatformString() + "rc" ),
963 xCmdEnv
, m_xComponentContext
);
964 ucb_content
.writeStream( xData
, true /* replace existing */ );
966 for (t_stringlist::iterator
i(m_components
.begin());
967 i
!= m_components
.end(); ++i
)
974 buf
.append(OUStringToOString(*i
, RTL_TEXTENCODING_UTF8
));
981 const Reference
<io::XInputStream
> xData(
982 ::xmlscript::createInputStream(
984 reinterpret_cast<sal_Int8
const *>(buf
.getStr()),
985 buf
.getLength() ) ) );
986 ::ucbhelper::Content
ucb_content(
987 makeURL( getCachePath(), "unorc" ), xCmdEnv
, m_xComponentContext
);
988 ucb_content
.writeStream( xData
, true /* replace existing */ );
990 m_unorc_modified
= false;
993 //______________________________________________________________________________
994 bool BackendImpl::addToUnoRc( RcItem kind
, OUString
const & url_
,
995 Reference
<XCommandEnvironment
> const & xCmdEnv
)
997 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
998 const ::osl::MutexGuard
guard( getMutex() );
999 unorc_verify_init( xCmdEnv
);
1000 t_stringlist
& rSet
= getRcItemList(kind
);
1001 if (::std::find( rSet
.begin(), rSet
.end(), rcterm
) == rSet
.end()) {
1002 rSet
.push_front( rcterm
); // prepend to list, thus overriding
1003 // write immediately:
1004 m_unorc_modified
= true;
1005 unorc_flush( xCmdEnv
);
1012 //______________________________________________________________________________
1013 bool BackendImpl::removeFromUnoRc(
1014 RcItem kind
, OUString
const & url_
,
1015 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1017 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
1018 const ::osl::MutexGuard
guard( getMutex() );
1019 unorc_verify_init( xCmdEnv
);
1020 getRcItemList(kind
).remove( rcterm
);
1021 // write immediately:
1022 m_unorc_modified
= true;
1023 unorc_flush( xCmdEnv
);
1027 //______________________________________________________________________________
1028 bool BackendImpl::hasInUnoRc(
1029 RcItem kind
, OUString
const & url_
)
1031 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
1032 const ::osl::MutexGuard
guard( getMutex() );
1033 t_stringlist
const & rSet
= getRcItemList(kind
);
1034 return ::std::find( rSet
.begin(), rSet
.end(), rcterm
) != rSet
.end();
1037 css::uno::Reference
< css::uno::XComponentContext
> BackendImpl::getRootContext()
1040 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1041 getComponentContext()->getValueByName("_root"),
1042 css::uno::UNO_QUERY
);
1043 return rootContext
.is() ? rootContext
: getComponentContext();
1046 //______________________________________________________________________________
1047 void BackendImpl::releaseObject( OUString
const & id
)
1049 const ::osl::MutexGuard
guard( getMutex() );
1050 m_backendObjects
.erase( id
);
1053 //______________________________________________________________________________
1054 Reference
<XInterface
> BackendImpl::getObject( OUString
const & id
)
1056 const ::osl::MutexGuard
guard( getMutex() );
1057 const t_string2object::const_iterator
iFind( m_backendObjects
.find( id
) );
1058 if (iFind
== m_backendObjects
.end())
1059 return Reference
<XInterface
>();
1061 return iFind
->second
;
1064 //______________________________________________________________________________
1065 Reference
<XInterface
> BackendImpl::insertObject(
1066 OUString
const & id
, Reference
<XInterface
> const & xObject
)
1068 const ::osl::MutexGuard
guard( getMutex() );
1069 const ::std::pair
<t_string2object::iterator
, bool> insertion(
1070 m_backendObjects
.insert( t_string2object::value_type(
1072 return insertion
.first
->second
;
1075 //------------------------------------------------------------------------------
1076 Reference
<XComponentContext
> raise_uno_process(
1077 Reference
<XComponentContext
> const & xContext
,
1078 ::rtl::Reference
<AbortChannel
> const & abortChannel
)
1080 OSL_ASSERT( xContext
.is() );
1082 OUString
url( util::theMacroExpander::get(xContext
)->expandMacros( "$URE_BIN_DIR/uno" ) );
1085 buf
.appendAscii( "uno:pipe,name=" );
1086 OUString
pipeId( generateRandomPipeId() );
1087 buf
.append( pipeId
);
1088 buf
.appendAscii( ";urp;uno.ComponentContext" );
1089 const OUString
connectStr( buf
.makeStringAndClear() );
1091 // raise core UNO process to register/run a component,
1092 // javavm service uses unorc next to executable to retrieve deployed
1095 ::std::vector
<OUString
> args
;
1096 #if OSL_DEBUG_LEVEL == 0
1097 args
.push_back( "--quiet" );
1099 args
.push_back( "--singleaccept" );
1100 args
.push_back( "-u" );
1101 args
.push_back( connectStr
);
1102 // don't inherit from unorc:
1103 args
.push_back( "-env:INIFILENAME=" );
1105 //now add the bootstrap variables which were supplied on the command line
1106 ::std::vector
<OUString
> bootvars
= getCmdBootstrapVariables();
1107 args
.insert(args
.end(), bootvars
.begin(), bootvars
.end());
1109 oslProcess hProcess
= raiseProcess(
1110 url
, comphelper::containerToSequence(args
) );
1112 return Reference
<XComponentContext
>(
1113 resolveUnoURL( connectStr
, xContext
, abortChannel
.get() ),
1117 // try to terminate process:
1118 if ( osl_terminateProcess( hProcess
) != osl_Process_E_None
)
1120 OSL_ASSERT( false );
1126 //------------------------------------------------------------------------------
1129 void extractComponentData(
1130 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
1131 css::uno::Reference
< css::registry::XRegistryKey
> const & registry
,
1132 ComponentBackendDb::Data
* data
,
1133 std::vector
< css::uno::Reference
< css::uno::XInterface
> > * factories
,
1134 css::uno::Reference
< css::loader::XImplementationLoader
> const &
1136 OUString
const & componentUrl
)
1139 context
.is() && registry
.is() && data
!= 0 && componentLoader
.is());
1140 OUString
registryName(registry
->getKeyName());
1141 sal_Int32 prefix
= registryName
.getLength();
1142 if (!registryName
.endsWith("/")) {
1143 prefix
+= RTL_CONSTASCII_LENGTH("/");
1145 css::uno::Sequence
< css::uno::Reference
< css::registry::XRegistryKey
> >
1146 keys(registry
->openKeys());
1147 css::uno::Reference
< css::lang::XMultiComponentFactory
> smgr(
1148 context
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1149 for (sal_Int32 i
= 0; i
< keys
.getLength(); ++i
) {
1150 OUString
name(keys
[i
]->getKeyName().copy(prefix
));
1151 data
->implementationNames
.push_back(name
);
1152 css::uno::Reference
< css::registry::XRegistryKey
> singletons(
1153 keys
[i
]->openKey("UNO/SINGLETONS"));
1154 if (singletons
.is()) {
1155 sal_Int32 prefix2
= keys
[i
]->getKeyName().getLength() +
1156 RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
1158 css::uno::Reference
< css::registry::XRegistryKey
> >
1159 singletonKeys(singletons
->openKeys());
1160 for (sal_Int32 j
= 0; j
< singletonKeys
.getLength(); ++j
) {
1161 data
->singletons
.push_back(
1162 std::pair
< OUString
, OUString
>(
1163 singletonKeys
[j
]->getKeyName().copy(prefix2
), name
));
1166 if (factories
!= 0) {
1167 factories
->push_back(
1168 componentLoader
->activate(
1169 name
, OUString(), componentUrl
, keys
[i
]));
1176 void BackendImpl::ComponentPackageImpl::getComponentInfo(
1177 ComponentBackendDb::Data
* data
,
1178 std::vector
< css::uno::Reference
< css::uno::XInterface
> > * factories
,
1179 Reference
<XComponentContext
> const & xContext
)
1181 const Reference
<loader::XImplementationLoader
> xLoader(
1182 xContext
->getServiceManager()->createInstanceWithContext(
1183 m_loader
, xContext
), UNO_QUERY
);
1186 throw css::deployment::DeploymentException(
1187 "cannot instantiate loader " + m_loader
,
1188 static_cast< OWeakObject
* >(this), Any());
1191 // HACK: highly dependent on stoc/source/servicemanager
1192 // and stoc/source/implreg implementation which rely on the same
1193 // services.rdb format!
1194 // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
1195 // writeRegistryInfo, however, but are known, fixed values here, so
1196 // can be passed into extractComponentData
1197 OUString
url(getURL());
1198 const Reference
<registry::XSimpleRegistry
> xMemReg(
1199 xContext
->getServiceManager()->createInstanceWithContext(
1200 "com.sun.star.registry.SimpleRegistry", xContext
),
1202 xMemReg
->open( OUString() /* in mem */, false, true );
1203 xLoader
->writeRegistryInfo( xMemReg
->getRootKey(), OUString(), url
);
1204 extractComponentData(
1205 xContext
, xMemReg
->getRootKey(), data
, factories
, xLoader
, url
);
1208 void BackendImpl::ComponentPackageImpl::componentLiveInsertion(
1209 ComponentBackendDb::Data
const & data
,
1210 std::vector
< css::uno::Reference
< css::uno::XInterface
> > const &
1213 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1214 getMyBackend()->getRootContext());
1215 css::uno::Reference
< css::container::XSet
> set(
1216 rootContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1217 std::vector
< css::uno::Reference
< css::uno::XInterface
> >::const_iterator
1218 factory(factories
.begin());
1219 for (t_stringlist::const_iterator
i(data
.implementationNames
.begin());
1220 i
!= data
.implementationNames
.end(); ++i
)
1223 set
->insert(css::uno::Any(*factory
++));
1224 } catch (const container::ElementExistException
&) {
1226 "implementation %s already registered",
1227 OUStringToOString(*i
, RTL_TEXTENCODING_UTF8
).getStr());
1230 if (!data
.singletons
.empty()) {
1231 css::uno::Reference
< css::container::XNameContainer
> cont(
1232 rootContext
, css::uno::UNO_QUERY_THROW
);
1233 for (t_stringpairvec::const_iterator
i(data
.singletons
.begin());
1234 i
!= data
.singletons
.end(); ++i
)
1236 OUString
name("/singletons/" + i
->first
);
1237 //TODO: Update should be atomic:
1239 cont
->removeByName( name
+ "/arguments");
1240 } catch (const container::NoSuchElementException
&) {}
1242 cont
->insertByName( name
+ "/service", css::uno::Any(i
->second
));
1243 } catch (const container::ElementExistException
&) {
1244 cont
->replaceByName( name
+ "/service", css::uno::Any(i
->second
));
1247 cont
->insertByName(name
, css::uno::Any());
1248 } catch (const container::ElementExistException
&) {
1250 "singleton %s already registered",
1252 i
->first
, RTL_TEXTENCODING_UTF8
).getStr());
1253 cont
->replaceByName(name
, css::uno::Any());
1259 void BackendImpl::ComponentPackageImpl::componentLiveRemoval(
1260 ComponentBackendDb::Data
const & data
)
1262 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1263 getMyBackend()->getRootContext());
1264 css::uno::Reference
< css::container::XSet
> set(
1265 rootContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1266 for (t_stringlist::const_iterator
i(data
.implementationNames
.begin());
1267 i
!= data
.implementationNames
.end(); ++i
)
1270 set
->remove(css::uno::Any(*i
));
1271 } catch (const css::container::NoSuchElementException
&) {
1272 // ignore if factory has not been live deployed
1275 if (!data
.singletons
.empty()) {
1276 css::uno::Reference
< css::container::XNameContainer
> cont(
1277 rootContext
, css::uno::UNO_QUERY_THROW
);
1278 for (t_stringpairvec::const_iterator
i(data
.singletons
.begin());
1279 i
!= data
.singletons
.end(); ++i
)
1281 OUString
name("/singletons/" + i
->first
);
1282 //TODO: Removal should be atomic:
1284 cont
->removeByName(name
);
1285 } catch (const container::NoSuchElementException
&) {}
1287 cont
->removeByName( name
+ "/service" );
1288 } catch (const container::NoSuchElementException
&) {}
1290 cont
->removeByName( name
+ "/arguments" );
1291 } catch (const container::NoSuchElementException
&) {}
1297 //______________________________________________________________________________
1298 //We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
1299 //And it also shows the problem if another extension has overwritten an implementation
1300 //entry, because it contains the same service implementation
1301 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1302 BackendImpl::ComponentPackageImpl::isRegistered_(
1303 ::osl::ResettableMutexGuard
&,
1304 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1305 Reference
<XCommandEnvironment
> const & )
1307 if (m_registered
== REG_UNINIT
)
1309 m_registered
= REG_NOT_REGISTERED
;
1310 bool bAmbiguousComponentName
= false;
1311 const Reference
<registry::XSimpleRegistry
> xRDB( getRDB() );
1314 // lookup rdb for location URL:
1315 const Reference
<registry::XRegistryKey
> xRootKey(
1316 xRDB
->getRootKey() );
1317 const Reference
<registry::XRegistryKey
> xImplKey(
1318 xRootKey
->openKey( "IMPLEMENTATIONS" ) );
1319 Sequence
<OUString
> implNames
;
1320 if (xImplKey
.is() && xImplKey
->isValid())
1321 implNames
= xImplKey
->getKeyNames();
1322 OUString
const * pImplNames
= implNames
.getConstArray();
1323 sal_Int32 pos
= implNames
.getLength();
1326 checkAborted( abortChannel
);
1328 pImplNames
[ pos
] + "/UNO/LOCATION" );
1329 const Reference
<registry::XRegistryKey
> xKey(
1330 xRootKey
->openKey(key
) );
1331 if (xKey
.is() && xKey
->isValid())
1333 const OUString
location( xKey
->getAsciiValue() );
1334 if (location
.equalsIgnoreAsciiCase( getURL() ))
1340 //try to match only the file name
1341 OUString
thisUrl(getURL());
1342 OUString
thisFileName(thisUrl
.copy(thisUrl
.lastIndexOf('/')));
1344 OUString
locationFileName(location
.copy(location
.lastIndexOf('/')));
1345 if (locationFileName
.equalsIgnoreAsciiCase(thisFileName
))
1346 bAmbiguousComponentName
= true;
1351 m_registered
= REG_REGISTERED
;
1352 else if (bAmbiguousComponentName
)
1353 m_registered
= REG_MAYBE_REGISTERED
;
1357 //Different extensions can use the same service implementations. Then the extensions
1358 //which was installed last will overwrite the one from the other extension. That is
1359 //the registry will contain the path (the location) of the library or jar of the
1360 //second extension. In this case isRegistered called for the lib of the first extension
1361 //would return "not registered". That would mean that during uninstallation
1362 //XPackage::registerPackage is not called, because it just was not registered. This is,
1363 //however, necessary for jar files. Registering and unregistering update
1364 //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
1365 //Therefore, we will return always "is ambiguous" if the path of this component cannot
1366 //be found in the registry and if there is another path and both have the same file name (but
1367 //the rest of the path is different).
1368 //If the caller cannot precisely determine that this package was registered, then it must
1369 //call registerPackage.
1370 sal_Bool bAmbiguous
= m_registered
== REG_VOID
// REG_VOID == we are in the progress of unregistration
1371 || m_registered
== REG_MAYBE_REGISTERED
;
1372 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1373 true /* IsPresent */,
1374 beans::Ambiguous
<sal_Bool
>(
1375 m_registered
== REG_REGISTERED
, bAmbiguous
) );
1378 //______________________________________________________________________________
1379 void BackendImpl::ComponentPackageImpl::processPackage_(
1380 ::osl::ResettableMutexGuard
&,
1381 bool doRegisterPackage
,
1383 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1384 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1386 BackendImpl
* that
= getMyBackend();
1387 OUString
url(getURL());
1388 if (doRegisterPackage
) {
1389 ComponentBackendDb::Data data
;
1390 css::uno::Reference
< css::uno::XComponentContext
> context
;
1392 context
= that
->getComponentContext();
1394 context
.set(that
->getObject(url
), css::uno::UNO_QUERY
);
1395 if (!context
.is()) {
1400 that
->getComponentContext(), abortChannel
)),
1401 css::uno::UNO_QUERY_THROW
);
1404 css::uno::Reference
< css::registry::XImplementationRegistration
> impreg(
1405 context
->getServiceManager()->createInstanceWithContext(
1406 "com.sun.star.registry.ImplementationRegistration",
1408 css::uno::UNO_QUERY_THROW
);
1409 css::uno::Reference
< css::registry::XSimpleRegistry
> rdb(getRDB());
1410 impreg
->registerImplementation(m_loader
, url
, rdb
);
1411 // Only write to unorc after successful registration; it may fail if
1412 // there is no suitable java
1413 if (m_loader
== "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url
, "UNO-Type-Path", xCmdEnv
))
1415 that
->addToUnoRc(RCITEM_JAR_TYPELIB
, url
, xCmdEnv
);
1416 data
.javaTypeLibrary
= true;
1418 std::vector
< css::uno::Reference
< css::uno::XInterface
> > factories
;
1419 getComponentInfo(&data
, startup
? 0 : &factories
, context
);
1422 componentLiveInsertion(data
, factories
);
1423 } catch (css::uno::Exception
& e
) {
1425 "desktop.deployment", "caught Exception " << e
.Message
);
1427 impreg
->revokeImplementation(url
, rdb
);
1428 } catch (css::uno::RuntimeException
& e2
) {
1430 "desktop.deployment",
1431 "ignored RuntimeException " << e2
.Message
);
1436 m_registered
= REG_REGISTERED
;
1437 that
->addDataToDb(url
, data
);
1439 m_registered
= REG_VOID
;
1440 ComponentBackendDb::Data
data(that
->readDataFromDb(url
));
1441 css::uno::Reference
< css::uno::XComponentContext
> context(
1442 that
->getObject(url
), css::uno::UNO_QUERY
);
1443 bool remoteContext
= context
.is();
1444 if (!remoteContext
) {
1445 context
= that
->getComponentContext();
1448 componentLiveRemoval(data
);
1450 css::uno::Reference
< css::registry::XImplementationRegistration
>(
1451 context
->getServiceManager()->createInstanceWithContext(
1452 "com.sun.star.registry.ImplementationRegistration",
1454 css::uno::UNO_QUERY_THROW
)->revokeImplementation(url
, getRDB());
1455 if (data
.javaTypeLibrary
) {
1456 that
->removeFromUnoRc(RCITEM_JAR_TYPELIB
, url
, xCmdEnv
);
1458 if (remoteContext
) {
1459 that
->releaseObject(url
);
1461 m_registered
= REG_NOT_REGISTERED
;
1462 getMyBackend()->revokeEntryFromDb(url
);
1466 BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
1467 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1468 OUString
const & url
, OUString
const & name
,
1469 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1470 bool jarFile
, bool bRemoved
, OUString
const & identifier
)
1471 : Package( myBackend
, url
, name
, name
/* display-name */,
1472 xPackageType
, bRemoved
, identifier
),
1473 m_jarFile( jarFile
)
1478 BackendImpl
* BackendImpl::TypelibraryPackageImpl::getMyBackend() const
1480 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1481 if (NULL
== pBackend
)
1483 //May throw a DisposedException
1485 //We should never get here...
1486 throw RuntimeException( "Failed to get the BackendImpl",
1487 static_cast<OWeakObject
*>(const_cast<TypelibraryPackageImpl
*>(this)));
1491 //______________________________________________________________________________
1492 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1493 BackendImpl::TypelibraryPackageImpl::isRegistered_(
1494 ::osl::ResettableMutexGuard
&,
1495 ::rtl::Reference
<AbortChannel
> const &,
1496 Reference
<XCommandEnvironment
> const & )
1498 BackendImpl
* that
= getMyBackend();
1499 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1500 true /* IsPresent */,
1501 beans::Ambiguous
<sal_Bool
>(
1503 m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
, getURL() ),
1504 false /* IsAmbiguous */ ) );
1507 //______________________________________________________________________________
1508 void BackendImpl::TypelibraryPackageImpl::processPackage_(
1509 ::osl::ResettableMutexGuard
&,
1510 bool doRegisterPackage
,
1512 ::rtl::Reference
<AbortChannel
> const &,
1513 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1515 BackendImpl
* that
= getMyBackend();
1516 const OUString
url( getURL() );
1518 if (doRegisterPackage
)
1522 // xxx todo add to classpath at runtime: ???
1523 //SB: It is probably not worth it to add the live inserted type
1524 // library JAR to the UnoClassLoader in the soffice process. Any
1525 // live inserted component JAR that might reference this type
1526 // library JAR runs in its own uno process, so there is probably no
1527 // Java code in the soffice process that would see any UNO types
1528 // introduced by this type library JAR.
1532 css::uno::Reference
< css::container::XSet
>(
1533 that
->getComponentContext()->getValueByName(
1535 "/com.sun.star.reflection.theTypeDescriptionManager"),
1536 css::uno::UNO_QUERY_THROW
)->insert(
1537 css::uno::makeAny(expandUnoRcUrl(url
)));
1540 that
->addToUnoRc( m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
,
1543 else // revokePackage()
1545 that
->removeFromUnoRc(
1546 m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
, url
, xCmdEnv
);
1548 // revoking types at runtime, possible, sensible?
1550 css::uno::Reference
< css::container::XSet
>(
1551 that
->getComponentContext()->getValueByName(
1553 "/com.sun.star.reflection.theTypeDescriptionManager"),
1554 css::uno::UNO_QUERY_THROW
)->remove(
1555 css::uno::makeAny(expandUnoRcUrl(url
)));
1560 BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
1561 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1562 OUString
const & url
, OUString
const & name
,
1563 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1564 bool bRemoved
, OUString
const & identifier
, OUString
const& rPlatform
)
1565 : Package(myBackend
, url
, name
, name
, xPackageType
, bRemoved
, identifier
)
1566 , m_aPlatform(rPlatform
)
1568 OSL_PRECOND(bRemoved
, "this class can only be used for removing packages!");
1572 BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
1574 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1575 if (NULL
== pBackend
)
1577 //Throws a DisposedException
1579 //We should never get here...
1580 throw RuntimeException("Failed to get the BackendImpl",
1581 static_cast<OWeakObject
*>(const_cast<OtherPlatformPackageImpl
*>(this)));
1586 Reference
<registry::XSimpleRegistry
> const
1587 BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
1589 OUString
const aRDB(m_aPlatform
+ ".rdb");
1590 OUString
const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB
));
1592 Reference
<registry::XSimpleRegistry
> xRegistry
;
1597 impl_createInstance("com.sun.star.registry.SimpleRegistry"),
1601 xRegistry
->open(expandUnoRcUrl(aRDBPath
), false, false);
1603 catch (registry::InvalidRegistryException
const&)
1605 // If the registry does not exist, we do not need to bother at all
1609 OSL_POSTCOND(xRegistry
.is(), "could not create registry for the package's platform");
1613 Reference
<XInterface
> const
1614 BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString
const& rService
)
1617 Reference
<XComponentContext
> const xContext(getMyBackend()->getComponentContext());
1618 OSL_ASSERT(xContext
.is());
1619 Reference
<XInterface
> xService
;
1621 xService
.set(xContext
->getServiceManager()->createInstanceWithContext(rService
, xContext
));
1625 beans::Optional
<beans::Ambiguous
<sal_Bool
> >
1626 BackendImpl::OtherPlatformPackageImpl::isRegistered_(
1627 ::osl::ResettableMutexGuard
& /* guard */,
1628 ::rtl::Reference
<AbortChannel
> const& /* abortChannel */,
1629 Reference
<XCommandEnvironment
> const& /* xCmdEnv */ )
1631 return beans::Optional
<beans::Ambiguous
<sal_Bool
> >(sal_True
,
1632 beans::Ambiguous
<sal_Bool
>(sal_True
, sal_False
));
1636 BackendImpl::OtherPlatformPackageImpl::processPackage_(
1637 ::osl::ResettableMutexGuard
& /* guard */,
1638 bool bRegisterPackage
,
1639 bool /* bStartup */,
1640 ::rtl::Reference
<AbortChannel
> const& /* abortChannel */,
1641 Reference
<XCommandEnvironment
> const& /* xCmdEnv */)
1643 OSL_PRECOND(!bRegisterPackage
, "this class can only be used for removing packages!");
1644 (void) bRegisterPackage
;
1646 OUString
const aURL(getURL());
1648 Reference
<registry::XSimpleRegistry
> const xServicesRDB(impl_openRDB());
1649 Reference
<registry::XImplementationRegistration
> const xImplReg(
1650 impl_createInstance("com.sun.star.registry.ImplementationRegistration"),
1653 if (xImplReg
.is() && xServicesRDB
.is())
1654 xImplReg
->revokeImplementation(aURL
, xServicesRDB
);
1655 if (xServicesRDB
.is())
1656 xServicesRDB
->close();
1658 getMyBackend()->revokeEntryFromDb(aURL
);
1661 BackendImpl
* BackendImpl::ComponentsPackageImpl::getMyBackend() const
1663 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1664 if (NULL
== pBackend
)
1666 //Throws a DisposedException
1668 //We should never get here...
1669 throw RuntimeException("Failed to get the BackendImpl",
1670 static_cast<OWeakObject
*>(const_cast<ComponentsPackageImpl
*>(this)));
1675 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1676 BackendImpl::ComponentsPackageImpl::isRegistered_(
1677 ::osl::ResettableMutexGuard
&,
1678 ::rtl::Reference
<AbortChannel
> const &,
1679 Reference
<XCommandEnvironment
> const & )
1681 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1683 beans::Ambiguous
<sal_Bool
>(
1684 getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS
, getURL()), false));
1687 void BackendImpl::ComponentsPackageImpl::processPackage_(
1688 ::osl::ResettableMutexGuard
&,
1689 bool doRegisterPackage
,
1691 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1692 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1694 BackendImpl
* that
= getMyBackend();
1695 OUString
url(getURL());
1696 if (doRegisterPackage
) {
1698 css::uno::Reference
< css::uno::XComponentContext
> context(
1699 that
->getObject(url
), css::uno::UNO_QUERY
);
1700 if (!context
.is()) {
1705 that
->getComponentContext(), abortChannel
)),
1706 css::uno::UNO_QUERY_THROW
);
1708 // This relies on the root component context's service manager
1709 // supporting the extended XSet semantics:
1710 css::uno::Sequence
< css::beans::NamedValue
> args(2);
1711 args
[0].Name
= OUString("uri");
1712 args
[0].Value
<<= expandUnoRcUrl(url
);
1713 args
[1].Name
= OUString("component-context");
1714 args
[1].Value
<<= context
;
1715 css::uno::Reference
< css::container::XSet
> smgr(
1716 that
->getRootContext()->getServiceManager(),
1717 css::uno::UNO_QUERY_THROW
);
1718 smgr
->insert(css::uno::makeAny(args
));
1720 that
->addToUnoRc(RCITEM_COMPONENTS
, url
, xCmdEnv
);
1722 that
->removeFromUnoRc(RCITEM_COMPONENTS
, url
, xCmdEnv
);
1724 // This relies on the root component context's service manager
1725 // supporting the extended XSet semantics:
1726 css::uno::Sequence
< css::beans::NamedValue
> args(1);
1727 args
[0].Name
= OUString("uri");
1728 args
[0].Value
<<= expandUnoRcUrl(url
);
1729 css::uno::Reference
< css::container::XSet
> smgr(
1730 that
->getRootContext()->getServiceManager(),
1731 css::uno::UNO_QUERY_THROW
);
1732 smgr
->remove(css::uno::makeAny(args
));
1734 that
->releaseObject(url
);
1735 that
->revokeEntryFromDb(url
); // in case it got added with old code
1739 BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
1740 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1741 OUString
const & url
, OUString
const & name
,
1742 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1743 bool bRemoved
, OUString
const & identifier
)
1744 : Package( myBackend
, url
, name
, name
/* display-name */,
1745 xPackageType
, bRemoved
, identifier
)
1750 namespace sdecl
= comphelper::service_decl
;
1751 sdecl::class_
<BackendImpl
, sdecl::with_args
<true> > serviceBI
;
1752 extern sdecl::ServiceDecl
const serviceDecl(
1754 IMPLEMENTATION_NAME
,
1755 BACKEND_SERVICE_NAME
);
1757 } // namespace component
1758 } // namespace backend
1759 } // namespace dp_registry
1762 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */