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>
22 #include <dp_shared.hxx>
23 #include <dp_backend.h>
24 #include <dp_platform.hxx>
25 #include <dp_services.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 <ucbhelper/content.hxx>
34 #include <comphelper/servicedecl.hxx>
35 #include <comphelper/sequence.hxx>
36 #include <xmlscript/xml_helper.hxx>
37 #include <svl/inettype.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <com/sun/star/deployment/DeploymentException.hpp>
40 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
41 #include <com/sun/star/container/XNameContainer.hpp>
42 #include <com/sun/star/container/XSet.hpp>
43 #include <com/sun/star/registry/XSimpleRegistry.hpp>
44 #include <com/sun/star/registry/XImplementationRegistration.hpp>
45 #include <com/sun/star/loader/XImplementationLoader.hpp>
46 #include <com/sun/star/io/XInputStream.hpp>
47 #include <com/sun/star/ucb/NameClash.hpp>
48 #include <com/sun/star/util/theMacroExpander.hpp>
52 #include <unordered_map>
54 #include "dp_compbackenddb.hxx"
56 using namespace ::dp_misc
;
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::uno
;
59 using namespace ::com::sun::star::ucb
;
61 namespace dp_registry
{
66 #define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
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
, OUString
const & name
,
87 Reference
<XCommandEnvironment
> const & xCmdEnv
)
90 buf
.append( "vnd.sun.star.zip://" );
93 url
, rtl_UriCharClassRegName
, rtl_UriEncodeIgnoreEscapes
,
94 RTL_TEXTENCODING_UTF8
) );
95 buf
.append( "/META-INF/MANIFEST.MF" );
96 ::ucbhelper::Content manifestContent
;
100 &manifestContent
, buf
.makeStringAndClear(), xCmdEnv
,
101 false /* no throw */ )
102 && readLine( &line
, name
, manifestContent
, RTL_TEXTENCODING_ASCII_US
);
106 class BackendImpl
: public ::dp_registry::backend::PackageRegistryBackend
108 class ComponentPackageImpl
: public ::dp_registry::backend::Package
110 BackendImpl
* getMyBackend() const;
112 const OUString m_loader
;
115 REG_UNINIT
, REG_VOID
, REG_REGISTERED
, REG_NOT_REGISTERED
, REG_MAYBE_REGISTERED
118 void getComponentInfo(
119 ComponentBackendDb::Data
* data
,
120 std::vector
< css::uno::Reference
< css::uno::XInterface
> > *
122 Reference
<XComponentContext
> const & xContext
);
124 void componentLiveInsertion(
125 ComponentBackendDb::Data
const & data
,
126 std::vector
< css::uno::Reference
< css::uno::XInterface
> > const &
129 void componentLiveRemoval(ComponentBackendDb::Data
const & data
);
132 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
133 ::osl::ResettableMutexGuard
& guard
,
134 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
135 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
136 virtual void processPackage_(
137 ::osl::ResettableMutexGuard
& guard
,
138 bool registerPackage
,
140 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
141 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
143 Reference
<registry::XSimpleRegistry
> getRDB() const;
146 ComponentPackageImpl(
147 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
148 OUString
const & url
, OUString
const & name
,
149 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
150 OUString
const & loader
, bool bRemoved
,
151 OUString
const & identifier
);
153 friend class ComponentPackageImpl
;
155 class ComponentsPackageImpl
: public ::dp_registry::backend::Package
157 BackendImpl
* getMyBackend() const;
160 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
161 ::osl::ResettableMutexGuard
& guard
,
162 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
163 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
164 virtual void processPackage_(
165 ::osl::ResettableMutexGuard
& guard
,
166 bool registerPackage
,
168 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
169 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
171 ComponentsPackageImpl(
172 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
173 OUString
const & url
, OUString
const & name
,
174 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
175 bool bRemoved
, OUString
const & identifier
);
177 friend class ComponentsPackageImpl
;
179 class TypelibraryPackageImpl
: public ::dp_registry::backend::Package
181 BackendImpl
* getMyBackend() const;
183 const bool m_jarFile
;
186 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
187 ::osl::ResettableMutexGuard
& guard
,
188 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
189 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
190 virtual void processPackage_(
191 ::osl::ResettableMutexGuard
& guard
,
192 bool registerPackage
,
194 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
195 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
198 TypelibraryPackageImpl(
199 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
200 OUString
const & url
, OUString
const & name
,
201 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
202 bool jarFile
, bool bRemoved
,
203 OUString
const & identifier
);
205 friend class TypelibraryPackageImpl
;
207 /** Serves for unregistering packages that were registered on a
208 different platform. This can happen if one has remotely mounted
211 class OtherPlatformPackageImpl
: public ::dp_registry::backend::Package
214 OtherPlatformPackageImpl(
215 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
216 OUString
const & url
, OUString
const & name
,
217 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
218 bool bRemoved
, OUString
const & identifier
, OUString
const& rPlatform
);
221 BackendImpl
* getMyBackend() const;
223 Reference
<registry::XSimpleRegistry
> impl_openRDB() const;
224 Reference
<XInterface
> impl_createInstance(OUString
const& rService
) const;
227 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
228 ::osl::ResettableMutexGuard
& guard
,
229 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
230 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
231 virtual void processPackage_(
232 ::osl::ResettableMutexGuard
& guard
,
233 bool registerPackage
,
235 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
236 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
239 OUString
const m_aPlatform
;
241 friend class OtherPlatformPackageImpl
;
243 std::deque
<OUString
> m_jar_typelibs
;
244 std::deque
<OUString
> m_rdb_typelibs
;
245 std::deque
<OUString
> m_components
;
247 enum RcItem
{ RCITEM_JAR_TYPELIB
, RCITEM_RDB_TYPELIB
, RCITEM_COMPONENTS
};
249 std::deque
<OUString
> & getRcItemList( RcItem kind
) {
252 case RCITEM_JAR_TYPELIB
:
253 return m_jar_typelibs
;
254 case RCITEM_RDB_TYPELIB
:
255 return m_rdb_typelibs
;
256 default: // case RCITEM_COMPONENTS
262 bool m_unorc_modified
;
263 bool bSwitchedRdbFiles
;
265 typedef std::unordered_map
< OUString
, Reference
<XInterface
> > t_string2object
;
266 t_string2object m_backendObjects
;
268 // PackageRegistryBackend
269 virtual Reference
<deployment::XPackage
> bindPackage_(
270 OUString
const & url
, OUString
const & mediaType
,
271 bool bRemoved
, OUString
const & identifier
,
272 Reference
<XCommandEnvironment
> const & xCmdEnv
) override
;
274 virtual void SAL_CALL
disposing() override
;
276 const Reference
<deployment::XPackageTypeInfo
> m_xDynComponentTypeInfo
;
277 const Reference
<deployment::XPackageTypeInfo
> m_xJavaComponentTypeInfo
;
278 const Reference
<deployment::XPackageTypeInfo
> m_xPythonComponentTypeInfo
;
279 const Reference
<deployment::XPackageTypeInfo
> m_xComponentsTypeInfo
;
280 const Reference
<deployment::XPackageTypeInfo
> m_xRDBTypelibTypeInfo
;
281 const Reference
<deployment::XPackageTypeInfo
> m_xJavaTypelibTypeInfo
;
282 Sequence
< Reference
<deployment::XPackageTypeInfo
> > m_typeInfos
;
284 OUString m_commonRDB
;
285 OUString m_nativeRDB
;
287 //URLs of the original rdbs (before any switching):
288 OUString m_commonRDB_orig
;
289 OUString m_nativeRDB_orig
;
291 std::unique_ptr
<ComponentBackendDb
> m_backendDb
;
293 void addDataToDb(OUString
const & url
, ComponentBackendDb::Data
const & data
);
294 ComponentBackendDb::Data
readDataFromDb(OUString
const & url
);
295 void revokeEntryFromDb(OUString
const & url
);
297 Reference
<registry::XSimpleRegistry
> m_xCommonRDB
;
298 Reference
<registry::XSimpleRegistry
> m_xNativeRDB
;
300 void unorc_verify_init( Reference
<XCommandEnvironment
> const & xCmdEnv
);
301 void unorc_flush( Reference
<XCommandEnvironment
> const & xCmdEnv
);
303 Reference
<XInterface
> getObject( OUString
const & id
);
304 Reference
<XInterface
> insertObject(
305 OUString
const & id
, Reference
<XInterface
> const & xObject
);
306 void releaseObject( OUString
const & id
);
308 void addToUnoRc( RcItem kind
, OUString
const & url
,
309 Reference
<XCommandEnvironment
> const & xCmdEnv
);
310 void removeFromUnoRc( RcItem kind
, OUString
const & url
,
311 Reference
<XCommandEnvironment
> const & xCmdEnv
);
312 bool hasInUnoRc( RcItem kind
, OUString
const & url
);
314 css::uno::Reference
< css::uno::XComponentContext
> getRootContext() const;
317 BackendImpl( Sequence
<Any
> const & args
,
318 Reference
<XComponentContext
> const & xComponentContext
);
321 virtual Sequence
< Reference
<deployment::XPackageTypeInfo
> > SAL_CALL
322 getSupportedPackageTypes() override
;
324 virtual void SAL_CALL
packageRemoved(OUString
const & url
, OUString
const & mediaType
) override
;
326 using PackageRegistryBackend::disposing
;
328 //Will be called from ComponentPackageImpl
329 void initServiceRdbFiles();
333 BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
334 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
335 OUString
const & url
, OUString
const & name
,
336 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
337 OUString
const & loader
, bool bRemoved
,
338 OUString
const & identifier
)
339 : Package( myBackend
, url
, name
, name
/* display-name */,
340 xPackageType
, bRemoved
, identifier
),
342 m_registered( REG_UNINIT
)
345 Reference
<registry::XSimpleRegistry
>
346 BackendImpl::ComponentPackageImpl::getRDB() const
348 BackendImpl
* that
= getMyBackend();
350 //Late "initialization" of the services rdb files
351 //This is to prevent problems when running several
352 //instances of OOo with root rights in parallel. This
353 //would otherwise cause problems when copying the rdbs.
354 //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
356 const ::osl::MutexGuard
guard( getMutex() );
357 if (!that
->bSwitchedRdbFiles
)
359 that
->bSwitchedRdbFiles
= true;
360 that
->initServiceRdbFiles();
363 if ( m_loader
== "com.sun.star.loader.SharedLibrary" )
364 return that
->m_xNativeRDB
;
366 return that
->m_xCommonRDB
;
369 BackendImpl
* BackendImpl::ComponentPackageImpl::getMyBackend() const
371 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
372 if (nullptr == pBackend
)
374 //Throws a DisposedException
376 //We should never get here...
377 throw RuntimeException(
378 "Failed to get the BackendImpl",
379 static_cast<OWeakObject
*>(const_cast<ComponentPackageImpl
*>(this)));
385 void BackendImpl::disposing()
388 m_backendObjects
= t_string2object();
389 if (m_xNativeRDB
.is()) {
390 m_xNativeRDB
->close();
391 m_xNativeRDB
.clear();
393 if (m_xCommonRDB
.is()) {
394 m_xCommonRDB
->close();
395 m_xCommonRDB
.clear();
397 unorc_flush( Reference
<XCommandEnvironment
>() );
399 PackageRegistryBackend::disposing();
401 catch (const RuntimeException
&) {
404 catch (const Exception
&) {
405 Any
exc( ::cppu::getCaughtException() );
406 throw lang::WrappedTargetRuntimeException(
407 "caught unexpected exception while disposing...",
408 static_cast<OWeakObject
*>(this), exc
);
413 void BackendImpl::initServiceRdbFiles()
415 const Reference
<XCommandEnvironment
> xCmdEnv
;
417 ::ucbhelper::Content
cacheDir( getCachePath(), xCmdEnv
, m_xComponentContext
);
418 ::ucbhelper::Content oldRDB
;
419 // switch common rdb:
420 if (!m_commonRDB_orig
.isEmpty())
422 (void)create_ucb_content(
423 &oldRDB
, makeURL( getCachePath(), m_commonRDB_orig
),
424 xCmdEnv
, false /* no throw */ );
426 m_commonRDB
= m_commonRDB_orig
== "common.rdb" ? OUStringLiteral("common_.rdb") : OUStringLiteral("common.rdb");
427 if (oldRDB
.get().is())
429 cacheDir
.transferContent(
430 oldRDB
, ::ucbhelper::InsertOperation::Copy
,
431 m_commonRDB
, NameClash::OVERWRITE
);
432 oldRDB
= ::ucbhelper::Content();
434 // switch native rdb:
435 if (!m_nativeRDB_orig
.isEmpty())
437 (void)create_ucb_content(
438 &oldRDB
, makeURL(getCachePath(), m_nativeRDB_orig
),
439 xCmdEnv
, false /* no throw */ );
441 const OUString
plt_rdb( getPlatformString() + ".rdb" );
442 const OUString
plt_rdb_( getPlatformString() + "_.rdb" );
443 m_nativeRDB
= (m_nativeRDB_orig
== plt_rdb
) ? plt_rdb_
: plt_rdb
;
444 if (oldRDB
.get().is())
446 cacheDir
.transferContent(
447 oldRDB
, ::ucbhelper::InsertOperation::Copy
,
448 m_nativeRDB
, NameClash::OVERWRITE
);
451 // UNO is bootstrapped, flush for next process start:
452 m_unorc_modified
= true;
453 unorc_flush( Reference
<XCommandEnvironment
>() );
456 // common rdb for java, native rdb for shared lib components
457 if (!m_commonRDB
.isEmpty()) {
459 m_xComponentContext
->getServiceManager()
460 ->createInstanceWithContext(
461 "com.sun.star.registry.SimpleRegistry",
462 m_xComponentContext
), UNO_QUERY_THROW
);
464 makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB
),
467 if (!m_nativeRDB
.isEmpty()) {
469 m_xComponentContext
->getServiceManager()
470 ->createInstanceWithContext(
471 "com.sun.star.registry.SimpleRegistry",
472 m_xComponentContext
), UNO_QUERY_THROW
);
474 makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB
),
479 BackendImpl::BackendImpl(
480 Sequence
<Any
> const & args
,
481 Reference
<XComponentContext
> const & xComponentContext
)
482 : PackageRegistryBackend( args
, xComponentContext
),
483 m_unorc_inited( false ),
484 m_unorc_modified( false ),
485 bSwitchedRdbFiles(false),
486 m_xDynComponentTypeInfo( new Package::TypeInfo(
487 "application/vnd.sun.star.uno-component;type=native;platform=" +
489 "*" SAL_DLLEXTENSION
,
490 DpResId(RID_STR_DYN_COMPONENT
)
492 m_xJavaComponentTypeInfo( new Package::TypeInfo(
493 "application/vnd.sun.star.uno-component;type=Java",
495 DpResId(RID_STR_JAVA_COMPONENT
)
497 m_xPythonComponentTypeInfo( new Package::TypeInfo(
498 "application/vnd.sun.star.uno-component;type=Python",
501 RID_STR_PYTHON_COMPONENT
)
503 m_xComponentsTypeInfo( new Package::TypeInfo(
504 "application/vnd.sun.star.uno-components",
506 DpResId(RID_STR_COMPONENTS
)
508 m_xRDBTypelibTypeInfo( new Package::TypeInfo(
509 "application/vnd.sun.star.uno-typelibrary;type=RDB",
511 DpResId(RID_STR_RDB_TYPELIB
)
513 m_xJavaTypelibTypeInfo( new Package::TypeInfo(
514 "application/vnd.sun.star.uno-typelibrary;type=Java",
516 DpResId(RID_STR_JAVA_TYPELIB
)
520 m_typeInfos
[ 0 ] = m_xDynComponentTypeInfo
;
521 m_typeInfos
[ 1 ] = m_xJavaComponentTypeInfo
;
522 m_typeInfos
[ 2 ] = m_xPythonComponentTypeInfo
;
523 m_typeInfos
[ 3 ] = m_xComponentsTypeInfo
;
524 m_typeInfos
[ 4 ] = m_xRDBTypelibTypeInfo
;
525 m_typeInfos
[ 5 ] = m_xJavaTypelibTypeInfo
;
527 const Reference
<XCommandEnvironment
> xCmdEnv
;
532 // common rdb for java, native rdb for shared lib components
534 xComponentContext
->getServiceManager()->createInstanceWithContext(
535 "com.sun.star.registry.SimpleRegistry",
536 xComponentContext
), UNO_QUERY_THROW
);
537 m_xCommonRDB
->open( OUString() /* in-mem */,
538 false /* ! read-only */, true /* create */ );
540 xComponentContext
->getServiceManager()->createInstanceWithContext(
541 "com.sun.star.registry.SimpleRegistry",
542 xComponentContext
), UNO_QUERY_THROW
);
543 m_xNativeRDB
->open( OUString() /* in-mem */,
544 false /* ! read-only */, true /* create */ );
548 unorc_verify_init( xCmdEnv
);
549 OUString dbFile
= makeURL(getCachePath(), "backenddb.xml");
551 new ComponentBackendDb(getComponentContext(), dbFile
));
555 void BackendImpl::addDataToDb(
556 OUString
const & url
, ComponentBackendDb::Data
const & data
)
559 m_backendDb
->addEntry(url
, data
);
562 ComponentBackendDb::Data
BackendImpl::readDataFromDb(OUString
const & url
)
564 ComponentBackendDb::Data data
;
566 data
= m_backendDb
->getEntry(url
);
570 void BackendImpl::revokeEntryFromDb(OUString
const & url
)
573 m_backendDb
->revokeEntry(url
);
578 Sequence
< Reference
<deployment::XPackageTypeInfo
> >
579 BackendImpl::getSupportedPackageTypes()
584 void BackendImpl::packageRemoved(OUString
const & url
, OUString
const & /*mediaType*/)
587 m_backendDb
->removeEntry(url
);
590 // PackageRegistryBackend
592 Reference
<deployment::XPackage
> BackendImpl::bindPackage_(
593 OUString
const & url
, OUString
const & mediaType_
,
594 bool bRemoved
, OUString
const & identifier
,
595 Reference
<XCommandEnvironment
> const & xCmdEnv
)
597 OUString
mediaType(mediaType_
);
598 if ( mediaType
.isEmpty() || mediaType
== "application/vnd.sun.star.uno-component" || mediaType
== "application/vnd.sun.star.uno-typelibrary" )
600 // detect exact media-type:
601 ::ucbhelper::Content ucbContent
;
602 if (create_ucb_content( &ucbContent
, url
, xCmdEnv
)) {
603 const OUString
title( StrTitle::getTitle( ucbContent
) );
604 if (title
.endsWithIgnoreAsciiCase(SAL_DLLEXTENSION
))
606 mediaType
= "application/vnd.sun.star.uno-component;type=native;platform=" +
609 else if (title
.endsWithIgnoreAsciiCase(".jar"))
611 if (jarManifestHeaderPresent(
612 url
, "RegistrationClassName", xCmdEnv
))
613 mediaType
= "application/vnd.sun.star.uno-component;type=Java";
614 if (mediaType
.isEmpty())
615 mediaType
= "application/vnd.sun.star.uno-typelibrary;type=Java";
617 else if (title
.endsWithIgnoreAsciiCase(".py"))
618 mediaType
= "application/vnd.sun.star.uno-component;type=Python";
619 else if (title
.endsWithIgnoreAsciiCase(".rdb"))
620 mediaType
= "application/vnd.sun.star.uno-typelibrary;type=RDB";
622 if (mediaType
.isEmpty())
623 throw lang::IllegalArgumentException(
624 StrCannotDetectMediaType() + url
,
625 static_cast<OWeakObject
*>(this), static_cast<sal_Int16
>(-1) );
628 OUString type
, subType
;
629 INetContentTypeParameterList params
;
630 if (INetContentTypes::parse( mediaType
, type
, subType
, ¶ms
))
632 if (type
.equalsIgnoreAsciiCase("application"))
637 ::ucbhelper::Content
ucbContent( url
, xCmdEnv
, m_xComponentContext
);
638 name
= StrTitle::getTitle( ucbContent
);
641 if (subType
.equalsIgnoreAsciiCase("vnd.sun.star.uno-component"))
643 // xxx todo: probe and evaluate component xml description
645 auto const iter
= params
.find(OString("platform"));
646 bool bPlatformFits(iter
== params
.end());
648 if (!bPlatformFits
) // platform is specified, we have to check
650 aPlatform
= iter
->second
.m_sValue
;
651 bPlatformFits
= platform_fits(aPlatform
);
653 // If the package is being removed, do not care whether
654 // platform fits. We won't be using it anyway.
655 if (bPlatformFits
|| bRemoved
) {
656 auto const iterType
= params
.find(OString("type"));
657 if (iterType
!= params
.end())
659 OUString
const & value
= iterType
->second
.m_sValue
;
660 if (value
.equalsIgnoreAsciiCase("native")) {
662 return new BackendImpl::ComponentPackageImpl(
663 this, url
, name
, m_xDynComponentTypeInfo
,
664 "com.sun.star.loader.SharedLibrary",
665 bRemoved
, identifier
);
667 return new BackendImpl::OtherPlatformPackageImpl(
668 this, url
, name
, m_xDynComponentTypeInfo
,
669 bRemoved
, identifier
, aPlatform
);
671 if (value
.equalsIgnoreAsciiCase("Java")) {
672 return new BackendImpl::ComponentPackageImpl(
673 this, url
, name
, m_xJavaComponentTypeInfo
,
674 "com.sun.star.loader.Java2",
675 bRemoved
, identifier
);
677 if (value
.equalsIgnoreAsciiCase("Python")) {
678 return new BackendImpl::ComponentPackageImpl(
679 this, url
, name
, m_xPythonComponentTypeInfo
,
680 "com.sun.star.loader.Python",
681 bRemoved
, identifier
);
686 else if (subType
.equalsIgnoreAsciiCase("vnd.sun.star.uno-components"))
688 auto const iter
= params
.find(OString("platform"));
689 if (iter
== params
.end() || platform_fits(iter
->second
.m_sValue
)) {
690 return new BackendImpl::ComponentsPackageImpl(
691 this, url
, name
, m_xComponentsTypeInfo
, bRemoved
,
695 else if (subType
.equalsIgnoreAsciiCase( "vnd.sun.star.uno-typelibrary"))
697 auto const iter
= params
.find(OString("type"));
698 if (iter
!= params
.end()) {
699 OUString
const & value
= iter
->second
.m_sValue
;
700 if (value
.equalsIgnoreAsciiCase("RDB"))
702 return new BackendImpl::TypelibraryPackageImpl(
703 this, url
, name
, m_xRDBTypelibTypeInfo
,
704 false /* rdb */, bRemoved
, identifier
);
706 if (value
.equalsIgnoreAsciiCase("Java")) {
707 return new BackendImpl::TypelibraryPackageImpl(
708 this, url
, name
, m_xJavaTypelibTypeInfo
,
709 true /* jar */, bRemoved
, identifier
);
715 throw lang::IllegalArgumentException(
716 StrUnsupportedMediaType() + mediaType
,
717 static_cast<OWeakObject
*>(this),
718 static_cast<sal_Int16
>(-1) );
722 void BackendImpl::unorc_verify_init(
723 Reference
<XCommandEnvironment
> const & xCmdEnv
)
727 const ::osl::MutexGuard
guard( getMutex() );
728 if (! m_unorc_inited
)
731 ::ucbhelper::Content ucb_content
;
732 if (create_ucb_content(
734 makeURL( getCachePath(), "unorc" ),
735 xCmdEnv
, false /* no throw */ ))
738 if (readLine( &line
, "UNO_JAVA_CLASSPATH=", ucb_content
,
739 RTL_TEXTENCODING_UTF8
))
741 sal_Int32 index
= sizeof ("UNO_JAVA_CLASSPATH=") - 1;
743 OUString
token( line
.getToken( 0, ' ', index
).trim() );
744 if (!token
.isEmpty())
746 if (create_ucb_content(
747 nullptr, expandUnoRcTerm(token
), xCmdEnv
,
748 false /* no throw */ ))
750 //The jar file may not exist anymore if a shared or bundled
751 //extension was removed, but it can still be in the unorc
752 //After running XExtensionManager::synchronize, the unorc is
754 m_jar_typelibs
.push_back( token
);
760 if (readLine( &line
, "UNO_TYPES=", ucb_content
,
761 RTL_TEXTENCODING_UTF8
)) {
762 sal_Int32 index
= sizeof ("UNO_TYPES=") - 1;
764 OUString
token( line
.getToken( 0, ' ', index
).trim() );
765 if (!token
.isEmpty())
767 if (token
[ 0 ] == '?')
768 token
= token
.copy( 1 );
769 if (create_ucb_content(
770 nullptr, expandUnoRcTerm(token
), xCmdEnv
,
771 false /* no throw */ ))
773 //The RDB file may not exist anymore if a shared or bundled
774 //extension was removed, but it can still be in the unorc.
775 //After running XExtensionManager::synchronize, the unorc is
777 m_rdb_typelibs
.push_back( token
);
783 if (readLine( &line
, "UNO_SERVICES=", ucb_content
,
784 RTL_TEXTENCODING_UTF8
))
786 // The UNO_SERVICES line always has the BNF form
788 // ("?$ORIGIN/" <common-rdb>)? -- first
789 // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second
790 // ("?" ("BUNDLED_EXTENSIONS" | -- third
791 // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
793 // so can unambiguously be split into its three parts:
795 for (sal_Int32 i
= RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
798 OUString
token(line
.getToken(0, ' ', i
));
799 if (!token
.isEmpty())
801 if (state
== 1 && token
.match("?$ORIGIN/"))
803 m_commonRDB_orig
= token
.copy(
804 RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
807 else if ( state
<= 2 && token
== "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" )
815 token
= token
.copy(1);
817 m_components
.push_back(token
);
825 if (create_ucb_content(
827 makeURL( getCachePath(), getPlatformString() + "rc"),
828 xCmdEnv
, false /* no throw */ )) {
829 if (readLine( &line
, "UNO_SERVICES=", ucb_content
,
830 RTL_TEXTENCODING_UTF8
)) {
831 m_nativeRDB_orig
= line
.copy(
832 sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
836 m_unorc_modified
= false;
837 m_unorc_inited
= true;
842 void BackendImpl::unorc_flush( Reference
<XCommandEnvironment
> const & xCmdEnv
)
846 if (!m_unorc_inited
|| !m_unorc_modified
)
851 buf
.append("ORIGIN=");
852 OUString sOrigin
= dp_misc::makeRcTerm(m_cachePath
);
853 OString osOrigin
= OUStringToOString(sOrigin
, RTL_TEXTENCODING_UTF8
);
854 buf
.append(osOrigin
);
857 if (! m_jar_typelibs
.empty())
859 auto iPos( m_jar_typelibs
.cbegin() );
860 auto const iEnd( m_jar_typelibs
.cend() );
861 buf
.append( "UNO_JAVA_CLASSPATH=" );
862 while (iPos
!= iEnd
) {
863 // encoded ASCII file-urls:
865 OUStringToOString( *iPos
, RTL_TEXTENCODING_ASCII_US
) );
873 if (! m_rdb_typelibs
.empty())
875 auto iPos( m_rdb_typelibs
.cbegin() );
876 auto const iEnd( m_rdb_typelibs
.cend() );
877 buf
.append( "UNO_TYPES=" );
878 while (iPos
!= iEnd
) {
880 // encoded ASCII file-urls:
882 OUStringToOString( *iPos
, RTL_TEXTENCODING_ASCII_US
) );
891 // If we duplicated the common or native rdb then we must use those urls
892 //otherwise we use those of the original files. That is, m_commonRDB_orig
893 //and m_nativeRDB_orig;
894 OUString
sCommonRDB(m_commonRDB
.isEmpty() ? m_commonRDB_orig
: m_commonRDB
);
895 OUString
sNativeRDB(m_nativeRDB
.isEmpty() ? m_nativeRDB_orig
: m_nativeRDB
);
897 if (!sCommonRDB
.isEmpty() || !sNativeRDB
.isEmpty() ||
898 !m_components
.empty())
900 buf
.append( "UNO_SERVICES=" );
902 if (!sCommonRDB
.isEmpty())
904 buf
.append( "?$ORIGIN/" );
905 buf
.append( OUStringToOString(
906 sCommonRDB
, RTL_TEXTENCODING_ASCII_US
) );
909 if (!sNativeRDB
.isEmpty())
915 buf
.append( "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" );
923 "UNO_SERVICES=?$ORIGIN/" +
924 OUStringToOString( sNativeRDB
, RTL_TEXTENCODING_ASCII_US
) +
927 const Reference
<io::XInputStream
> xData(
928 ::xmlscript::createInputStream(
929 reinterpret_cast<sal_Int8
const *>(buf2
.getStr()),
930 buf2
.getLength() ) );
931 ::ucbhelper::Content
ucb_content(
932 makeURL( getCachePath(), getPlatformString() + "rc" ),
933 xCmdEnv
, m_xComponentContext
);
934 ucb_content
.writeStream( xData
, true /* replace existing */ );
936 for (auto const& component
: m_components
)
943 buf
.append(OUStringToOString(component
, RTL_TEXTENCODING_UTF8
));
950 const Reference
<io::XInputStream
> xData(
951 ::xmlscript::createInputStream(
952 reinterpret_cast<sal_Int8
const *>(buf
.getStr()),
954 ::ucbhelper::Content
ucb_content(
955 makeURL( getCachePath(), "unorc" ), xCmdEnv
, m_xComponentContext
);
956 ucb_content
.writeStream( xData
, true /* replace existing */ );
958 m_unorc_modified
= false;
962 void BackendImpl::addToUnoRc( RcItem kind
, OUString
const & url_
,
963 Reference
<XCommandEnvironment
> const & xCmdEnv
)
965 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
966 const ::osl::MutexGuard
guard( getMutex() );
967 unorc_verify_init( xCmdEnv
);
968 std::deque
<OUString
> & rSet
= getRcItemList(kind
);
969 if (std::find( rSet
.begin(), rSet
.end(), rcterm
) == rSet
.end()) {
970 rSet
.push_front( rcterm
); // prepend to list, thus overriding
971 // write immediately:
972 m_unorc_modified
= true;
973 unorc_flush( xCmdEnv
);
978 void BackendImpl::removeFromUnoRc(
979 RcItem kind
, OUString
const & url_
,
980 Reference
<XCommandEnvironment
> const & xCmdEnv
)
982 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
983 const ::osl::MutexGuard
guard( getMutex() );
984 unorc_verify_init( xCmdEnv
);
985 std::deque
<OUString
> & aRcItemList
= getRcItemList(kind
);
986 aRcItemList
.erase(std::remove(aRcItemList
.begin(), aRcItemList
.end(), rcterm
), aRcItemList
.end());
987 // write immediately:
988 m_unorc_modified
= true;
989 unorc_flush( xCmdEnv
);
993 bool BackendImpl::hasInUnoRc(
994 RcItem kind
, OUString
const & url_
)
996 const OUString
rcterm( dp_misc::makeRcTerm(url_
) );
997 const ::osl::MutexGuard
guard( getMutex() );
998 std::deque
<OUString
> const & rSet
= getRcItemList(kind
);
999 return std::find( rSet
.begin(), rSet
.end(), rcterm
) != rSet
.end();
1002 css::uno::Reference
< css::uno::XComponentContext
> BackendImpl::getRootContext()
1005 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1006 getComponentContext()->getValueByName("_root"),
1007 css::uno::UNO_QUERY
);
1008 return rootContext
.is() ? rootContext
: getComponentContext();
1012 void BackendImpl::releaseObject( OUString
const & id
)
1014 const ::osl::MutexGuard
guard( getMutex() );
1015 m_backendObjects
.erase( id
);
1019 Reference
<XInterface
> BackendImpl::getObject( OUString
const & id
)
1021 const ::osl::MutexGuard
guard( getMutex() );
1022 const t_string2object::const_iterator
iFind( m_backendObjects
.find( id
) );
1023 if (iFind
== m_backendObjects
.end())
1024 return Reference
<XInterface
>();
1026 return iFind
->second
;
1030 Reference
<XInterface
> BackendImpl::insertObject(
1031 OUString
const & id
, Reference
<XInterface
> const & xObject
)
1033 const ::osl::MutexGuard
guard( getMutex() );
1034 const std::pair
<t_string2object::iterator
, bool> insertion(
1035 m_backendObjects
.emplace( id
, xObject
) );
1036 return insertion
.first
->second
;
1040 Reference
<XComponentContext
> raise_uno_process(
1041 Reference
<XComponentContext
> const & xContext
,
1042 ::rtl::Reference
<AbortChannel
> const & abortChannel
)
1044 OSL_ASSERT( xContext
.is() );
1046 OUString
url( util::theMacroExpander::get(xContext
)->expandMacros( "$URE_BIN_DIR/uno" ) );
1048 const OUString connectStr
= "uno:pipe,name=" + generateRandomPipeId() + ";urp;uno.ComponentContext";
1050 // raise core UNO process to register/run a component,
1051 // javavm service uses unorc next to executable to retrieve deployed
1054 std::vector
<OUString
> args
{
1055 #if OSL_DEBUG_LEVEL == 0
1061 // don't inherit from unorc:
1062 "-env:INIFILENAME=" };
1064 //now add the bootstrap variables which were supplied on the command line
1065 std::vector
<OUString
> bootvars
= getCmdBootstrapVariables();
1066 args
.insert(args
.end(), bootvars
.begin(), bootvars
.end());
1068 oslProcess hProcess
;
1070 hProcess
= raiseProcess(
1071 url
, comphelper::containerToSequence(args
) );
1074 OUStringBuffer sMsg
= "error starting process: " + url
;
1075 for(const auto& arg
: args
)
1076 sMsg
.append(" ").append(arg
);
1077 throw uno::RuntimeException(sMsg
.makeStringAndClear());
1080 return Reference
<XComponentContext
>(
1081 resolveUnoURL( connectStr
, xContext
, abortChannel
.get() ),
1085 // try to terminate process:
1086 if ( osl_terminateProcess( hProcess
) != osl_Process_E_None
)
1088 OSL_ASSERT( false );
1094 void extractComponentData(
1095 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
1096 css::uno::Reference
< css::registry::XRegistryKey
> const & registry
,
1097 ComponentBackendDb::Data
* data
,
1098 std::vector
< css::uno::Reference
< css::uno::XInterface
> > * factories
,
1099 css::uno::Reference
< css::loader::XImplementationLoader
> const &
1101 OUString
const & componentUrl
)
1104 context
.is() && registry
.is() && data
!= nullptr && componentLoader
.is());
1105 OUString
registryName(registry
->getKeyName());
1106 sal_Int32 prefix
= registryName
.getLength();
1107 if (!registryName
.endsWith("/")) {
1108 prefix
+= RTL_CONSTASCII_LENGTH("/");
1110 css::uno::Sequence
< css::uno::Reference
< css::registry::XRegistryKey
> >
1111 keys(registry
->openKeys());
1112 css::uno::Reference
< css::lang::XMultiComponentFactory
> smgr(
1113 context
->getServiceManager(), css::uno::UNO_SET_THROW
);
1114 for (sal_Int32 i
= 0; i
< keys
.getLength(); ++i
) {
1115 OUString
name(keys
[i
]->getKeyName().copy(prefix
));
1116 data
->implementationNames
.push_back(name
);
1117 css::uno::Reference
< css::registry::XRegistryKey
> singletons(
1118 keys
[i
]->openKey("UNO/SINGLETONS"));
1119 if (singletons
.is()) {
1120 sal_Int32 prefix2
= keys
[i
]->getKeyName().getLength() +
1121 RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
1123 css::uno::Reference
< css::registry::XRegistryKey
> >
1124 singletonKeys(singletons
->openKeys());
1125 for (sal_Int32 j
= 0; j
< singletonKeys
.getLength(); ++j
) {
1126 data
->singletons
.emplace_back(
1127 singletonKeys
[j
]->getKeyName().copy(prefix2
), name
);
1130 if (factories
!= nullptr) {
1131 factories
->push_back(
1132 componentLoader
->activate(
1133 name
, OUString(), componentUrl
, keys
[i
]));
1138 void BackendImpl::ComponentPackageImpl::getComponentInfo(
1139 ComponentBackendDb::Data
* data
,
1140 std::vector
< css::uno::Reference
< css::uno::XInterface
> > * factories
,
1141 Reference
<XComponentContext
> const & xContext
)
1143 const Reference
<loader::XImplementationLoader
> xLoader(
1144 xContext
->getServiceManager()->createInstanceWithContext(
1145 m_loader
, xContext
), UNO_QUERY
);
1148 throw css::deployment::DeploymentException(
1149 "cannot instantiate loader " + m_loader
,
1150 static_cast< OWeakObject
* >(this), Any());
1153 // HACK: highly dependent on stoc/source/servicemanager
1154 // and stoc/source/implreg implementation which rely on the same
1155 // services.rdb format!
1156 // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
1157 // writeRegistryInfo, however, but are known, fixed values here, so
1158 // can be passed into extractComponentData
1159 OUString
url(getURL());
1160 const Reference
<registry::XSimpleRegistry
> xMemReg(
1161 xContext
->getServiceManager()->createInstanceWithContext(
1162 "com.sun.star.registry.SimpleRegistry", xContext
),
1164 xMemReg
->open( OUString() /* in mem */, false, true );
1165 xLoader
->writeRegistryInfo( xMemReg
->getRootKey(), OUString(), url
);
1166 extractComponentData(
1167 xContext
, xMemReg
->getRootKey(), data
, factories
, xLoader
, url
);
1170 void BackendImpl::ComponentPackageImpl::componentLiveInsertion(
1171 ComponentBackendDb::Data
const & data
,
1172 std::vector
< css::uno::Reference
< css::uno::XInterface
> > const &
1175 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1176 getMyBackend()->getRootContext());
1177 css::uno::Reference
< css::container::XSet
> set(
1178 rootContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1179 std::vector
< css::uno::Reference
< css::uno::XInterface
> >::const_iterator
1180 factory(factories
.begin());
1181 for (auto const& implementationName
: data
.implementationNames
)
1184 set
->insert(css::uno::Any(*factory
++));
1185 } catch (const container::ElementExistException
&) {
1186 SAL_WARN("desktop.deployment", "implementation already registered " << implementationName
);
1189 if (!data
.singletons
.empty()) {
1190 css::uno::Reference
< css::container::XNameContainer
> cont(
1191 rootContext
, css::uno::UNO_QUERY_THROW
);
1192 for (auto const& singleton
: data
.singletons
)
1194 OUString
name("/singletons/" + singleton
.first
);
1195 //TODO: Update should be atomic:
1197 cont
->removeByName( name
+ "/arguments");
1198 } catch (const container::NoSuchElementException
&) {}
1200 cont
->insertByName( name
+ "/service", css::uno::Any(singleton
.second
));
1201 } catch (const container::ElementExistException
&) {
1202 cont
->replaceByName( name
+ "/service", css::uno::Any(singleton
.second
));
1205 cont
->insertByName(name
, css::uno::Any());
1206 } catch (const container::ElementExistException
&) {
1207 SAL_WARN("desktop.deployment", "singleton already registered " << singleton
.first
);
1208 cont
->replaceByName(name
, css::uno::Any());
1214 void BackendImpl::ComponentPackageImpl::componentLiveRemoval(
1215 ComponentBackendDb::Data
const & data
)
1217 css::uno::Reference
< css::uno::XComponentContext
> rootContext(
1218 getMyBackend()->getRootContext());
1219 css::uno::Reference
< css::container::XSet
> set(
1220 rootContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
1221 for (auto const& implementationName
: data
.implementationNames
)
1224 set
->remove(css::uno::Any(implementationName
));
1225 } catch (const css::container::NoSuchElementException
&) {
1226 // ignore if factory has not been live deployed
1229 if (!data
.singletons
.empty()) {
1230 css::uno::Reference
< css::container::XNameContainer
> cont(
1231 rootContext
, css::uno::UNO_QUERY_THROW
);
1232 for (auto const& singleton
: data
.singletons
)
1234 OUString
name("/singletons/" + singleton
.first
);
1235 //TODO: Removal should be atomic:
1237 cont
->removeByName(name
);
1238 } catch (const container::NoSuchElementException
&) {}
1240 cont
->removeByName( name
+ "/service" );
1241 } catch (const container::NoSuchElementException
&) {}
1243 cont
->removeByName( name
+ "/arguments" );
1244 } catch (const container::NoSuchElementException
&) {}
1251 //We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
1252 //And it also shows the problem if another extension has overwritten an implementation
1253 //entry, because it contains the same service implementation
1254 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1255 BackendImpl::ComponentPackageImpl::isRegistered_(
1256 ::osl::ResettableMutexGuard
&,
1257 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1258 Reference
<XCommandEnvironment
> const & )
1260 if (m_registered
== REG_UNINIT
)
1262 m_registered
= REG_NOT_REGISTERED
;
1263 const Reference
<registry::XSimpleRegistry
> xRDB( getRDB() );
1266 bool bAmbiguousComponentName
= false;
1267 // lookup rdb for location URL:
1268 const Reference
<registry::XRegistryKey
> xRootKey(
1269 xRDB
->getRootKey() );
1270 const Reference
<registry::XRegistryKey
> xImplKey(
1271 xRootKey
->openKey( "IMPLEMENTATIONS" ) );
1272 Sequence
<OUString
> implNames
;
1273 if (xImplKey
.is() && xImplKey
->isValid())
1274 implNames
= xImplKey
->getKeyNames();
1275 OUString
const * pImplNames
= implNames
.getConstArray();
1276 sal_Int32 pos
= implNames
.getLength();
1279 checkAborted( abortChannel
);
1281 pImplNames
[ pos
] + "/UNO/LOCATION" );
1282 const Reference
<registry::XRegistryKey
> xKey(
1283 xRootKey
->openKey(key
) );
1284 if (xKey
.is() && xKey
->isValid())
1286 const OUString
location( xKey
->getAsciiValue() );
1287 if (location
.equalsIgnoreAsciiCase( getURL() ))
1293 //try to match only the file name
1294 OUString
thisUrl(getURL());
1295 OUString
thisFileName(thisUrl
.copy(thisUrl
.lastIndexOf('/')));
1297 OUString
locationFileName(location
.copy(location
.lastIndexOf('/')));
1298 if (locationFileName
.equalsIgnoreAsciiCase(thisFileName
))
1299 bAmbiguousComponentName
= true;
1304 m_registered
= REG_REGISTERED
;
1305 else if (bAmbiguousComponentName
)
1306 m_registered
= REG_MAYBE_REGISTERED
;
1310 //Different extensions can use the same service implementations. Then the extensions
1311 //which was installed last will overwrite the one from the other extension. That is
1312 //the registry will contain the path (the location) of the library or jar of the
1313 //second extension. In this case isRegistered called for the lib of the first extension
1314 //would return "not registered". That would mean that during uninstallation
1315 //XPackage::registerPackage is not called, because it just was not registered. This is,
1316 //however, necessary for jar files. Registering and unregistering update
1317 //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
1318 //Therefore, we will return always "is ambiguous" if the path of this component cannot
1319 //be found in the registry and if there is another path and both have the same file name (but
1320 //the rest of the path is different).
1321 //If the caller cannot precisely determine that this package was registered, then it must
1322 //call registerPackage.
1323 bool bAmbiguous
= m_registered
== REG_VOID
// REG_VOID == we are in the progress of unregistration
1324 || m_registered
== REG_MAYBE_REGISTERED
;
1325 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1326 true /* IsPresent */,
1327 beans::Ambiguous
<sal_Bool
>(
1328 m_registered
== REG_REGISTERED
, bAmbiguous
) );
1332 void BackendImpl::ComponentPackageImpl::processPackage_(
1333 ::osl::ResettableMutexGuard
&,
1334 bool doRegisterPackage
,
1336 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1337 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1339 BackendImpl
* that
= getMyBackend();
1340 OUString
url(getURL());
1341 if (doRegisterPackage
) {
1342 ComponentBackendDb::Data data
;
1343 css::uno::Reference
< css::uno::XComponentContext
> context
;
1345 context
= that
->getComponentContext();
1347 context
.set(that
->getObject(url
), css::uno::UNO_QUERY
);
1348 if (!context
.is()) {
1353 that
->getComponentContext(), abortChannel
)),
1354 css::uno::UNO_QUERY_THROW
);
1357 css::uno::Reference
< css::registry::XImplementationRegistration
> impreg(
1358 context
->getServiceManager()->createInstanceWithContext(
1359 "com.sun.star.registry.ImplementationRegistration",
1361 css::uno::UNO_QUERY_THROW
);
1362 css::uno::Reference
< css::registry::XSimpleRegistry
> rdb(getRDB());
1363 impreg
->registerImplementation(m_loader
, url
, rdb
);
1364 // Only write to unorc after successful registration; it may fail if
1365 // there is no suitable java
1366 if (m_loader
== "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url
, "UNO-Type-Path", xCmdEnv
))
1368 that
->addToUnoRc(RCITEM_JAR_TYPELIB
, url
, xCmdEnv
);
1369 data
.javaTypeLibrary
= true;
1371 std::vector
< css::uno::Reference
< css::uno::XInterface
> > factories
;
1372 getComponentInfo(&data
, startup
? nullptr : &factories
, context
);
1375 componentLiveInsertion(data
, factories
);
1376 } catch (css::uno::Exception
&) {
1377 TOOLS_INFO_EXCEPTION("desktop.deployment", "caught");
1379 impreg
->revokeImplementation(url
, rdb
);
1380 } catch (css::uno::RuntimeException
&) {
1381 TOOLS_WARN_EXCEPTION("desktop.deployment", "ignored");
1386 m_registered
= REG_REGISTERED
;
1387 that
->addDataToDb(url
, data
);
1389 m_registered
= REG_VOID
;
1390 ComponentBackendDb::Data
data(that
->readDataFromDb(url
));
1391 css::uno::Reference
< css::uno::XComponentContext
> context(
1392 that
->getObject(url
), css::uno::UNO_QUERY
);
1393 bool remoteContext
= context
.is();
1394 if (!remoteContext
) {
1395 context
= that
->getComponentContext();
1398 componentLiveRemoval(data
);
1400 css::uno::Reference
< css::registry::XImplementationRegistration
>(
1401 context
->getServiceManager()->createInstanceWithContext(
1402 "com.sun.star.registry.ImplementationRegistration",
1404 css::uno::UNO_QUERY_THROW
)->revokeImplementation(url
, getRDB());
1405 if (data
.javaTypeLibrary
) {
1406 that
->removeFromUnoRc(RCITEM_JAR_TYPELIB
, url
, xCmdEnv
);
1408 if (remoteContext
) {
1409 that
->releaseObject(url
);
1411 m_registered
= REG_NOT_REGISTERED
;
1412 getMyBackend()->revokeEntryFromDb(url
);
1416 BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
1417 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1418 OUString
const & url
, OUString
const & name
,
1419 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1420 bool jarFile
, bool bRemoved
, OUString
const & identifier
)
1421 : Package( myBackend
, url
, name
, name
/* display-name */,
1422 xPackageType
, bRemoved
, identifier
),
1423 m_jarFile( jarFile
)
1428 BackendImpl
* BackendImpl::TypelibraryPackageImpl::getMyBackend() const
1430 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1431 if (nullptr == pBackend
)
1433 //May throw a DisposedException
1435 //We should never get here...
1436 throw RuntimeException( "Failed to get the BackendImpl",
1437 static_cast<OWeakObject
*>(const_cast<TypelibraryPackageImpl
*>(this)));
1442 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1443 BackendImpl::TypelibraryPackageImpl::isRegistered_(
1444 ::osl::ResettableMutexGuard
&,
1445 ::rtl::Reference
<AbortChannel
> const &,
1446 Reference
<XCommandEnvironment
> const & )
1448 BackendImpl
* that
= getMyBackend();
1449 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1450 true /* IsPresent */,
1451 beans::Ambiguous
<sal_Bool
>(
1453 m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
, getURL() ),
1454 false /* IsAmbiguous */ ) );
1458 void BackendImpl::TypelibraryPackageImpl::processPackage_(
1459 ::osl::ResettableMutexGuard
&,
1460 bool doRegisterPackage
,
1462 ::rtl::Reference
<AbortChannel
> const &,
1463 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1465 BackendImpl
* that
= getMyBackend();
1466 const OUString
url( getURL() );
1468 if (doRegisterPackage
)
1472 // xxx todo add to classpath at runtime: ???
1473 //SB: It is probably not worth it to add the live inserted type
1474 // library JAR to the UnoClassLoader in the soffice process. Any
1475 // live inserted component JAR that might reference this type
1476 // library JAR runs in its own uno process, so there is probably no
1477 // Java code in the soffice process that would see any UNO types
1478 // introduced by this type library JAR.
1482 css::uno::Reference
< css::container::XSet
>(
1483 that
->getComponentContext()->getValueByName(
1485 "/com.sun.star.reflection.theTypeDescriptionManager"),
1486 css::uno::UNO_QUERY_THROW
)->insert(
1487 css::uno::makeAny(expandUnoRcUrl(url
)));
1490 that
->addToUnoRc( m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
,
1493 else // revokePackage()
1495 that
->removeFromUnoRc(
1496 m_jarFile
? RCITEM_JAR_TYPELIB
: RCITEM_RDB_TYPELIB
, url
, xCmdEnv
);
1498 // revoking types at runtime, possible, sensible?
1500 css::uno::Reference
< css::container::XSet
>(
1501 that
->getComponentContext()->getValueByName(
1503 "/com.sun.star.reflection.theTypeDescriptionManager"),
1504 css::uno::UNO_QUERY_THROW
)->remove(
1505 css::uno::makeAny(expandUnoRcUrl(url
)));
1510 BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
1511 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1512 OUString
const & url
, OUString
const & name
,
1513 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1514 bool bRemoved
, OUString
const & identifier
, OUString
const& rPlatform
)
1515 : Package(myBackend
, url
, name
, name
, xPackageType
, bRemoved
, identifier
)
1516 , m_aPlatform(rPlatform
)
1518 OSL_PRECOND(bRemoved
, "this class can only be used for removing packages!");
1522 BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
1524 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1525 if (nullptr == pBackend
)
1527 //Throws a DisposedException
1529 //We should never get here...
1530 throw RuntimeException("Failed to get the BackendImpl",
1531 static_cast<OWeakObject
*>(const_cast<OtherPlatformPackageImpl
*>(this)));
1536 Reference
<registry::XSimpleRegistry
>
1537 BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
1539 OUString
const aRDB(m_aPlatform
+ ".rdb");
1540 OUString
const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB
));
1542 Reference
<registry::XSimpleRegistry
> xRegistry
;
1547 impl_createInstance("com.sun.star.registry.SimpleRegistry"),
1551 xRegistry
->open(expandUnoRcUrl(aRDBPath
), false, false);
1553 catch (registry::InvalidRegistryException
const&)
1555 // If the registry does not exist, we do not need to bother at all
1556 xRegistry
.set(nullptr);
1559 SAL_WARN_IF( !xRegistry
.is(), "desktop.deployment", "could not create registry for the package's platform");
1563 Reference
<XInterface
>
1564 BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString
const& rService
)
1567 Reference
<XComponentContext
> const xContext(getMyBackend()->getComponentContext());
1568 OSL_ASSERT(xContext
.is());
1569 Reference
<XInterface
> xService
;
1571 xService
.set(xContext
->getServiceManager()->createInstanceWithContext(rService
, xContext
));
1575 beans::Optional
<beans::Ambiguous
<sal_Bool
> >
1576 BackendImpl::OtherPlatformPackageImpl::isRegistered_(
1577 ::osl::ResettableMutexGuard
& /* guard */,
1578 ::rtl::Reference
<AbortChannel
> const& /* abortChannel */,
1579 Reference
<XCommandEnvironment
> const& /* xCmdEnv */ )
1581 return beans::Optional
<beans::Ambiguous
<sal_Bool
> >(true,
1582 beans::Ambiguous
<sal_Bool
>(true, false));
1586 BackendImpl::OtherPlatformPackageImpl::processPackage_(
1587 ::osl::ResettableMutexGuard
& /* guard */,
1588 bool bRegisterPackage
,
1589 bool /* bStartup */,
1590 ::rtl::Reference
<AbortChannel
> const& /* abortChannel */,
1591 Reference
<XCommandEnvironment
> const& /* xCmdEnv */)
1593 OSL_PRECOND(!bRegisterPackage
, "this class can only be used for removing packages!");
1595 OUString
const aURL(getURL());
1597 Reference
<registry::XSimpleRegistry
> const xServicesRDB(impl_openRDB());
1598 Reference
<registry::XImplementationRegistration
> const xImplReg(
1599 impl_createInstance("com.sun.star.registry.ImplementationRegistration"),
1602 if (xImplReg
.is() && xServicesRDB
.is())
1603 xImplReg
->revokeImplementation(aURL
, xServicesRDB
);
1604 if (xServicesRDB
.is())
1605 xServicesRDB
->close();
1607 getMyBackend()->revokeEntryFromDb(aURL
);
1610 BackendImpl
* BackendImpl::ComponentsPackageImpl::getMyBackend() const
1612 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
1613 if (nullptr == pBackend
)
1615 //Throws a DisposedException
1617 //We should never get here...
1618 throw RuntimeException("Failed to get the BackendImpl",
1619 static_cast<OWeakObject
*>(const_cast<ComponentsPackageImpl
*>(this)));
1624 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
1625 BackendImpl::ComponentsPackageImpl::isRegistered_(
1626 ::osl::ResettableMutexGuard
&,
1627 ::rtl::Reference
<AbortChannel
> const &,
1628 Reference
<XCommandEnvironment
> const & )
1630 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
1632 beans::Ambiguous
<sal_Bool
>(
1633 getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS
, getURL()), false));
1636 void BackendImpl::ComponentsPackageImpl::processPackage_(
1637 ::osl::ResettableMutexGuard
&,
1638 bool doRegisterPackage
,
1640 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1641 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1643 BackendImpl
* that
= getMyBackend();
1644 OUString
url(getURL());
1645 if (doRegisterPackage
) {
1647 css::uno::Reference
< css::uno::XComponentContext
> context(
1648 that
->getObject(url
), css::uno::UNO_QUERY
);
1649 if (!context
.is()) {
1654 that
->getComponentContext(), abortChannel
)),
1655 css::uno::UNO_QUERY_THROW
);
1657 // This relies on the root component context's service manager
1658 // supporting the extended XSet semantics:
1659 css::uno::Sequence
< css::beans::NamedValue
> args
1661 { "uri", css::uno::makeAny(expandUnoRcUrl(url
)) },
1662 { "component-context", css::uno::makeAny(context
) }
1664 css::uno::Reference
< css::container::XSet
> smgr(
1665 that
->getRootContext()->getServiceManager(),
1666 css::uno::UNO_QUERY_THROW
);
1667 smgr
->insert(css::uno::makeAny(args
));
1669 that
->addToUnoRc(RCITEM_COMPONENTS
, url
, xCmdEnv
);
1671 that
->removeFromUnoRc(RCITEM_COMPONENTS
, url
, xCmdEnv
);
1673 // This relies on the root component context's service manager
1674 // supporting the extended XSet semantics:
1675 css::uno::Sequence
< css::beans::NamedValue
> args
{ { "uri", css::uno::makeAny(expandUnoRcUrl(url
)) } };
1676 css::uno::Reference
< css::container::XSet
> smgr(
1677 that
->getRootContext()->getServiceManager(),
1678 css::uno::UNO_QUERY_THROW
);
1679 smgr
->remove(css::uno::makeAny(args
));
1681 that
->releaseObject(url
);
1682 that
->revokeEntryFromDb(url
); // in case it got added with old code
1686 BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
1687 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
1688 OUString
const & url
, OUString
const & name
,
1689 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
1690 bool bRemoved
, OUString
const & identifier
)
1691 : Package( myBackend
, url
, name
, name
/* display-name */,
1692 xPackageType
, bRemoved
, identifier
)
1697 namespace sdecl
= comphelper::service_decl
;
1698 sdecl::class_
<BackendImpl
, sdecl::with_args
<true> > serviceBI
;
1699 sdecl::ServiceDecl
const serviceDecl(
1701 IMPLEMENTATION_NAME
,
1702 BACKEND_SERVICE_NAME
);
1704 } // namespace component
1705 } // namespace backend
1706 } // namespace dp_registry
1709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */