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 <strings.hrc>
23 #include <dp_shared.hxx>
24 #include <dp_backend.h>
25 #include <dp_platform.hxx>
27 #include <rtl/string.hxx>
28 #include <rtl/strbuf.hxx>
29 #include <rtl/ustrbuf.hxx>
30 #include <rtl/uri.hxx>
31 #include <sal/log.hxx>
32 #include <cppuhelper/exc_hlp.hxx>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <ucbhelper/content.hxx>
35 #include <comphelper/sequence.hxx>
37 #include <xmlscript/xml_helper.hxx>
38 #include <svl/inettype.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <o3tl/string_view.hxx>
41 #include <com/sun/star/beans/NamedValue.hpp>
42 #include <com/sun/star/deployment/DeploymentException.hpp>
43 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/container/XSet.hpp>
46 #include <com/sun/star/registry/XSimpleRegistry.hpp>
47 #include <com/sun/star/registry/XImplementationRegistration.hpp>
48 #include <com/sun/star/loader/XImplementationLoader.hpp>
49 #include <com/sun/star/io/XInputStream.hpp>
50 #include <com/sun/star/ucb/NameClash.hpp>
51 #include <com/sun/star/util/theMacroExpander.hpp>
55 #include <string_view>
56 #include <unordered_map>
58 #include "dp_compbackenddb.hxx"
60 using namespace ::dp_misc
;
61 using namespace ::com::sun::star
;
62 using namespace ::com::sun::star::uno
;
63 using namespace ::com::sun::star::ucb
;
65 namespace dp_registry::backend::component
{
68 /** return a vector of bootstrap variables which have been provided
71 std::vector
<OUString
> getCmdBootstrapVariables()
73 std::vector
<OUString
> ret
;
74 sal_uInt32 count
= osl_getCommandArgCount();
75 for (sal_uInt32 i
= 0; i
< count
; i
++)
78 osl_getCommandArg(i
, &arg
.pData
);
79 if (arg
.startsWith("-env:"))
85 bool jarManifestHeaderPresent(
86 OUString
const & url
, std::u16string_view name
,
87 Reference
<XCommandEnvironment
> const & xCmdEnv
)
89 OUString buf
= "vnd.sun.star.zip://"
91 url
, rtl_UriCharClassRegName
, rtl_UriEncodeIgnoreEscapes
,
92 RTL_TEXTENCODING_UTF8
)
93 + "/META-INF/MANIFEST.MF";
94 ::ucbhelper::Content manifestContent
;
98 &manifestContent
, buf
, xCmdEnv
,
99 false /* no throw */ )
100 && readLine( &line
, name
, manifestContent
, RTL_TEXTENCODING_ASCII_US
);
104 class BackendImpl
: public ::dp_registry::backend::PackageRegistryBackend
106 class ComponentPackageImpl
: public ::dp_registry::backend::Package
108 BackendImpl
* getMyBackend() const;
110 const OUString m_loader
;
112 enum class Reg
{ Uninit
, Void
, Registered
, NotRegistered
, MaybeRegistered
};
115 void getComponentInfo(
116 ComponentBackendDb::Data
* data
,
117 std::vector
< css::uno::Reference
< css::uno::XInterface
> > *
119 Reference
<XComponentContext
> const & xContext
);
121 void componentLiveInsertion(
122 ComponentBackendDb::Data
const & data
,
123 std::vector
< css::uno::Reference
< css::uno::XInterface
> > const &
126 void componentLiveRemoval(ComponentBackendDb::Data
const & data
);
129 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
130 ::osl::ResettableMutexGuard
& guard
,
131 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
132 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
133 virtual void processPackage_(
134 ::osl::ResettableMutexGuard
& guard
,
135 bool registerPackage
,
137 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
138 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
140 Reference
<registry::XSimpleRegistry
> getRDB() const;
143 ComponentPackageImpl(
144 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
145 OUString
const & url
, OUString
const & name
,
146 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
147 OUString loader
, bool bRemoved
,
148 OUString
const & identifier
);
150 friend class ComponentPackageImpl
;
152 class ComponentsPackageImpl
: public ::dp_registry::backend::Package
154 BackendImpl
* getMyBackend() const;
157 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
158 ::osl::ResettableMutexGuard
& guard
,
159 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
160 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
161 virtual void processPackage_(
162 ::osl::ResettableMutexGuard
& guard
,
163 bool registerPackage
,
165 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
166 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
168 ComponentsPackageImpl(
169 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
170 OUString
const & url
, OUString
const & name
,
171 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
172 bool bRemoved
, OUString
const & identifier
);
174 friend class ComponentsPackageImpl
;
176 class TypelibraryPackageImpl
: public ::dp_registry::backend::Package
178 BackendImpl
* getMyBackend() const;
180 const bool m_jarFile
;
183 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
184 ::osl::ResettableMutexGuard
& guard
,
185 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
186 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
187 virtual void processPackage_(
188 ::osl::ResettableMutexGuard
& guard
,
189 bool registerPackage
,
191 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
192 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
195 TypelibraryPackageImpl(
196 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
197 OUString
const & url
, OUString
const & name
,
198 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
199 bool jarFile
, bool bRemoved
,
200 OUString
const & identifier
);
202 friend class TypelibraryPackageImpl
;
204 /** Serves for unregistering packages that were registered on a
205 different platform. This can happen if one has remotely mounted
208 class OtherPlatformPackageImpl
: public ::dp_registry::backend::Package
211 OtherPlatformPackageImpl(
212 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
213 OUString
const & url
, OUString
const & name
,
214 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
215 bool bRemoved
, OUString
const & identifier
, OUString platform
);
218 BackendImpl
* getMyBackend() const;
220 Reference
<registry::XSimpleRegistry
> impl_openRDB() const;
221 Reference
<XInterface
> impl_createInstance(OUString
const& rService
) const;
224 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
225 ::osl::ResettableMutexGuard
& guard
,
226 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
227 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
228 virtual void processPackage_(
229 ::osl::ResettableMutexGuard
& guard
,
230 bool registerPackage
,
232 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
233 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
236 OUString
const m_aPlatform
;
238 friend class OtherPlatformPackageImpl
;
240 std::deque
<OUString
> m_jar_typelibs
;
241 std::deque
<OUString
> m_rdb_typelibs
;
242 std::deque
<OUString
> m_components
;
244 enum RcItem
{ RCITEM_JAR_TYPELIB
, RCITEM_RDB_TYPELIB
, RCITEM_COMPONENTS
};
246 std::deque
<OUString
> & getRcItemList( RcItem kind
) {
249 case RCITEM_JAR_TYPELIB
:
250 return m_jar_typelibs
;
251 case RCITEM_RDB_TYPELIB
:
252 return m_rdb_typelibs
;
253 default: // case RCITEM_COMPONENTS
259 bool m_unorc_modified
;
260 bool bSwitchedRdbFiles
;
262 typedef std::unordered_map
< OUString
, Reference
<XInterface
> > t_string2object
;
263 t_string2object m_backendObjects
;
265 // PackageRegistryBackend
266 virtual Reference
<deployment::XPackage
> bindPackage_(
267 OUString
const & url
, OUString
const & mediaType
,
268 bool bRemoved
, OUString
const & identifier
,
269 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
271 virtual void SAL_CALL
disposing() override
;
273 const Reference
<deployment::XPackageTypeInfo
> m_xDynComponentTypeInfo
;
274 const Reference
<deployment::XPackageTypeInfo
> m_xJavaComponentTypeInfo
;
275 const Reference
<deployment::XPackageTypeInfo
> m_xPythonComponentTypeInfo
;
276 const Reference
<deployment::XPackageTypeInfo
> m_xComponentsTypeInfo
;
277 const Reference
<deployment::XPackageTypeInfo
> m_xRDBTypelibTypeInfo
;
278 const Reference
<deployment::XPackageTypeInfo
> m_xJavaTypelibTypeInfo
;
279 Sequence
< Reference
<deployment::XPackageTypeInfo
> > m_typeInfos
;
281 OUString m_commonRDB
;
282 OUString m_nativeRDB
;
284 //URLs of the original rdbs (before any switching):
285 OUString m_commonRDB_orig
;
286 OUString m_nativeRDB_orig
;
288 std::unique_ptr
<ComponentBackendDb
> m_backendDb
;
290 void addDataToDb(OUString
const & url
, ComponentBackendDb::Data
const & data
);
291 ComponentBackendDb::Data
readDataFromDb(std::u16string_view url
);
292 void revokeEntryFromDb(std::u16string_view url
);
294 Reference
<registry::XSimpleRegistry
> m_xCommonRDB
;
295 Reference
<registry::XSimpleRegistry
> m_xNativeRDB
;
297 void unorc_verify_init( Reference
<XCommandEnvironment
> const & xCmdEnv
);
298 void unorc_flush( Reference
<XCommandEnvironment
> const & xCmdEnv
);
300 Reference
<XInterface
> getObject( OUString
const & id
);
301 Reference
<XInterface
> insertObject(
302 OUString
const & id
, Reference
<XInterface
> const & xObject
);
303 void releaseObject( OUString
const & id
);
305 void addToUnoRc( RcItem kind
, OUString
const & url
,
306 Reference
<XCommandEnvironment
> const & xCmdEnv
);
307 void removeFromUnoRc( RcItem kind
, OUString
const & url
,
308 Reference
<XCommandEnvironment
> const & xCmdEnv
);
309 bool hasInUnoRc( RcItem kind
, OUString
const & url
);
311 css::uno::Reference
< css::uno::XComponentContext
> getRootContext() const;
314 BackendImpl( Sequence
<Any
> const & args
,
315 Reference
<XComponentContext
> const & xComponentContext
);
318 virtual OUString SAL_CALL
getImplementationName() override
;
319 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
320 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
323 virtual Sequence
< Reference
<deployment::XPackageTypeInfo
> > SAL_CALL
324 getSupportedPackageTypes() override
;
326 virtual void SAL_CALL
packageRemoved(OUString
const & url
, OUString
const & mediaType
) override
;
328 using PackageRegistryBackend::disposing
;
330 //Will be called from ComponentPackageImpl
331 void initServiceRdbFiles();
335 BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
336 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
337 OUString
const & url
, OUString
const & name
,
338 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
339 OUString loader
, bool bRemoved
,
340 OUString
const & identifier
)
341 : Package( myBackend
, url
, name
, name
/* display-name */,
342 xPackageType
, bRemoved
, identifier
),
343 m_loader(std::move( loader
)),
344 m_registered( Reg::Uninit
)
347 Reference
<registry::XSimpleRegistry
>
348 BackendImpl::ComponentPackageImpl::getRDB() const
350 BackendImpl
* that
= getMyBackend();
352 //Late "initialization" of the services rdb files
353 //This is to prevent problems when running several
354 //instances of OOo with root rights in parallel. This
355 //would otherwise cause problems when copying the rdbs.
356 //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
358 const ::osl::MutexGuard
guard( m_aMutex
);
359 if (!that
->bSwitchedRdbFiles
)
361 that
->bSwitchedRdbFiles
= true;
362 that
->initServiceRdbFiles();
365 if ( m_loader
== "com.sun.star.loader.SharedLibrary" )
366 return that
->m_xNativeRDB
;
368 return that
->m_xCommonRDB
;
371 BackendImpl
* BackendImpl::ComponentPackageImpl::getMyBackend() const
373 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
374 if (nullptr == pBackend
)
376 //Throws a DisposedException
378 //We should never get here...
379 throw RuntimeException(
380 u
"Failed to get the BackendImpl"_ustr
,
381 static_cast<OWeakObject
*>(const_cast<ComponentPackageImpl
*>(this)));
387 void BackendImpl::disposing()
390 m_backendObjects
= t_string2object();
391 if (m_xNativeRDB
.is()) {
392 m_xNativeRDB
->close();
393 m_xNativeRDB
.clear();
395 if (m_xCommonRDB
.is()) {
396 m_xCommonRDB
->close();
397 m_xCommonRDB
.clear();
399 unorc_flush( Reference
<XCommandEnvironment
>() );
401 PackageRegistryBackend::disposing();
403 catch (const RuntimeException
&) {
406 catch (const Exception
&) {
407 Any
exc( ::cppu::getCaughtException() );
408 throw lang::WrappedTargetRuntimeException(
409 u
"caught unexpected exception while disposing..."_ustr
,
410 static_cast<OWeakObject
*>(this), exc
);
415 void BackendImpl::initServiceRdbFiles()
417 const Reference
<XCommandEnvironment
> xCmdEnv
;
419 ::ucbhelper::Content
cacheDir( getCachePath(), xCmdEnv
, m_xComponentContext
);
420 ::ucbhelper::Content oldRDB
;
421 // switch common rdb:
422 if (!m_commonRDB_orig
.isEmpty())
424 (void)create_ucb_content(
425 &oldRDB
, makeURL( getCachePath(), m_commonRDB_orig
),
426 xCmdEnv
, false /* no throw */ );
428 m_commonRDB
= m_commonRDB_orig
== "common.rdb" ? std::u16string_view(u
"common_.rdb") : std::u16string_view(u
"common.rdb");
429 if (oldRDB
.get().is())
431 cacheDir
.transferContent(
432 oldRDB
, ::ucbhelper::InsertOperation::Copy
,
433 m_commonRDB
, NameClash::OVERWRITE
);
434 oldRDB
= ::ucbhelper::Content();
436 // switch native rdb:
437 if (!m_nativeRDB_orig
.isEmpty())
439 (void)create_ucb_content(
440 &oldRDB
, makeURL(getCachePath(), m_nativeRDB_orig
),
441 xCmdEnv
, false /* no throw */ );
443 const OUString
plt_rdb( getPlatformString() + ".rdb" );
444 const OUString
plt_rdb_( getPlatformString() + "_.rdb" );
445 m_nativeRDB
= (m_nativeRDB_orig
== plt_rdb
) ? plt_rdb_
: plt_rdb
;
446 if (oldRDB
.get().is())
448 cacheDir
.transferContent(
449 oldRDB
, ::ucbhelper::InsertOperation::Copy
,
450 m_nativeRDB
, NameClash::OVERWRITE
);
453 // UNO is bootstrapped, flush for next process start:
454 m_unorc_modified
= true;
455 unorc_flush( Reference
<XCommandEnvironment
>() );
458 // common rdb for java, native rdb for shared lib components
459 if (!m_commonRDB
.isEmpty()) {
461 m_xComponentContext
->getServiceManager()
462 ->createInstanceWithContext(
463 u
"com.sun.star.registry.SimpleRegistry"_ustr
,
464 m_xComponentContext
), UNO_QUERY_THROW
);
466 makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB
),
469 if (!m_nativeRDB
.isEmpty()) {
471 m_xComponentContext
->getServiceManager()
472 ->createInstanceWithContext(
473 u
"com.sun.star.registry.SimpleRegistry"_ustr
,
474 m_xComponentContext
), UNO_QUERY_THROW
);
476 makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB
),
481 BackendImpl::BackendImpl(
482 Sequence
<Any
> const & args
,
483 Reference
<XComponentContext
> const & xComponentContext
)
484 : PackageRegistryBackend( args
, xComponentContext
),
485 m_unorc_inited( false ),
486 m_unorc_modified( false ),
487 bSwitchedRdbFiles(false),
488 m_xDynComponentTypeInfo( new Package::TypeInfo(
489 "application/vnd.sun.star.uno-component;type=native;platform=" +
491 u
"*" SAL_DLLEXTENSION
""_ustr
,
492 DpResId(RID_STR_DYN_COMPONENT
)
494 m_xJavaComponentTypeInfo( new Package::TypeInfo(
495 u
"application/vnd.sun.star.uno-component;type=Java"_ustr
,
497 DpResId(RID_STR_JAVA_COMPONENT
)
499 m_xPythonComponentTypeInfo( new Package::TypeInfo(
500 u
"application/vnd.sun.star.uno-component;type=Python"_ustr
,
503 RID_STR_PYTHON_COMPONENT
)
505 m_xComponentsTypeInfo( new Package::TypeInfo(
506 u
"application/vnd.sun.star.uno-components"_ustr
,
507 u
"*.components"_ustr
,
508 DpResId(RID_STR_COMPONENTS
)
510 m_xRDBTypelibTypeInfo( new Package::TypeInfo(
511 u
"application/vnd.sun.star.uno-typelibrary;type=RDB"_ustr
,
513 DpResId(RID_STR_RDB_TYPELIB
)
515 m_xJavaTypelibTypeInfo( new Package::TypeInfo(
516 u
"application/vnd.sun.star.uno-typelibrary;type=Java"_ustr
,
518 DpResId(RID_STR_JAVA_TYPELIB
)
520 m_typeInfos
{ m_xDynComponentTypeInfo
, m_xJavaComponentTypeInfo
, m_xPythonComponentTypeInfo
,
521 m_xComponentsTypeInfo
, m_xRDBTypelibTypeInfo
, m_xJavaTypelibTypeInfo
}
523 const Reference
<XCommandEnvironment
> xCmdEnv
;
528 // common rdb for java, native rdb for shared lib components
530 xComponentContext
->getServiceManager()->createInstanceWithContext(
531 u
"com.sun.star.registry.SimpleRegistry"_ustr
,
532 xComponentContext
), UNO_QUERY_THROW
);
533 m_xCommonRDB
->open( OUString() /* in-mem */,
534 false /* ! read-only */, true /* create */ );
536 xComponentContext
->getServiceManager()->createInstanceWithContext(
537 u
"com.sun.star.registry.SimpleRegistry"_ustr
,
538 xComponentContext
), UNO_QUERY_THROW
);
539 m_xNativeRDB
->open( OUString() /* in-mem */,
540 false /* ! read-only */, true /* create */ );
544 unorc_verify_init( xCmdEnv
);
545 OUString dbFile
= makeURL(getCachePath(), u
"backenddb.xml"_ustr
);
547 new ComponentBackendDb(getComponentContext(), dbFile
));
552 OUString
BackendImpl::getImplementationName()
554 return u
"com.sun.star.comp.deployment.component.PackageRegistryBackend"_ustr
;
557 sal_Bool
BackendImpl::supportsService( const OUString
& ServiceName
)
559 return cppu::supportsService(this, ServiceName
);
562 css::uno::Sequence
< OUString
> BackendImpl::getSupportedServiceNames()
564 return { BACKEND_SERVICE_NAME
};
567 void BackendImpl::addDataToDb(
568 OUString
const & url
, ComponentBackendDb::Data
const & data
)
571 m_backendDb
->addEntry(url
, data
);
574 ComponentBackendDb::Data
BackendImpl::readDataFromDb(std::u16string_view url
)
576 ComponentBackendDb::Data data
;
578 data
= m_backendDb
->getEntry(url
);
582 void BackendImpl::revokeEntryFromDb(std::u16string_view url
)
585 m_backendDb
->revokeEntry(url
);
590 Sequence
< Reference
<deployment::XPackageTypeInfo
> >
591 BackendImpl::getSupportedPackageTypes()
596 void BackendImpl::packageRemoved(OUString
const & url
, OUString
const & /*mediaType*/)
599 m_backendDb
->removeEntry(url
);
602 // PackageRegistryBackend
604 Reference
<deployment::XPackage
> BackendImpl::bindPackage_(
605 OUString
const & url
, OUString
const & mediaType_
,
606 bool bRemoved
, OUString
const & identifier
,
607 Reference
<XCommandEnvironment
> const & xCmdEnv
)
609 OUString
mediaType(mediaType_
);
610 if ( mediaType
.isEmpty() || mediaType
== "application/vnd.sun.star.uno-component" || mediaType
== "application/vnd.sun.star.uno-typelibrary" )
612 // detect exact media-type:
613 ::ucbhelper::Content ucbContent
;
614 if (create_ucb_content( &ucbContent
, url
, xCmdEnv
)) {
615 const OUString
title( StrTitle::getTitle( ucbContent
) );
616 if (title
.endsWithIgnoreAsciiCase(SAL_DLLEXTENSION
))
618 mediaType
= "application/vnd.sun.star.uno-component;type=native;platform=" +
621 else if (title
.endsWithIgnoreAsciiCase(".jar"))
623 if (jarManifestHeaderPresent(
624 url
, u
"RegistrationClassName", xCmdEnv
))
625 mediaType
= "application/vnd.sun.star.uno-component;type=Java";
626 if (mediaType
.isEmpty())
627 mediaType
= "application/vnd.sun.star.uno-typelibrary;type=Java";
629 else if (title
.endsWithIgnoreAsciiCase(".py"))
630 mediaType
= "application/vnd.sun.star.uno-component;type=Python";
631 else if (title
.endsWithIgnoreAsciiCase(".rdb"))
632 mediaType
= "application/vnd.sun.star.uno-typelibrary;type=RDB";
634 if (mediaType
.isEmpty())
635 throw lang::IllegalArgumentException(
636 StrCannotDetectMediaType() + url
,
637 static_cast<OWeakObject
*>(this), static_cast<sal_Int16
>(-1) );
640 OUString type
, subType
;
641 INetContentTypeParameterList params
;
642 if (INetContentTypes::parse( mediaType
, type
, subType
, ¶ms
))
644 if (type
.equalsIgnoreAsciiCase("application"))
649 ::ucbhelper::Content
ucbContent( url
, xCmdEnv
, m_xComponentContext
);
650 name
= StrTitle::getTitle( ucbContent
);
653 if (subType
.equalsIgnoreAsciiCase("vnd.sun.star.uno-component"))
655 // xxx todo: probe and evaluate component xml description
657 auto const iter
= params
.find("platform"_ostr
);
658 bool bPlatformFits(iter
== params
.end());
660 if (!bPlatformFits
) // platform is specified, we have to check
662 aPlatform
= iter
->second
.m_sValue
;
663 bPlatformFits
= platform_fits(aPlatform
);
665 // If the package is being removed, do not care whether
666 // platform fits. We won't be using it anyway.
667 if (bPlatformFits
|| bRemoved
) {
668 auto const iterType
= params
.find("type"_ostr
);
669 if (iterType
!= params
.end())
671 OUString
const & value
= iterType
->second
.m_sValue
;
672 if (value
.equalsIgnoreAsciiCase("native")) {
674 return new BackendImpl::ComponentPackageImpl(
675 this, url
, name
, m_xDynComponentTypeInfo
,
676 u
"com.sun.star.loader.SharedLibrary"_ustr
,
677 bRemoved
, identifier
);
679 return new BackendImpl::OtherPlatformPackageImpl(
680 this, url
, name
, m_xDynComponentTypeInfo
,
681 bRemoved
, identifier
, aPlatform
);
683 if (value
.equalsIgnoreAsciiCase("Java")) {
684 return new BackendImpl::ComponentPackageImpl(
685 this, url
, name
, m_xJavaComponentTypeInfo
,
686 u
"com.sun.star.loader.Java2"_ustr
,
687 bRemoved
, identifier
);
689 if (value
.equalsIgnoreAsciiCase("Python")) {
690 return new BackendImpl::ComponentPackageImpl(
691 this, url
, name
, m_xPythonComponentTypeInfo
,
692 u
"com.sun.star.loader.Python"_ustr
,
693 bRemoved
, identifier
);
698 else if (subType
.equalsIgnoreAsciiCase("vnd.sun.star.uno-components"))
700 auto const iter
= params
.find("platform"_ostr
);
701 if (iter
== params
.end() || platform_fits(iter
->second
.m_sValue
)) {
702 return new BackendImpl::ComponentsPackageImpl(
703 this, url
, name
, m_xComponentsTypeInfo
, bRemoved
,
707 else if (subType
.equalsIgnoreAsciiCase( "vnd.sun.star.uno-typelibrary"))
709 auto const iter
= params
.find("type"_ostr
);
710 if (iter
!= params
.end()) {
711 OUString
const & value
= iter
->second
.m_sValue
;
712 if (value
.equalsIgnoreAsciiCase("RDB"))
714 return new BackendImpl::TypelibraryPackageImpl(
715 this, url
, name
, m_xRDBTypelibTypeInfo
,
716 false /* rdb */, bRemoved
, identifier
);
718 if (value
.equalsIgnoreAsciiCase("Java")) {
719 return new BackendImpl::TypelibraryPackageImpl(
720 this, url
, name
, m_xJavaTypelibTypeInfo
,
721 true /* jar */, bRemoved
, identifier
);
727 throw lang::IllegalArgumentException(
728 StrUnsupportedMediaType() + mediaType
,
729 static_cast<OWeakObject
*>(this),
730 static_cast<sal_Int16
>(-1) );
734 void BackendImpl::unorc_verify_init(
735 Reference
<XCommandEnvironment
> const & xCmdEnv
)
739 const ::osl::MutexGuard
guard( m_aMutex
);
744 ::ucbhelper::Content ucb_content
;
745 if (create_ucb_content(
747 makeURL( getCachePath(), u
"unorc"_ustr
),
748 xCmdEnv
, false /* no throw */ ))
751 if (readLine( &line
, u
"UNO_JAVA_CLASSPATH=", ucb_content
,
752 RTL_TEXTENCODING_UTF8
))
754 sal_Int32 index
= sizeof ("UNO_JAVA_CLASSPATH=") - 1;
756 OUString
token( o3tl::trim(o3tl::getToken(line
, 0, ' ', index
)) );
757 if (!token
.isEmpty())
759 if (create_ucb_content(
760 nullptr, expandUnoRcTerm(token
), xCmdEnv
,
761 false /* no throw */ ))
763 //The jar file may not exist anymore if a shared or bundled
764 //extension was removed, but it can still be in the unorc
765 //After running XExtensionManager::synchronize, the unorc is
767 m_jar_typelibs
.push_back( token
);
773 if (readLine( &line
, u
"UNO_TYPES=", ucb_content
,
774 RTL_TEXTENCODING_UTF8
)) {
775 sal_Int32 index
= sizeof ("UNO_TYPES=") - 1;
777 OUString
token( o3tl::trim(o3tl::getToken(line
, 0, ' ', index
)) );
778 if (!token
.isEmpty())
780 if (token
[ 0 ] == '?')
781 token
= token
.copy( 1 );
782 if (create_ucb_content(
783 nullptr, expandUnoRcTerm(token
), xCmdEnv
,
784 false /* no throw */ ))
786 //The RDB file may not exist anymore if a shared or bundled
787 //extension was removed, but it can still be in the unorc.
788 //After running XExtensionManager::synchronize, the unorc is
790 m_rdb_typelibs
.push_back( token
);
796 if (readLine( &line
, u
"UNO_SERVICES=", ucb_content
,
797 RTL_TEXTENCODING_UTF8
))
799 // The UNO_SERVICES line always has the BNF form
801 // ("?$ORIGIN/" <common-rdb>)? -- first
802 // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second
803 // ("?" ("BUNDLED_EXTENSIONS" | -- third
804 // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
806 // so can unambiguously be split into its three parts:
808 for (sal_Int32 i
= RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
811 OUString
token(line
.getToken(0, ' ', i
));
812 if (!token
.isEmpty())
814 if (state
== 1 && token
.match("?$ORIGIN/"))
816 m_commonRDB_orig
= token
.copy(
817 RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
820 else if ( state
<= 2 && token
== "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" )
828 token
= token
.copy(1);
830 m_components
.push_back(token
);
838 if (create_ucb_content(
840 makeURL( getCachePath(), getPlatformString() + "rc"),
841 xCmdEnv
, false /* no throw */ )) {
842 if (readLine( &line
, u
"UNO_SERVICES=", ucb_content
,
843 RTL_TEXTENCODING_UTF8
)) {
844 m_nativeRDB_orig
= line
.copy(
845 sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
849 m_unorc_modified
= false;
850 m_unorc_inited
= true;
854 void BackendImpl::unorc_flush( Reference
<XCommandEnvironment
> const & xCmdEnv
)
858 if (!m_unorc_inited
|| !m_unorc_modified
)
861 OUString sOrigin
= dp_misc::makeRcTerm(m_cachePath
);
862 OString osOrigin
= OUStringToOString(sOrigin
, RTL_TEXTENCODING_UTF8
);
863 OStringBuffer
buf("ORIGIN=" + osOrigin
+ OStringChar(LF
));
865 if (! m_jar_typelibs
.empty())
867 auto iPos( m_jar_typelibs
.cbegin() );
868 auto const iEnd( m_jar_typelibs
.cend() );
869 buf
.append( "UNO_JAVA_CLASSPATH=" );
870 while (iPos
!= iEnd
) {
871 // encoded ASCII file-urls:
873 OUStringToOString( *iPos
, RTL_TEXTENCODING_ASCII_US
) );
881 if (! m_rdb_typelibs
.empty())
883 auto iPos( m_rdb_typelibs
.cbegin() );
884 auto const iEnd( m_rdb_typelibs
.cend() );
885 buf
.append( "UNO_TYPES=" );
886 while (iPos
!= iEnd
) {
888 // encoded ASCII file-urls:
890 OUStringToOString( *iPos
, RTL_TEXTENCODING_ASCII_US
) );
899 // If we duplicated the common or native rdb then we must use those urls
900 //otherwise we use those of the original files. That is, m_commonRDB_orig
901 //and m_nativeRDB_orig;
902 OUString
sCommonRDB(m_commonRDB
.isEmpty() ? m_commonRDB_orig
: m_commonRDB
);
903 OUString
sNativeRDB(m_nativeRDB
.isEmpty() ? m_nativeRDB_orig
: m_nativeRDB
);
905 if (!sCommonRDB
.isEmpty() || !sNativeRDB
.isEmpty() ||
906 !m_components
.empty())
908 buf
.append( "UNO_SERVICES=" );
910 if (!sCommonRDB
.isEmpty())
912 buf
.append( "?$ORIGIN/"
913 + OUStringToOString( sCommonRDB
, RTL_TEXTENCODING_ASCII_US
) );
916 if (!sNativeRDB
.isEmpty())
922 buf
.append( "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" );
930 "UNO_SERVICES=?$ORIGIN/" +
931 OUStringToOString( sNativeRDB
, RTL_TEXTENCODING_ASCII_US
) +
934 const Reference
<io::XInputStream
> xData(
935 ::xmlscript::createInputStream(
936 reinterpret_cast<sal_Int8
const *>(buf2
.getStr()),
937 buf2
.getLength() ) );
938 ::ucbhelper::Content
ucb_content(
939 makeURL( getCachePath(), getPlatformString() + "rc" ),
940 xCmdEnv
, m_xComponentContext
);
941 ucb_content
.writeStream( xData
, true /* replace existing */ );
943 for (auto const& component
: m_components
)
949 buf
.append("?" + OUStringToOString(component
, RTL_TEXTENCODING_UTF8
));
956 const Reference
<io::XInputStream
> xData(
957 ::xmlscript::createInputStream(
958 reinterpret_cast<sal_Int8
const *>(buf
.getStr()),
960 ::ucbhelper::Content
ucb_content(
961 makeURL( getCachePath(), u
"unorc"_ustr
), xCmdEnv
, m_xComponentContext
);
962 ucb_content
.writeStream( xData
, true /* replace existing */ );
964 m_unorc_modified
= false;
968 void BackendImpl::addToUnoRc( RcItem kind
, OUString
const & url_
,
969 Reference
<XCommandEnvironment
> const & xCmdEnv
)
971 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
972 const ::osl::MutexGuard
guard( m_aMutex
);
973 unorc_verify_init( xCmdEnv
);
974 std::deque
<OUString
> & rSet
= getRcItemList(kind
);
975 if (std::find( rSet
.begin(), rSet
.end(), rcterm
) == rSet
.end()) {
976 rSet
.push_front( rcterm
); // prepend to list, thus overriding
977 // write immediately:
978 m_unorc_modified
= true;
979 unorc_flush( xCmdEnv
);
984 void BackendImpl::removeFromUnoRc(
985 RcItem kind
, OUString
const & url_
,
986 Reference
<XCommandEnvironment
> const & xCmdEnv
)
988 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
989 const ::osl::MutexGuard
guard( m_aMutex
);
990 unorc_verify_init( xCmdEnv
);
991 std::deque
<OUString
> & aRcItemList
= getRcItemList(kind
);
992 std::erase(aRcItemList
, rcterm
);
993 // write immediately:
994 m_unorc_modified
= true;
995 unorc_flush( xCmdEnv
);
999 bool BackendImpl::hasInUnoRc(
1000 RcItem kind
, OUString
const & url_
)
1002 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
1003 const ::osl::MutexGuard
guard( m_aMutex
);
1004 std::deque
<OUString
> const & rSet
= getRcItemList(kind
);
1005 return std::find( rSet
.begin(), rSet
.end(), rcterm
) != rSet
.end();
1008 css::uno::Reference
< css::uno::XComponentContext
> BackendImpl::getRootContext()
1011 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1012 getComponentContext()->getValueByName(u
"_root"_ustr
),
1013 css::uno::UNO_QUERY
);
1014 return rootContext
.is() ? rootContext
: getComponentContext();
1018 void BackendImpl::releaseObject( OUString
const & id
)
1020 const ::osl::MutexGuard
guard( m_aMutex
);
1021 m_backendObjects
.erase( id
);
1025 Reference
<XInterface
> BackendImpl::getObject( OUString
const & id
)
1027 const ::osl::MutexGuard
guard( m_aMutex
);
1028 const t_string2object::const_iterator
iFind( m_backendObjects
.find( id
) );
1029 if (iFind
== m_backendObjects
.end())
1030 return Reference
<XInterface
>();
1032 return iFind
->second
;
1036 Reference
<XInterface
> BackendImpl::insertObject(
1037 OUString
const & id
, Reference
<XInterface
> const & xObject
)
1039 const ::osl::MutexGuard
guard( m_aMutex
);
1040 const std::pair
<t_string2object::iterator
, bool> insertion(
1041 m_backendObjects
.emplace( id
, xObject
) );
1042 return insertion
.first
->second
;
1046 Reference
<XComponentContext
> raise_uno_process(
1047 Reference
<XComponentContext
> const & xContext
,
1048 ::rtl::Reference
<AbortChannel
> const & abortChannel
)
1050 OSL_ASSERT( xContext
.is() );
1052 OUString
url( util::theMacroExpander::get(xContext
)->expandMacros( u
"$URE_BIN_DIR/uno"_ustr
) );
1054 const OUString connectStr
= "uno:pipe,name=" + generateRandomPipeId() + ";urp;uno.ComponentContext";
1056 // raise core UNO process to register/run a component,
1057 // javavm service uses unorc next to executable to retrieve deployed
1060 std::vector
<OUString
> args
{
1061 #if OSL_DEBUG_LEVEL == 0
1064 u
"--singleaccept"_ustr
,
1067 // don't inherit from unorc:
1068 u
"-env:INIFILENAME="_ustr
};
1070 //now add the bootstrap variables which were supplied on the command line
1071 std::vector
<OUString
> bootvars
= getCmdBootstrapVariables();
1072 args
.insert(args
.end(), bootvars
.begin(), bootvars
.end());
1074 oslProcess hProcess
;
1076 hProcess
= raiseProcess(
1077 url
, comphelper::containerToSequence(args
) );
1080 OUStringBuffer sMsg
= "error starting process: " + url
;
1081 for(const auto& arg
: args
)
1082 sMsg
.append(" " + arg
);
1083 throw uno::RuntimeException(sMsg
.makeStringAndClear());
1086 return Reference
<XComponentContext
>(
1087 resolveUnoURL( connectStr
, xContext
, abortChannel
.get() ),
1091 // try to terminate process:
1092 if ( osl_terminateProcess( hProcess
) != osl_Process_E_None
)
1094 OSL_ASSERT( false );
1100 void extractComponentData(
1101 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
1102 css::uno::Reference
< css::registry::XRegistryKey
> const & registry
,
1103 ComponentBackendDb::Data
* data
,
1104 std::vector
< css::uno::Reference
< css::uno::XInterface
> > * factories
,
1105 css::uno::Reference
< css::loader::XImplementationLoader
> const &
1107 OUString
const & componentUrl
)
1110 context
.is() && registry
.is() && data
!= nullptr && componentLoader
.is());
1111 OUString
registryName(registry
->getKeyName());
1112 sal_Int32 prefix
= registryName
.getLength();
1113 if (!registryName
.endsWith("/")) {
1114 prefix
+= RTL_CONSTASCII_LENGTH("/");
1116 const css::uno::Sequence
< css::uno::Reference
< css::registry::XRegistryKey
> >
1117 keys(registry
->openKeys());
1118 css::uno::Reference
< css::lang::XMultiComponentFactory
> smgr(
1119 context
->getServiceManager(), css::uno::UNO_SET_THROW
);
1120 for (css::uno::Reference
< css::registry::XRegistryKey
> const & key
: keys
) {
1121 OUString
name(key
->getKeyName().copy(prefix
));
1122 data
->implementationNames
.push_back(name
);
1123 css::uno::Reference
< css::registry::XRegistryKey
> singletons(
1124 key
->openKey(u
"UNO/SINGLETONS"_ustr
));
1125 if (singletons
.is()) {
1126 sal_Int32 prefix2
= key
->getKeyName().getLength() +
1127 RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
1128 const css::uno::Sequence
<
1129 css::uno::Reference
< css::registry::XRegistryKey
> >
1130 singletonKeys(singletons
->openKeys());
1131 for (css::uno::Reference
< css::registry::XRegistryKey
> const & singletonKey
: singletonKeys
) {
1132 data
->singletons
.emplace_back(
1133 singletonKey
->getKeyName().copy(prefix2
), name
);
1136 if (factories
!= nullptr) {
1137 factories
->push_back(
1138 componentLoader
->activate(
1139 name
, OUString(), componentUrl
, key
));
1144 void BackendImpl::ComponentPackageImpl::getComponentInfo(
1145 ComponentBackendDb::Data
* data
,
1146 std::vector
< css::uno::Reference
< css::uno::XInterface
> > * factories
,
1147 Reference
<XComponentContext
> const & xContext
)
1149 const Reference
<loader::XImplementationLoader
> xLoader(
1150 xContext
->getServiceManager()->createInstanceWithContext(
1151 m_loader
, xContext
), UNO_QUERY
);
1154 throw css::deployment::DeploymentException(
1155 "cannot instantiate loader " + m_loader
,
1156 static_cast< OWeakObject
* >(this), Any());
1159 // HACK: highly dependent on stoc/source/servicemanager
1160 // and stoc/source/implreg implementation which rely on the same
1161 // services.rdb format!
1162 // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
1163 // writeRegistryInfo, however, but are known, fixed values here, so
1164 // can be passed into extractComponentData
1165 OUString
url(getURL());
1166 const Reference
<registry::XSimpleRegistry
> xMemReg(
1167 xContext
->getServiceManager()->createInstanceWithContext(
1168 u
"com.sun.star.registry.SimpleRegistry"_ustr
, xContext
),
1170 xMemReg
->open( OUString() /* in mem */, false, true );
1171 xLoader
->writeRegistryInfo( xMemReg
->getRootKey(), OUString(), url
);
1172 extractComponentData(
1173 xContext
, xMemReg
->getRootKey(), data
, factories
, xLoader
, url
);
1176 void BackendImpl::ComponentPackageImpl::componentLiveInsertion(
1177 ComponentBackendDb::Data
const & data
,
1178 std::vector
< css::uno::Reference
< css::uno::XInterface
> > const &
1181 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1182 getMyBackend()->getRootContext());
1183 css::uno::Reference
< css::container::XSet
> set(
1184 rootContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1185 std::vector
< css::uno::Reference
< css::uno::XInterface
> >::const_iterator
1186 factory(factories
.begin());
1187 for (auto const& implementationName
: data
.implementationNames
)
1190 set
->insert(css::uno::Any(*factory
++));
1191 } catch (const container::ElementExistException
&) {
1192 SAL_WARN("desktop.deployment", "implementation already registered " << implementationName
);
1195 if (data
.singletons
.empty()) return;
1197 css::uno::Reference
< css::container::XNameContainer
> cont(
1198 rootContext
, css::uno::UNO_QUERY_THROW
);
1199 for (auto const& singleton
: data
.singletons
)
1201 OUString
name("/singletons/" + singleton
.first
);
1202 //TODO: Update should be atomic:
1204 cont
->removeByName( name
+ "/arguments");
1205 } catch (const container::NoSuchElementException
&) {}
1207 cont
->insertByName( name
+ "/service", css::uno::Any(singleton
.second
));
1208 } catch (const container::ElementExistException
&) {
1209 cont
->replaceByName( name
+ "/service", css::uno::Any(singleton
.second
));
1212 cont
->insertByName(name
, css::uno::Any());
1213 } catch (const container::ElementExistException
&) {
1214 SAL_WARN("desktop.deployment", "singleton already registered " << singleton
.first
);
1215 cont
->replaceByName(name
, css::uno::Any());
1220 void BackendImpl::ComponentPackageImpl::componentLiveRemoval(
1221 ComponentBackendDb::Data
const & data
)
1223 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1224 getMyBackend()->getRootContext());
1225 css::uno::Reference
< css::container::XSet
> set(
1226 rootContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1227 for (auto const& implementationName
: data
.implementationNames
)
1230 set
->remove(css::uno::Any(implementationName
));
1231 } catch (const css::container::NoSuchElementException
&) {
1232 // ignore if factory has not been live deployed
1235 if (data
.singletons
.empty())
1238 css::uno::Reference
< css::container::XNameContainer
> cont(
1239 rootContext
, css::uno::UNO_QUERY_THROW
);
1240 for (auto const& singleton
: data
.singletons
)
1242 OUString
name("/singletons/" + singleton
.first
);
1243 //TODO: Removal should be atomic:
1245 cont
->removeByName(name
);
1246 } catch (const container::NoSuchElementException
&) {}
1248 cont
->removeByName( name
+ "/service" );
1249 } catch (const container::NoSuchElementException
&) {}
1251 cont
->removeByName( name
+ "/arguments" );
1252 } catch (const container::NoSuchElementException
&) {}
1258 //We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
1259 //And it also shows the problem if another extension has overwritten an implementation
1260 //entry, because it contains the same service implementation
1261 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1262 BackendImpl::ComponentPackageImpl::isRegistered_(
1263 ::osl::ResettableMutexGuard
&,
1264 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1265 Reference
<XCommandEnvironment
> const & )
1267 if (m_registered
== Reg::Uninit
)
1269 m_registered
= Reg::NotRegistered
;
1270 const Reference
<registry::XSimpleRegistry
> xRDB( getRDB() );
1273 bool bAmbiguousComponentName
= false;
1274 // lookup rdb for location URL:
1275 const Reference
<registry::XRegistryKey
> xRootKey(
1276 xRDB
->getRootKey() );
1277 const Reference
<registry::XRegistryKey
> xImplKey(
1278 xRootKey
->openKey( u
"IMPLEMENTATIONS"_ustr
) );
1279 Sequence
<OUString
> implNames
;
1280 if (xImplKey
.is() && xImplKey
->isValid())
1281 implNames
= xImplKey
->getKeyNames();
1282 sal_Int32 pos
= implNames
.getLength();
1285 checkAborted( abortChannel
);
1286 const OUString
key(implNames
[pos
] + "/UNO/LOCATION");
1287 const Reference
<registry::XRegistryKey
> xKey(
1288 xRootKey
->openKey(key
) );
1289 if (xKey
.is() && xKey
->isValid())
1291 const OUString
location( xKey
->getAsciiValue() );
1292 if (location
.equalsIgnoreAsciiCase( getURL() ))
1298 //try to match only the file name
1299 OUString
thisUrl(getURL());
1300 std::u16string_view
thisFileName(thisUrl
.subView(thisUrl
.lastIndexOf('/')));
1302 std::u16string_view
locationFileName(location
.subView(location
.lastIndexOf('/')));
1303 if (o3tl::equalsIgnoreAsciiCase(locationFileName
, thisFileName
))
1304 bAmbiguousComponentName
= true;
1309 m_registered
= Reg::Registered
;
1310 else if (bAmbiguousComponentName
)
1311 m_registered
= Reg::MaybeRegistered
;
1315 //Different extensions can use the same service implementations. Then the extensions
1316 //which was installed last will overwrite the one from the other extension. That is
1317 //the registry will contain the path (the location) of the library or jar of the
1318 //second extension. In this case isRegistered called for the lib of the first extension
1319 //would return "not registered". That would mean that during uninstallation
1320 //XPackage::registerPackage is not called, because it just was not registered. This is,
1321 //however, necessary for jar files. Registering and unregistering update
1322 //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
1323 //Therefore, we will return always "is ambiguous" if the path of this component cannot
1324 //be found in the registry and if there is another path and both have the same file name (but
1325 //the rest of the path is different).
1326 //If the caller cannot precisely determine that this package was registered, then it must
1327 //call registerPackage.
1328 bool bAmbiguous
= m_registered
== Reg::Void
// Reg::Void == we are in the progress of unregistration
1329 || m_registered
== Reg::MaybeRegistered
;
1330 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1331 true /* IsPresent */,
1332 beans::Ambiguous
<sal_Bool
>(
1333 m_registered
== Reg::Registered
, bAmbiguous
) );
1337 void BackendImpl::ComponentPackageImpl::processPackage_(
1338 ::osl::ResettableMutexGuard
&,
1339 bool doRegisterPackage
,
1341 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1342 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1344 BackendImpl
* that
= getMyBackend();
1345 OUString
url(getURL());
1346 if (doRegisterPackage
) {
1347 ComponentBackendDb::Data data
;
1348 css::uno::Reference
< css::uno::XComponentContext
> context
;
1350 context
= that
->getComponentContext();
1352 context
.set(that
->getObject(url
), css::uno::UNO_QUERY
);
1353 if (!context
.is()) {
1358 that
->getComponentContext(), abortChannel
)),
1359 css::uno::UNO_QUERY_THROW
);
1362 css::uno::Reference
< css::registry::XImplementationRegistration
> impreg(
1363 context
->getServiceManager()->createInstanceWithContext(
1364 u
"com.sun.star.registry.ImplementationRegistration"_ustr
,
1366 css::uno::UNO_QUERY_THROW
);
1367 css::uno::Reference
< css::registry::XSimpleRegistry
> rdb(getRDB());
1368 impreg
->registerImplementation(m_loader
, url
, rdb
);
1369 // Only write to unorc after successful registration; it may fail if
1370 // there is no suitable java
1371 if (m_loader
== "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url
, u
"UNO-Type-Path", xCmdEnv
))
1373 that
->addToUnoRc(RCITEM_JAR_TYPELIB
, url
, xCmdEnv
);
1374 data
.javaTypeLibrary
= true;
1376 std::vector
< css::uno::Reference
< css::uno::XInterface
> > factories
;
1377 getComponentInfo(&data
, startup
? nullptr : &factories
, context
);
1380 componentLiveInsertion(data
, factories
);
1381 } catch (css::uno::Exception
&) {
1382 TOOLS_INFO_EXCEPTION("desktop.deployment", "caught");
1384 impreg
->revokeImplementation(url
, rdb
);
1385 } catch (css::uno::RuntimeException
&) {
1386 TOOLS_WARN_EXCEPTION("desktop.deployment", "ignored");
1391 m_registered
= Reg::Registered
;
1392 that
->addDataToDb(url
, data
);
1394 m_registered
= Reg::Void
;
1395 ComponentBackendDb::Data
data(that
->readDataFromDb(url
));
1396 css::uno::Reference
< css::uno::XComponentContext
> context(
1397 that
->getObject(url
), css::uno::UNO_QUERY
);
1398 bool remoteContext
= context
.is();
1399 if (!remoteContext
) {
1400 context
= that
->getComponentContext();
1403 componentLiveRemoval(data
);
1405 css::uno::Reference
< css::registry::XImplementationRegistration
>(
1406 context
->getServiceManager()->createInstanceWithContext(
1407 u
"com.sun.star.registry.ImplementationRegistration"_ustr
,
1409 css::uno::UNO_QUERY_THROW
)->revokeImplementation(url
, getRDB());
1410 if (data
.javaTypeLibrary
) {
1411 that
->removeFromUnoRc(RCITEM_JAR_TYPELIB
, url
, xCmdEnv
);
1413 if (remoteContext
) {
1414 that
->releaseObject(url
);
1416 m_registered
= Reg::NotRegistered
;
1417 getMyBackend()->revokeEntryFromDb(url
);
1421 BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
1422 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1423 OUString
const & url
, OUString
const & name
,
1424 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1425 bool jarFile
, bool bRemoved
, OUString
const & identifier
)
1426 : Package( myBackend
, url
, name
, name
/* display-name */,
1427 xPackageType
, bRemoved
, identifier
),
1428 m_jarFile( jarFile
)
1433 BackendImpl
* BackendImpl::TypelibraryPackageImpl::getMyBackend() const
1435 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1436 if (nullptr == pBackend
)
1438 //May throw a DisposedException
1440 //We should never get here...
1441 throw RuntimeException( u
"Failed to get the BackendImpl"_ustr
,
1442 static_cast<OWeakObject
*>(const_cast<TypelibraryPackageImpl
*>(this)));
1447 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1448 BackendImpl::TypelibraryPackageImpl::isRegistered_(
1449 ::osl::ResettableMutexGuard
&,
1450 ::rtl::Reference
<AbortChannel
> const &,
1451 Reference
<XCommandEnvironment
> const & )
1453 BackendImpl
* that
= getMyBackend();
1454 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1455 true /* IsPresent */,
1456 beans::Ambiguous
<sal_Bool
>(
1458 m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
, getURL() ),
1459 false /* IsAmbiguous */ ) );
1463 void BackendImpl::TypelibraryPackageImpl::processPackage_(
1464 ::osl::ResettableMutexGuard
&,
1465 bool doRegisterPackage
,
1467 ::rtl::Reference
<AbortChannel
> const &,
1468 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1470 BackendImpl
* that
= getMyBackend();
1471 const OUString
url( getURL() );
1473 if (doRegisterPackage
)
1477 // xxx todo add to classpath at runtime: ???
1478 //SB: It is probably not worth it to add the live inserted type
1479 // library JAR to the UnoClassLoader in the soffice process. Any
1480 // live inserted component JAR that might reference this type
1481 // library JAR runs in its own uno process, so there is probably no
1482 // Java code in the soffice process that would see any UNO types
1483 // introduced by this type library JAR.
1487 css::uno::Reference
< css::container::XSet
>(
1488 that
->getComponentContext()->getValueByName(
1490 "/com.sun.star.reflection.theTypeDescriptionManager"_ustr
),
1491 css::uno::UNO_QUERY_THROW
)->insert(
1492 css::uno::Any(expandUnoRcUrl(url
)));
1495 that
->addToUnoRc( m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
,
1498 else // revokePackage()
1500 that
->removeFromUnoRc(
1501 m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
, url
, xCmdEnv
);
1503 // revoking types at runtime, possible, sensible?
1505 css::uno::Reference
< css::container::XSet
>(
1506 that
->getComponentContext()->getValueByName(
1508 "/com.sun.star.reflection.theTypeDescriptionManager"_ustr
),
1509 css::uno::UNO_QUERY_THROW
)->remove(
1510 css::uno::Any(expandUnoRcUrl(url
)));
1515 BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
1516 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1517 OUString
const & url
, OUString
const & name
,
1518 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1519 bool bRemoved
, OUString
const & identifier
, OUString platform
)
1520 : Package(myBackend
, url
, name
, name
, xPackageType
, bRemoved
, identifier
)
1521 , m_aPlatform(std::move(platform
))
1523 OSL_PRECOND(bRemoved
, "this class can only be used for removing packages!");
1527 BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
1529 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1530 if (nullptr == pBackend
)
1532 //Throws a DisposedException
1534 //We should never get here...
1535 throw RuntimeException(u
"Failed to get the BackendImpl"_ustr
,
1536 static_cast<OWeakObject
*>(const_cast<OtherPlatformPackageImpl
*>(this)));
1541 Reference
<registry::XSimpleRegistry
>
1542 BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
1544 OUString
const aRDB(m_aPlatform
+ ".rdb");
1545 OUString
const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB
));
1547 Reference
<registry::XSimpleRegistry
> xRegistry
;
1552 impl_createInstance(u
"com.sun.star.registry.SimpleRegistry"_ustr
),
1556 xRegistry
->open(expandUnoRcUrl(aRDBPath
), false, false);
1558 catch (registry::InvalidRegistryException
const&)
1560 // If the registry does not exist, we do not need to bother at all
1564 SAL_WARN_IF( !xRegistry
.is(), "desktop.deployment", "could not create registry for the package's platform");
1568 Reference
<XInterface
>
1569 BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString
const& rService
)
1572 Reference
<XComponentContext
> const xContext(getMyBackend()->getComponentContext());
1573 OSL_ASSERT(xContext
.is());
1574 Reference
<XInterface
> xService
;
1576 xService
.set(xContext
->getServiceManager()->createInstanceWithContext(rService
, xContext
));
1580 beans::Optional
<beans::Ambiguous
<sal_Bool
> >
1581 BackendImpl::OtherPlatformPackageImpl::isRegistered_(
1582 ::osl::ResettableMutexGuard
& /* guard */,
1583 ::rtl::Reference
<AbortChannel
> const& /* abortChannel */,
1584 Reference
<XCommandEnvironment
> const& /* xCmdEnv */ )
1586 return beans::Optional
<beans::Ambiguous
<sal_Bool
> >(true,
1587 beans::Ambiguous
<sal_Bool
>(true, false));
1591 BackendImpl::OtherPlatformPackageImpl::processPackage_(
1592 ::osl::ResettableMutexGuard
& /* guard */,
1593 bool bRegisterPackage
,
1594 bool /* bStartup */,
1595 ::rtl::Reference
<AbortChannel
> const& /* abortChannel */,
1596 Reference
<XCommandEnvironment
> const& /* xCmdEnv */)
1598 OSL_PRECOND(!bRegisterPackage
, "this class can only be used for removing packages!");
1600 OUString
const aURL(getURL());
1602 Reference
<registry::XSimpleRegistry
> const xServicesRDB(impl_openRDB());
1603 Reference
<registry::XImplementationRegistration
> const xImplReg(
1604 impl_createInstance(u
"com.sun.star.registry.ImplementationRegistration"_ustr
),
1607 if (xImplReg
.is() && xServicesRDB
.is())
1608 xImplReg
->revokeImplementation(aURL
, xServicesRDB
);
1609 if (xServicesRDB
.is())
1610 xServicesRDB
->close();
1612 getMyBackend()->revokeEntryFromDb(aURL
);
1615 BackendImpl
* BackendImpl::ComponentsPackageImpl::getMyBackend() const
1617 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1618 if (nullptr == pBackend
)
1620 //Throws a DisposedException
1622 //We should never get here...
1623 throw RuntimeException(u
"Failed to get the BackendImpl"_ustr
,
1624 static_cast<OWeakObject
*>(const_cast<ComponentsPackageImpl
*>(this)));
1629 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1630 BackendImpl::ComponentsPackageImpl::isRegistered_(
1631 ::osl::ResettableMutexGuard
&,
1632 ::rtl::Reference
<AbortChannel
> const &,
1633 Reference
<XCommandEnvironment
> const & )
1635 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1637 beans::Ambiguous
<sal_Bool
>(
1638 getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS
, getURL()), false));
1641 void BackendImpl::ComponentsPackageImpl::processPackage_(
1642 ::osl::ResettableMutexGuard
&,
1643 bool doRegisterPackage
,
1645 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1646 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1648 BackendImpl
* that
= getMyBackend();
1649 OUString
url(getURL());
1650 if (doRegisterPackage
) {
1652 css::uno::Reference
< css::uno::XComponentContext
> context(
1653 that
->getObject(url
), css::uno::UNO_QUERY
);
1654 if (!context
.is()) {
1659 that
->getComponentContext(), abortChannel
)),
1660 css::uno::UNO_QUERY_THROW
);
1662 // This relies on the root component context's service manager
1663 // supporting the extended XSet semantics:
1664 css::uno::Sequence
< css::beans::NamedValue
> args
1666 { u
"uri"_ustr
, css::uno::Any(expandUnoRcUrl(url
)) },
1667 { u
"component-context"_ustr
, css::uno::Any(context
) }
1669 css::uno::Reference
< css::container::XSet
> smgr(
1670 that
->getRootContext()->getServiceManager(),
1671 css::uno::UNO_QUERY_THROW
);
1672 smgr
->insert(css::uno::Any(args
));
1674 that
->addToUnoRc(RCITEM_COMPONENTS
, url
, xCmdEnv
);
1676 that
->removeFromUnoRc(RCITEM_COMPONENTS
, url
, xCmdEnv
);
1678 // This relies on the root component context's service manager
1679 // supporting the extended XSet semantics:
1680 css::uno::Sequence
< css::beans::NamedValue
> args
{ { u
"uri"_ustr
, css::uno::Any(expandUnoRcUrl(url
)) } };
1681 css::uno::Reference
< css::container::XSet
> smgr(
1682 that
->getRootContext()->getServiceManager(),
1683 css::uno::UNO_QUERY_THROW
);
1684 smgr
->remove(css::uno::Any(args
));
1686 that
->releaseObject(url
);
1687 that
->revokeEntryFromDb(url
); // in case it got added with old code
1691 BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
1692 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1693 OUString
const & url
, OUString
const & name
,
1694 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1695 bool bRemoved
, OUString
const & identifier
)
1696 : Package( myBackend
, url
, name
, name
/* display-name */,
1697 xPackageType
, bRemoved
, identifier
)
1702 } // namespace dp_registry
1705 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1706 com_sun_star_comp_deployment_component_PackageRegistryBackend_get_implementation(
1707 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& args
)
1709 return cppu::acquire(new dp_registry::backend::component::BackendImpl(args
, context
));
1712 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */