Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "dp_component.hrc"
22 : #include "dp_backend.h"
23 : #include "dp_platform.hxx"
24 : #include "dp_ucb.h"
25 : #include <rtl/string.hxx>
26 : #include <rtl/strbuf.hxx>
27 : #include <rtl/ustrbuf.hxx>
28 : #include <rtl/uri.hxx>
29 : #include <sal/log.hxx>
30 : #include <cppuhelper/exc_hlp.hxx>
31 : #include <ucbhelper/content.hxx>
32 : #include <comphelper/anytostring.hxx>
33 : #include <comphelper/servicedecl.hxx>
34 : #include <comphelper/sequence.hxx>
35 : #include <xmlscript/xml_helper.hxx>
36 : #include <svl/inettype.hxx>
37 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
38 : #include <com/sun/star/container/XNameContainer.hpp>
39 : #include <com/sun/star/container/XSet.hpp>
40 : #include <com/sun/star/registry/XSimpleRegistry.hpp>
41 : #include <com/sun/star/registry/XImplementationRegistration.hpp>
42 : #include <com/sun/star/loader/XImplementationLoader.hpp>
43 : #include <com/sun/star/io/XInputStream.hpp>
44 : #include <com/sun/star/ucb/NameClash.hpp>
45 : #include <com/sun/star/util/theMacroExpander.hpp>
46 : #include <algorithm>
47 : #include <list>
48 : #include <memory>
49 : #include <unordered_map>
50 : #include <vector>
51 : #include "dp_compbackenddb.hxx"
52 :
53 : using namespace ::dp_misc;
54 : using namespace ::com::sun::star;
55 : using namespace ::com::sun::star::uno;
56 : using namespace ::com::sun::star::ucb;
57 :
58 : namespace dp_registry {
59 : namespace backend {
60 : namespace component {
61 : namespace {
62 :
63 : typedef ::std::list<OUString> t_stringlist;
64 : typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
65 :
66 : #define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
67 :
68 : /** return a vector of bootstrap variables which have been provided
69 : as command arguments.
70 : */
71 1 : ::std::vector<OUString> getCmdBootstrapVariables()
72 : {
73 1 : ::std::vector<OUString> ret;
74 1 : sal_uInt32 count = osl_getCommandArgCount();
75 9 : for (sal_uInt32 i = 0; i < count; i++)
76 : {
77 8 : OUString arg;
78 8 : osl_getCommandArg(i, &arg.pData);
79 8 : if (arg.match("-env:"))
80 3 : ret.push_back(arg);
81 8 : }
82 1 : return ret;
83 : }
84 :
85 1 : bool jarManifestHeaderPresent(
86 : OUString const & url, OUString const & name,
87 : Reference<XCommandEnvironment> const & xCmdEnv )
88 : {
89 1 : OUStringBuffer buf;
90 1 : buf.appendAscii( "vnd.sun.star.zip://" );
91 : buf.append(
92 : ::rtl::Uri::encode(
93 : url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
94 1 : RTL_TEXTENCODING_UTF8 ) );
95 1 : buf.appendAscii( "/META-INF/MANIFEST.MF" );
96 2 : ::ucbhelper::Content manifestContent;
97 2 : OUString line;
98 : return
99 : create_ucb_content(
100 : &manifestContent, buf.makeStringAndClear(), xCmdEnv,
101 4 : false /* no throw */ )
102 4 : && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US );
103 : }
104 :
105 :
106 392 : class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
107 : {
108 2 : class ComponentPackageImpl : public ::dp_registry::backend::Package
109 : {
110 : BackendImpl * getMyBackend() const;
111 :
112 : const OUString m_loader;
113 :
114 : enum reg {
115 : REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_REGISTERED
116 : } m_registered;
117 :
118 : void getComponentInfo(
119 : ComponentBackendDb::Data * data,
120 : std::vector< css::uno::Reference< css::uno::XInterface > > *
121 : factories,
122 : Reference<XComponentContext> const & xContext );
123 :
124 : void componentLiveInsertion(
125 : ComponentBackendDb::Data const & data,
126 : std::vector< css::uno::Reference< css::uno::XInterface > > const &
127 : factories);
128 :
129 : void componentLiveRemoval(ComponentBackendDb::Data const & data);
130 :
131 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
132 :
133 : // Package
134 : virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
135 : ::osl::ResettableMutexGuard & guard,
136 : ::rtl::Reference<AbortChannel> const & abortChannel,
137 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
138 : virtual void processPackage_(
139 : ::osl::ResettableMutexGuard & guard,
140 : bool registerPackage,
141 : bool startup,
142 : ::rtl::Reference<AbortChannel> const & abortChannel,
143 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
144 :
145 : const Reference<registry::XSimpleRegistry> getRDB() const;
146 :
147 : public:
148 : ComponentPackageImpl(
149 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
150 : OUString const & url, OUString const & name,
151 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
152 : OUString const & loader, bool bRemoved,
153 : OUString const & identifier);
154 : };
155 : friend class ComponentPackageImpl;
156 :
157 0 : class ComponentsPackageImpl : public ::dp_registry::backend::Package
158 : {
159 : BackendImpl * getMyBackend() const;
160 :
161 : // Package
162 : virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
163 : ::osl::ResettableMutexGuard & guard,
164 : ::rtl::Reference<AbortChannel> const & abortChannel,
165 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
166 : virtual void processPackage_(
167 : ::osl::ResettableMutexGuard & guard,
168 : bool registerPackage,
169 : bool startup,
170 : ::rtl::Reference<AbortChannel> const & abortChannel,
171 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
172 : public:
173 : ComponentsPackageImpl(
174 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
175 : OUString const & url, OUString const & name,
176 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
177 : bool bRemoved, OUString const & identifier);
178 : };
179 : friend class ComponentsPackageImpl;
180 :
181 0 : class TypelibraryPackageImpl : public ::dp_registry::backend::Package
182 : {
183 : BackendImpl * getMyBackend() const;
184 :
185 : const bool m_jarFile;
186 :
187 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
188 :
189 : // Package
190 : virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
191 : ::osl::ResettableMutexGuard & guard,
192 : ::rtl::Reference<AbortChannel> const & abortChannel,
193 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
194 : virtual void processPackage_(
195 : ::osl::ResettableMutexGuard & guard,
196 : bool registerPackage,
197 : bool startup,
198 : ::rtl::Reference<AbortChannel> const & abortChannel,
199 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
200 :
201 : public:
202 : TypelibraryPackageImpl(
203 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
204 : OUString const & url, OUString const & name,
205 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
206 : bool jarFile, bool bRemoved,
207 : OUString const & identifier);
208 : };
209 : friend class TypelibraryPackageImpl;
210 :
211 : /** Serves for unregistering packages that were registered on a
212 : different platform. This can happen if one has remotely mounted
213 : /home, for example.
214 : */
215 0 : class OtherPlatformPackageImpl : public ::dp_registry::backend::Package
216 : {
217 : public:
218 : OtherPlatformPackageImpl(
219 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
220 : OUString const & url, OUString const & name,
221 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
222 : bool bRemoved, OUString const & identifier, OUString const& rPlatform);
223 :
224 : private:
225 : BackendImpl * getMyBackend() const;
226 :
227 : const Reference<registry::XSimpleRegistry> impl_openRDB() const;
228 : const Reference<XInterface> impl_createInstance(OUString const& rService) const;
229 :
230 : // Package
231 : virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
232 : ::osl::ResettableMutexGuard & guard,
233 : ::rtl::Reference<AbortChannel> const & abortChannel,
234 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
235 : virtual void processPackage_(
236 : ::osl::ResettableMutexGuard & guard,
237 : bool registerPackage,
238 : bool startup,
239 : ::rtl::Reference<AbortChannel> const & abortChannel,
240 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
241 :
242 : private:
243 : OUString const m_aPlatform;
244 : };
245 : friend class OtherPlatformPackageImpl;
246 :
247 : t_stringlist m_jar_typelibs;
248 : t_stringlist m_rdb_typelibs;
249 : t_stringlist m_components;
250 :
251 : enum RcItem { RCITEM_JAR_TYPELIB, RCITEM_RDB_TYPELIB, RCITEM_COMPONENTS };
252 :
253 2 : t_stringlist & getRcItemList( RcItem kind ) {
254 2 : switch (kind)
255 : {
256 : case RCITEM_JAR_TYPELIB:
257 2 : return m_jar_typelibs;
258 : case RCITEM_RDB_TYPELIB:
259 0 : return m_rdb_typelibs;
260 : default: // case RCITEM_COMPONENTS
261 0 : return m_components;
262 : }
263 : }
264 :
265 : bool m_unorc_inited;
266 : bool m_unorc_modified;
267 : bool bSwitchedRdbFiles;
268 :
269 : typedef std::unordered_map< OUString, Reference<XInterface>,
270 : OUStringHash > t_string2object;
271 : t_string2object m_backendObjects;
272 :
273 : // PackageRegistryBackend
274 : virtual Reference<deployment::XPackage> bindPackage_(
275 : OUString const & url, OUString const & mediaType,
276 : bool bRemoved, OUString const & identifier,
277 : Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
278 :
279 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
280 :
281 : const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo;
282 : const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo;
283 : const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo;
284 : const Reference<deployment::XPackageTypeInfo> m_xComponentsTypeInfo;
285 : const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo;
286 : const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo;
287 : Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
288 :
289 : OUString m_commonRDB;
290 : OUString m_nativeRDB;
291 :
292 : //URLs of the original rdbs (before any switching):
293 : OUString m_commonRDB_orig;
294 : OUString m_nativeRDB_orig;
295 :
296 : std::unique_ptr<ComponentBackendDb> m_backendDb;
297 :
298 : void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data);
299 : ComponentBackendDb::Data readDataFromDb(OUString const & url);
300 : void revokeEntryFromDb(OUString const & url);
301 :
302 : Reference<registry::XSimpleRegistry> m_xCommonRDB;
303 : Reference<registry::XSimpleRegistry> m_xNativeRDB;
304 :
305 : void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv );
306 : void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv );
307 :
308 : Reference<XInterface> getObject( OUString const & id );
309 : Reference<XInterface> insertObject(
310 : OUString const & id, Reference<XInterface> const & xObject );
311 : void releaseObject( OUString const & id );
312 :
313 : bool addToUnoRc( RcItem kind, OUString const & url,
314 : Reference<XCommandEnvironment> const & xCmdEnv );
315 : bool removeFromUnoRc( RcItem kind, OUString const & url,
316 : Reference<XCommandEnvironment> const & xCmdEnv );
317 : bool hasInUnoRc( RcItem kind, OUString const & url );
318 :
319 : css::uno::Reference< css::uno::XComponentContext > getRootContext() const;
320 :
321 : public:
322 : BackendImpl( Sequence<Any> const & args,
323 : Reference<XComponentContext> const & xComponentContext );
324 :
325 : // XPackageRegistry
326 : virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
327 : getSupportedPackageTypes() throw (RuntimeException, std::exception) SAL_OVERRIDE;
328 :
329 : virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
330 : throw (deployment::DeploymentException,
331 : uno::RuntimeException, std::exception) SAL_OVERRIDE;
332 :
333 : using PackageRegistryBackend::disposing;
334 :
335 : //Will be called from ComponentPackageImpl
336 : void initServiceRdbFiles();
337 : };
338 :
339 :
340 :
341 1 : BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
342 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
343 : OUString const & url, OUString const & name,
344 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
345 : OUString const & loader, bool bRemoved,
346 : OUString const & identifier)
347 : : Package( myBackend, url, name, name /* display-name */,
348 : xPackageType, bRemoved, identifier),
349 : m_loader( loader ),
350 1 : m_registered( REG_UNINIT )
351 1 : {}
352 :
353 : const Reference<registry::XSimpleRegistry>
354 3 : BackendImpl::ComponentPackageImpl::getRDB() const
355 : {
356 3 : BackendImpl * that = getMyBackend();
357 :
358 : //Late "initialization" of the services rdb files
359 : //This is to prevent problems when running several
360 : //instances of OOo with root rights in parallel. This
361 : //would otherwise cause problems when copying the rdbs.
362 : //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
363 : {
364 3 : const ::osl::MutexGuard guard( getMutex() );
365 3 : if (!that->bSwitchedRdbFiles)
366 : {
367 1 : that->bSwitchedRdbFiles = true;
368 1 : that->initServiceRdbFiles();
369 3 : }
370 : }
371 3 : if ( m_loader == "com.sun.star.loader.SharedLibrary" )
372 0 : return that->m_xNativeRDB;
373 : else
374 3 : return that->m_xCommonRDB;
375 : }
376 :
377 8 : BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const
378 : {
379 8 : BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
380 8 : if (NULL == pBackend)
381 : {
382 : //Throws a DisposedException
383 0 : check();
384 : //We should never get here...
385 : throw RuntimeException(
386 : "Failed to get the BackendImpl",
387 0 : static_cast<OWeakObject*>(const_cast<ComponentPackageImpl *>(this)));
388 : }
389 8 : return pBackend;
390 : }
391 :
392 :
393 :
394 1 : void BackendImpl::ComponentPackageImpl::disposing()
395 : {
396 1 : Package::disposing();
397 1 : }
398 :
399 :
400 0 : void BackendImpl::TypelibraryPackageImpl::disposing()
401 : {
402 0 : Package::disposing();
403 0 : }
404 :
405 :
406 392 : void BackendImpl::disposing()
407 : {
408 : try {
409 392 : m_backendObjects = t_string2object();
410 392 : if (m_xNativeRDB.is()) {
411 1 : m_xNativeRDB->close();
412 1 : m_xNativeRDB.clear();
413 : }
414 392 : if (m_xCommonRDB.is()) {
415 1 : m_xCommonRDB->close();
416 1 : m_xCommonRDB.clear();
417 : }
418 392 : unorc_flush( Reference<XCommandEnvironment>() );
419 :
420 392 : PackageRegistryBackend::disposing();
421 : }
422 0 : catch (const RuntimeException &) {
423 0 : throw;
424 : }
425 0 : catch (const Exception &) {
426 0 : Any exc( ::cppu::getCaughtException() );
427 : throw lang::WrappedTargetRuntimeException(
428 : "caught unexpected exception while disposing...",
429 0 : static_cast<OWeakObject *>(this), exc );
430 : }
431 392 : }
432 :
433 :
434 1 : void BackendImpl::initServiceRdbFiles()
435 : {
436 1 : const Reference<XCommandEnvironment> xCmdEnv;
437 :
438 2 : ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv, m_xComponentContext );
439 2 : ::ucbhelper::Content oldRDB;
440 : // switch common rdb:
441 1 : if (!m_commonRDB_orig.isEmpty())
442 : {
443 : (void)create_ucb_content(
444 0 : &oldRDB, makeURL( getCachePath(), m_commonRDB_orig),
445 0 : xCmdEnv, false /* no throw */ );
446 : }
447 1 : m_commonRDB = m_commonRDB_orig == "common.rdb" ? OUString("common_.rdb") : OUString("common.rdb");
448 1 : if (oldRDB.get().is())
449 : {
450 0 : if (! cacheDir.transferContent(
451 : oldRDB, ::ucbhelper::InsertOperation_COPY,
452 0 : m_commonRDB, NameClash::OVERWRITE ))
453 : {
454 :
455 0 : throw RuntimeException( "UCB transferContent() failed!", 0 );
456 : }
457 0 : oldRDB = ::ucbhelper::Content();
458 : }
459 : // switch native rdb:
460 1 : if (!m_nativeRDB_orig.isEmpty())
461 : {
462 : (void)create_ucb_content(
463 0 : &oldRDB, makeURL(getCachePath(), m_nativeRDB_orig),
464 0 : xCmdEnv, false /* no throw */ );
465 : }
466 2 : const OUString plt_rdb( getPlatformString() + ".rdb" );
467 2 : const OUString plt_rdb_( getPlatformString() + "_.rdb" );
468 1 : m_nativeRDB = (m_nativeRDB_orig == plt_rdb ) ? plt_rdb_ : plt_rdb;
469 1 : if (oldRDB.get().is())
470 : {
471 0 : if (! cacheDir.transferContent(
472 : oldRDB, ::ucbhelper::InsertOperation_COPY,
473 0 : m_nativeRDB, NameClash::OVERWRITE ))
474 0 : throw RuntimeException( "UCB transferContent() failed!", 0 );
475 : }
476 :
477 : // UNO is bootstrapped, flush for next process start:
478 1 : m_unorc_modified = true;
479 1 : unorc_flush( Reference<XCommandEnvironment>() );
480 :
481 :
482 : // common rdb for java, native rdb for shared lib components
483 1 : if (!m_commonRDB.isEmpty()) {
484 : m_xCommonRDB.set(
485 1 : m_xComponentContext->getServiceManager()
486 2 : ->createInstanceWithContext(
487 : "com.sun.star.registry.SimpleRegistry",
488 1 : m_xComponentContext ), UNO_QUERY_THROW );
489 1 : m_xCommonRDB->open(
490 1 : makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ),
491 2 : false, true);
492 : }
493 1 : if (!m_nativeRDB.isEmpty()) {
494 : m_xNativeRDB.set(
495 1 : m_xComponentContext->getServiceManager()
496 2 : ->createInstanceWithContext(
497 : "com.sun.star.registry.SimpleRegistry",
498 1 : m_xComponentContext ), UNO_QUERY_THROW );
499 1 : m_xNativeRDB->open(
500 1 : makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ),
501 2 : false, true);
502 1 : }
503 1 : }
504 :
505 392 : BackendImpl::BackendImpl(
506 : Sequence<Any> const & args,
507 : Reference<XComponentContext> const & xComponentContext )
508 : : PackageRegistryBackend( args, xComponentContext ),
509 : m_unorc_inited( false ),
510 : m_unorc_modified( false ),
511 : bSwitchedRdbFiles(false),
512 : m_xDynComponentTypeInfo( new Package::TypeInfo(
513 784 : "application/vnd.sun.star.uno-component;type=native;platform=" +
514 392 : getPlatformString(),
515 : "*" SAL_DLLEXTENSION,
516 : getResourceString(RID_STR_DYN_COMPONENT),
517 392 : RID_IMG_COMPONENT) ),
518 : m_xJavaComponentTypeInfo( new Package::TypeInfo(
519 : "application/vnd.sun.star.uno-component;type=Java",
520 : "*.jar",
521 : getResourceString(RID_STR_JAVA_COMPONENT),
522 392 : RID_IMG_JAVA_COMPONENT) ),
523 : m_xPythonComponentTypeInfo( new Package::TypeInfo(
524 : "application/vnd.sun.star.uno-component;type=Python",
525 : "*.py",
526 : getResourceString(
527 : RID_STR_PYTHON_COMPONENT),
528 392 : RID_IMG_COMPONENT ) ),
529 : m_xComponentsTypeInfo( new Package::TypeInfo(
530 : "application/vnd.sun.star.uno-components",
531 : "*.components",
532 : getResourceString(RID_STR_COMPONENTS),
533 392 : RID_IMG_COMPONENT ) ),
534 : m_xRDBTypelibTypeInfo( new Package::TypeInfo(
535 : "application/vnd.sun.star.uno-typelibrary;type=RDB",
536 : "*.rdb",
537 : getResourceString(RID_STR_RDB_TYPELIB),
538 392 : RID_IMG_TYPELIB ) ),
539 : m_xJavaTypelibTypeInfo( new Package::TypeInfo(
540 : "application/vnd.sun.star.uno-typelibrary;type=Java",
541 : "*.jar",
542 : getResourceString(RID_STR_JAVA_TYPELIB),
543 392 : RID_IMG_JAVA_TYPELIB ) ),
544 3528 : m_typeInfos( 6 )
545 : {
546 392 : m_typeInfos[ 0 ] = m_xDynComponentTypeInfo;
547 392 : m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo;
548 392 : m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo;
549 392 : m_typeInfos[ 3 ] = m_xComponentsTypeInfo;
550 392 : m_typeInfos[ 4 ] = m_xRDBTypelibTypeInfo;
551 392 : m_typeInfos[ 5 ] = m_xJavaTypelibTypeInfo;
552 :
553 392 : const Reference<XCommandEnvironment> xCmdEnv;
554 :
555 392 : if (transientMode())
556 : {
557 : // in-mem rdbs:
558 : // common rdb for java, native rdb for shared lib components
559 : m_xCommonRDB.set(
560 0 : xComponentContext->getServiceManager()->createInstanceWithContext(
561 : "com.sun.star.registry.SimpleRegistry",
562 0 : xComponentContext ), UNO_QUERY_THROW );
563 0 : m_xCommonRDB->open( OUString() /* in-mem */,
564 0 : false /* ! read-only */, true /* create */ );
565 : m_xNativeRDB.set(
566 0 : xComponentContext->getServiceManager()->createInstanceWithContext(
567 : "com.sun.star.registry.SimpleRegistry",
568 0 : xComponentContext ), UNO_QUERY_THROW );
569 0 : m_xNativeRDB->open( OUString() /* in-mem */,
570 0 : false /* ! read-only */, true /* create */ );
571 : }
572 : else
573 : {
574 392 : unorc_verify_init( xCmdEnv );
575 392 : OUString dbFile = makeURL(getCachePath(), "backenddb.xml");
576 : m_backendDb.reset(
577 392 : new ComponentBackendDb(getComponentContext(), dbFile));
578 392 : }
579 392 : }
580 :
581 1 : void BackendImpl::addDataToDb(
582 : OUString const & url, ComponentBackendDb::Data const & data)
583 : {
584 1 : if (m_backendDb.get())
585 1 : m_backendDb->addEntry(url, data);
586 1 : }
587 :
588 1 : ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url)
589 : {
590 1 : ComponentBackendDb::Data data;
591 1 : if (m_backendDb.get())
592 1 : data = m_backendDb->getEntry(url);
593 1 : return data;
594 : }
595 :
596 1 : void BackendImpl::revokeEntryFromDb(OUString const & url)
597 : {
598 1 : if (m_backendDb.get())
599 1 : m_backendDb->revokeEntry(url);
600 1 : }
601 :
602 : // XPackageRegistry
603 :
604 : Sequence< Reference<deployment::XPackageTypeInfo> >
605 392 : BackendImpl::getSupportedPackageTypes() throw (RuntimeException, std::exception)
606 : {
607 392 : return m_typeInfos;
608 : }
609 :
610 1 : void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
611 : throw (deployment::DeploymentException,
612 : uno::RuntimeException, std::exception)
613 : {
614 1 : if (m_backendDb.get())
615 1 : m_backendDb->removeEntry(url);
616 1 : }
617 :
618 : // PackageRegistryBackend
619 :
620 4 : Reference<deployment::XPackage> BackendImpl::bindPackage_(
621 : OUString const & url, OUString const & mediaType_,
622 : bool bRemoved, OUString const & identifier,
623 : Reference<XCommandEnvironment> const & xCmdEnv )
624 : {
625 4 : OUString mediaType(mediaType_);
626 4 : if ( mediaType.isEmpty() || mediaType == "application/vnd.sun.star.uno-component" || mediaType == "application/vnd.sun.star.uno-typelibrary" )
627 : {
628 : // detect exact media-type:
629 3 : ::ucbhelper::Content ucbContent;
630 3 : if (create_ucb_content( &ucbContent, url, xCmdEnv )) {
631 3 : const OUString title( StrTitle::getTitle( ucbContent ) );
632 3 : if (title.endsWithIgnoreAsciiCase(SAL_DLLEXTENSION))
633 : {
634 0 : mediaType = "application/vnd.sun.star.uno-component;type=native;platform=" +
635 0 : getPlatformString();
636 : }
637 3 : else if (title.endsWithIgnoreAsciiCase(".jar"))
638 : {
639 0 : if (jarManifestHeaderPresent(
640 0 : url, "RegistrationClassName", xCmdEnv ))
641 0 : mediaType = "application/vnd.sun.star.uno-component;type=Java";
642 0 : if (mediaType.isEmpty())
643 0 : mediaType = "application/vnd.sun.star.uno-typelibrary;type=Java";
644 : }
645 3 : else if (title.endsWithIgnoreAsciiCase(".py"))
646 0 : mediaType = "application/vnd.sun.star.uno-component;type=Python";
647 3 : else if (title.endsWithIgnoreAsciiCase(".rdb"))
648 0 : mediaType = "application/vnd.sun.star.uno-typelibrary;type=RDB";
649 : }
650 3 : if (mediaType.isEmpty())
651 : throw lang::IllegalArgumentException(
652 6 : StrCannotDetectMediaType::get() + url,
653 9 : static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
654 : }
655 :
656 2 : OUString type, subType;
657 2 : INetContentTypeParameterList params;
658 1 : if (INetContentTypes::parse( mediaType, type, subType, ¶ms ))
659 : {
660 1 : if (type.equalsIgnoreAsciiCase("application"))
661 : {
662 1 : OUString name;
663 1 : if (!bRemoved)
664 : {
665 1 : ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
666 1 : name = StrTitle::getTitle( ucbContent );
667 : }
668 :
669 1 : if (subType.equalsIgnoreAsciiCase("vnd.sun.star.uno-component"))
670 : {
671 : // xxx todo: probe and evaluate component xml description
672 :
673 1 : INetContentTypeParameter const * param = params.find(OString("platform"));
674 1 : bool bPlatformFits(param == 0);
675 1 : OUString aPlatform;
676 1 : if (!bPlatformFits) // platform is specified, we have to check
677 : {
678 0 : aPlatform = param->m_sValue;
679 0 : bPlatformFits = platform_fits(aPlatform);
680 : }
681 : // If the package is being removed, do not care whether
682 : // platform fits. We won't be using it anyway.
683 1 : if (bPlatformFits || bRemoved) {
684 1 : param = params.find(OString("type"));
685 1 : if (param != 0)
686 : {
687 1 : OUString const & value = param->m_sValue;
688 1 : if (value.equalsIgnoreAsciiCase("native")) {
689 0 : if (bPlatformFits)
690 : return new BackendImpl::ComponentPackageImpl(
691 : this, url, name, m_xDynComponentTypeInfo,
692 : "com.sun.star.loader.SharedLibrary",
693 0 : bRemoved, identifier);
694 : else
695 : return new BackendImpl::OtherPlatformPackageImpl(
696 : this, url, name, m_xDynComponentTypeInfo,
697 0 : bRemoved, identifier, aPlatform);
698 : }
699 1 : if (value.equalsIgnoreAsciiCase("Java")) {
700 : return new BackendImpl::ComponentPackageImpl(
701 : this, url, name, m_xJavaComponentTypeInfo,
702 : "com.sun.star.loader.Java2",
703 1 : bRemoved, identifier);
704 : }
705 0 : if (value.equalsIgnoreAsciiCase("Python")) {
706 : return new BackendImpl::ComponentPackageImpl(
707 : this, url, name, m_xPythonComponentTypeInfo,
708 : "com.sun.star.loader.Python",
709 0 : bRemoved, identifier);
710 : }
711 : }
712 0 : }
713 : }
714 0 : else if (subType.equalsIgnoreAsciiCase("vnd.sun.star.uno-components"))
715 : {
716 0 : INetContentTypeParameter const * param = params.find(OString("platform"));
717 0 : if (param == 0 || platform_fits( param->m_sValue )) {
718 : return new BackendImpl::ComponentsPackageImpl(
719 : this, url, name, m_xComponentsTypeInfo, bRemoved,
720 0 : identifier);
721 : }
722 : }
723 0 : else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.uno-typelibrary"))
724 : {
725 0 : INetContentTypeParameter const * param = params.find(OString("type"));
726 0 : if (param != 0) {
727 0 : OUString const & value = param->m_sValue;
728 0 : if (value.equalsIgnoreAsciiCase("RDB"))
729 : {
730 : return new BackendImpl::TypelibraryPackageImpl(
731 : this, url, name, m_xRDBTypelibTypeInfo,
732 0 : false /* rdb */, bRemoved, identifier);
733 : }
734 0 : if (value.equalsIgnoreAsciiCase("Java")) {
735 : return new BackendImpl::TypelibraryPackageImpl(
736 : this, url, name, m_xJavaTypelibTypeInfo,
737 0 : true /* jar */, bRemoved, identifier);
738 : }
739 : }
740 0 : }
741 : }
742 : }
743 : throw lang::IllegalArgumentException(
744 0 : StrUnsupportedMediaType::get() + mediaType,
745 : static_cast<OWeakObject *>(this),
746 4 : static_cast<sal_Int16>(-1) );
747 : }
748 :
749 :
750 :
751 394 : void BackendImpl::unorc_verify_init(
752 : Reference<XCommandEnvironment> const & xCmdEnv )
753 : {
754 394 : if (transientMode())
755 394 : return;
756 394 : const ::osl::MutexGuard guard( getMutex() );
757 394 : if (! m_unorc_inited)
758 : {
759 : // common rc:
760 392 : ::ucbhelper::Content ucb_content;
761 784 : if (create_ucb_content(
762 : &ucb_content,
763 392 : makeURL( getCachePath(), "unorc" ),
764 1176 : xCmdEnv, false /* no throw */ ))
765 : {
766 0 : OUString line;
767 0 : if (readLine( &line, "UNO_JAVA_CLASSPATH=", ucb_content,
768 0 : RTL_TEXTENCODING_UTF8 ))
769 : {
770 0 : sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
771 0 : do {
772 0 : OUString token( line.getToken( 0, ' ', index ).trim() );
773 0 : if (!token.isEmpty())
774 : {
775 0 : if (create_ucb_content(
776 : 0, expandUnoRcTerm(token), xCmdEnv,
777 0 : false /* no throw */ ))
778 : {
779 : //The jar file may not exist anymore if a shared or bundled
780 : //extension was removed, but it can still be in the unorc
781 : //After running XExtensionManager::synchronize, the unorc is
782 : //cleaned up
783 0 : m_jar_typelibs.push_back( token );
784 : }
785 0 : }
786 : }
787 0 : while (index >= 0);
788 : }
789 0 : if (readLine( &line, "UNO_TYPES=", ucb_content,
790 0 : RTL_TEXTENCODING_UTF8 )) {
791 0 : sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
792 0 : do {
793 0 : OUString token( line.getToken( 0, ' ', index ).trim() );
794 0 : if (!token.isEmpty())
795 : {
796 0 : if (token[ 0 ] == '?')
797 0 : token = token.copy( 1 );
798 0 : if (create_ucb_content(
799 : 0, expandUnoRcTerm(token), xCmdEnv,
800 0 : false /* no throw */ ))
801 : {
802 : //The RDB file may not exist anymore if a shared or bundled
803 : //extension was removed, but it can still be in the unorc.
804 : //After running XExtensionManager::synchronize, the unorc is
805 : //cleaned up
806 0 : m_rdb_typelibs.push_back( token );
807 : }
808 0 : }
809 : }
810 0 : while (index >= 0);
811 : }
812 0 : if (readLine( &line, "UNO_SERVICES=", ucb_content,
813 0 : RTL_TEXTENCODING_UTF8 ))
814 : {
815 : // The UNO_SERVICES line always has the BNF form
816 : // "UNO_SERVICES="
817 : // ("?$ORIGIN/" <common-rdb>)? -- first
818 : // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second
819 : // ("?" ("BUNDLED_EXTENSIONS" | -- third
820 : // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
821 : // ...)*
822 : // so can unambiguously be split into its thre parts:
823 0 : int state = 1;
824 0 : for (sal_Int32 i = RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
825 0 : i >= 0;)
826 : {
827 0 : OUString token(line.getToken(0, ' ', i));
828 0 : if (!token.isEmpty())
829 : {
830 0 : if (state == 1 && token.match("?$ORIGIN/"))
831 : {
832 0 : m_commonRDB_orig = token.copy(
833 0 : RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
834 0 : state = 2;
835 : }
836 0 : else if ( state <= 2 && token == "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" )
837 : {
838 0 : state = 3;
839 : }
840 : else
841 : {
842 0 : if (token[0] == '?')
843 : {
844 0 : token = token.copy(1);
845 : }
846 0 : m_components.push_back(token);
847 0 : state = 3;
848 : }
849 : }
850 0 : }
851 : }
852 :
853 : // native rc:
854 0 : if (create_ucb_content(
855 : &ucb_content,
856 0 : makeURL( getCachePath(), getPlatformString() + "rc"),
857 0 : xCmdEnv, false /* no throw */ )) {
858 0 : if (readLine( &line, "UNO_SERVICES=", ucb_content,
859 0 : RTL_TEXTENCODING_UTF8 )) {
860 0 : m_nativeRDB_orig = line.copy(
861 0 : sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
862 : }
863 0 : }
864 : }
865 392 : m_unorc_modified = false;
866 392 : m_unorc_inited = true;
867 394 : }
868 : }
869 :
870 :
871 395 : void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
872 : {
873 395 : if (transientMode())
874 392 : return;
875 395 : if (!m_unorc_inited || !m_unorc_modified)
876 392 : return;
877 :
878 3 : OStringBuffer buf;
879 :
880 3 : buf.append("ORIGIN=");
881 6 : OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
882 6 : OString osOrigin = OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
883 3 : buf.append(osOrigin);
884 3 : buf.append(LF);
885 :
886 3 : if (! m_jar_typelibs.empty())
887 : {
888 1 : t_stringlist::const_iterator iPos( m_jar_typelibs.begin() );
889 1 : t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() );
890 1 : buf.append( "UNO_JAVA_CLASSPATH=" );
891 3 : while (iPos != iEnd) {
892 : // encoded ASCII file-urls:
893 : const OString item(
894 1 : OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
895 1 : buf.append( item );
896 1 : ++iPos;
897 1 : if (iPos != iEnd)
898 0 : buf.append( ' ' );
899 1 : }
900 1 : buf.append(LF);
901 : }
902 3 : if (! m_rdb_typelibs.empty())
903 : {
904 0 : t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() );
905 0 : t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() );
906 0 : buf.append( "UNO_TYPES=" );
907 0 : while (iPos != iEnd) {
908 0 : buf.append( '?' );
909 : // encoded ASCII file-urls:
910 : const OString item(
911 0 : OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
912 0 : buf.append( item );
913 0 : ++iPos;
914 0 : if (iPos != iEnd)
915 0 : buf.append( ' ' );
916 0 : }
917 0 : buf.append(LF);
918 : }
919 :
920 : // If we duplicated the common or native rdb then we must use those urls
921 : //otherwise we use those of the original files. That is, m_commonRDB_orig
922 : //and m_nativeRDB_orig;
923 6 : OUString sCommonRDB(m_commonRDB.isEmpty() ? m_commonRDB_orig : m_commonRDB );
924 6 : OUString sNativeRDB(m_nativeRDB.isEmpty() ? m_nativeRDB_orig : m_nativeRDB );
925 :
926 3 : if (!sCommonRDB.isEmpty() || !sNativeRDB.isEmpty() ||
927 0 : !m_components.empty())
928 : {
929 3 : buf.append( "UNO_SERVICES=" );
930 3 : bool space = false;
931 3 : if (!sCommonRDB.isEmpty())
932 : {
933 3 : buf.append( "?$ORIGIN/" );
934 : buf.append( OUStringToOString(
935 3 : sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
936 3 : space = true;
937 : }
938 3 : if (!sNativeRDB.isEmpty())
939 : {
940 3 : if (space)
941 : {
942 3 : buf.append(' ');
943 : }
944 3 : buf.append( "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" );
945 3 : space = true;
946 :
947 : // write native rc:
948 3 : OStringBuffer buf2;
949 3 : buf2.append("ORIGIN=");
950 3 : buf2.append(osOrigin);
951 3 : buf2.append(LF);
952 3 : buf2.append( "UNO_SERVICES=?$ORIGIN/" );
953 : buf2.append( OUStringToOString(
954 3 : sNativeRDB, RTL_TEXTENCODING_ASCII_US ) );
955 3 : buf2.append(LF);
956 :
957 : const Reference<io::XInputStream> xData(
958 : ::xmlscript::createInputStream(
959 : ::rtl::ByteSequence(
960 3 : reinterpret_cast<sal_Int8 const *>(buf2.getStr()),
961 9 : buf2.getLength() ) ) );
962 : ::ucbhelper::Content ucb_content(
963 9 : makeURL( getCachePath(), getPlatformString() + "rc" ),
964 12 : xCmdEnv, m_xComponentContext );
965 6 : ucb_content.writeStream( xData, true /* replace existing */ );
966 : }
967 9 : for (t_stringlist::iterator i(m_components.begin());
968 6 : i != m_components.end(); ++i)
969 : {
970 0 : if (space)
971 : {
972 0 : buf.append(' ');
973 : }
974 0 : buf.append('?');
975 0 : buf.append(OUStringToOString(*i, RTL_TEXTENCODING_UTF8));
976 0 : space = true;
977 : }
978 3 : buf.append(LF);
979 : }
980 :
981 : // write unorc:
982 : const Reference<io::XInputStream> xData(
983 : ::xmlscript::createInputStream(
984 : ::rtl::ByteSequence(
985 3 : reinterpret_cast<sal_Int8 const *>(buf.getStr()),
986 9 : buf.getLength() ) ) );
987 : ::ucbhelper::Content ucb_content(
988 6 : makeURL( getCachePath(), "unorc" ), xCmdEnv, m_xComponentContext );
989 3 : ucb_content.writeStream( xData, true /* replace existing */ );
990 :
991 6 : m_unorc_modified = false;
992 : }
993 :
994 :
995 1 : bool BackendImpl::addToUnoRc( RcItem kind, OUString const & url_,
996 : Reference<XCommandEnvironment> const & xCmdEnv )
997 : {
998 1 : const OUString rcterm( dp_misc::makeRcTerm(url_) );
999 2 : const ::osl::MutexGuard guard( getMutex() );
1000 1 : unorc_verify_init( xCmdEnv );
1001 1 : t_stringlist & rSet = getRcItemList(kind);
1002 1 : if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
1003 1 : rSet.push_front( rcterm ); // prepend to list, thus overriding
1004 : // write immediately:
1005 1 : m_unorc_modified = true;
1006 1 : unorc_flush( xCmdEnv );
1007 1 : return true;
1008 : }
1009 : else
1010 1 : return false;
1011 : }
1012 :
1013 :
1014 1 : bool BackendImpl::removeFromUnoRc(
1015 : RcItem kind, OUString const & url_,
1016 : Reference<XCommandEnvironment> const & xCmdEnv )
1017 : {
1018 1 : const OUString rcterm( dp_misc::makeRcTerm(url_) );
1019 2 : const ::osl::MutexGuard guard( getMutex() );
1020 1 : unorc_verify_init( xCmdEnv );
1021 1 : getRcItemList(kind).remove( rcterm );
1022 : // write immediately:
1023 1 : m_unorc_modified = true;
1024 1 : unorc_flush( xCmdEnv );
1025 2 : return true;
1026 : }
1027 :
1028 :
1029 0 : bool BackendImpl::hasInUnoRc(
1030 : RcItem kind, OUString const & url_ )
1031 : {
1032 0 : const OUString rcterm( dp_misc::makeRcTerm(url_) );
1033 0 : const ::osl::MutexGuard guard( getMutex() );
1034 0 : t_stringlist const & rSet = getRcItemList(kind);
1035 0 : return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end();
1036 : }
1037 :
1038 2 : css::uno::Reference< css::uno::XComponentContext > BackendImpl::getRootContext()
1039 : const
1040 : {
1041 : css::uno::Reference< css::uno::XComponentContext > rootContext(
1042 2 : getComponentContext()->getValueByName("_root"),
1043 2 : css::uno::UNO_QUERY);
1044 2 : return rootContext.is() ? rootContext : getComponentContext();
1045 : }
1046 :
1047 :
1048 1 : void BackendImpl::releaseObject( OUString const & id )
1049 : {
1050 1 : const ::osl::MutexGuard guard( getMutex() );
1051 1 : m_backendObjects.erase( id );
1052 1 : }
1053 :
1054 :
1055 2 : Reference<XInterface> BackendImpl::getObject( OUString const & id )
1056 : {
1057 2 : const ::osl::MutexGuard guard( getMutex() );
1058 2 : const t_string2object::const_iterator iFind( m_backendObjects.find( id ) );
1059 2 : if (iFind == m_backendObjects.end())
1060 1 : return Reference<XInterface>();
1061 : else
1062 1 : return iFind->second;
1063 : }
1064 :
1065 :
1066 1 : Reference<XInterface> BackendImpl::insertObject(
1067 : OUString const & id, Reference<XInterface> const & xObject )
1068 : {
1069 1 : const ::osl::MutexGuard guard( getMutex() );
1070 : const ::std::pair<t_string2object::iterator, bool> insertion(
1071 : m_backendObjects.insert( t_string2object::value_type(
1072 1 : id, xObject ) ) );
1073 1 : return insertion.first->second;
1074 : }
1075 :
1076 :
1077 1 : Reference<XComponentContext> raise_uno_process(
1078 : Reference<XComponentContext> const & xContext,
1079 : ::rtl::Reference<AbortChannel> const & abortChannel )
1080 : {
1081 : OSL_ASSERT( xContext.is() );
1082 :
1083 1 : OUString url( util::theMacroExpander::get(xContext)->expandMacros( "$URE_BIN_DIR/uno" ) );
1084 :
1085 2 : const OUString connectStr = "uno:pipe,name=" + generateRandomPipeId() + ";urp;uno.ComponentContext";
1086 :
1087 : // raise core UNO process to register/run a component,
1088 : // javavm service uses unorc next to executable to retrieve deployed
1089 : // jar typelibs
1090 :
1091 : ::std::vector<OUString> args{
1092 : #if OSL_DEBUG_LEVEL == 0
1093 : "--quiet",
1094 : #endif
1095 : "--singleaccept",
1096 : "-u",
1097 : connectStr,
1098 : // don't inherit from unorc:
1099 2 : "-env:INIFILENAME=" };
1100 :
1101 : //now add the bootstrap variables which were supplied on the command line
1102 2 : ::std::vector<OUString> bootvars = getCmdBootstrapVariables();
1103 1 : args.insert(args.end(), bootvars.begin(), bootvars.end());
1104 :
1105 : oslProcess hProcess;
1106 : try {
1107 : hProcess = raiseProcess(
1108 1 : url, comphelper::containerToSequence(args) );
1109 : }
1110 0 : catch (...) {
1111 0 : OUString sMsg = "error starting process: " + url;
1112 0 : for(auto arg : args)
1113 0 : sMsg += " " + arg;
1114 0 : throw uno::RuntimeException(sMsg);
1115 : }
1116 : try {
1117 : return Reference<XComponentContext>(
1118 : resolveUnoURL( connectStr, xContext, abortChannel.get() ),
1119 2 : UNO_QUERY_THROW );
1120 : }
1121 0 : catch (...) {
1122 : // try to terminate process:
1123 0 : if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
1124 : {
1125 : OSL_ASSERT( false );
1126 : }
1127 0 : throw;
1128 1 : }
1129 : }
1130 :
1131 :
1132 : namespace {
1133 :
1134 1 : void extractComponentData(
1135 : css::uno::Reference< css::uno::XComponentContext > const & context,
1136 : css::uno::Reference< css::registry::XRegistryKey > const & registry,
1137 : ComponentBackendDb::Data * data,
1138 : std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
1139 : css::uno::Reference< css::loader::XImplementationLoader > const &
1140 : componentLoader,
1141 : OUString const & componentUrl)
1142 : {
1143 : OSL_ASSERT(
1144 : context.is() && registry.is() && data != 0 && componentLoader.is());
1145 1 : OUString registryName(registry->getKeyName());
1146 1 : sal_Int32 prefix = registryName.getLength();
1147 1 : if (!registryName.endsWith("/")) {
1148 0 : prefix += RTL_CONSTASCII_LENGTH("/");
1149 : }
1150 : css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
1151 2 : keys(registry->openKeys());
1152 : css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
1153 2 : context->getServiceManager(), css::uno::UNO_QUERY_THROW);
1154 2 : for (sal_Int32 i = 0; i < keys.getLength(); ++i) {
1155 1 : OUString name(keys[i]->getKeyName().copy(prefix));
1156 1 : data->implementationNames.push_back(name);
1157 : css::uno::Reference< css::registry::XRegistryKey > singletons(
1158 2 : keys[i]->openKey("UNO/SINGLETONS"));
1159 1 : if (singletons.is()) {
1160 0 : sal_Int32 prefix2 = keys[i]->getKeyName().getLength() +
1161 0 : RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
1162 : css::uno::Sequence<
1163 : css::uno::Reference< css::registry::XRegistryKey > >
1164 0 : singletonKeys(singletons->openKeys());
1165 0 : for (sal_Int32 j = 0; j < singletonKeys.getLength(); ++j) {
1166 : data->singletons.push_back(
1167 : std::pair< OUString, OUString >(
1168 0 : singletonKeys[j]->getKeyName().copy(prefix2), name));
1169 0 : }
1170 : }
1171 1 : if (factories != 0) {
1172 : factories->push_back(
1173 1 : componentLoader->activate(
1174 1 : name, OUString(), componentUrl, keys[i]));
1175 : }
1176 2 : }
1177 1 : }
1178 :
1179 : }
1180 :
1181 1 : void BackendImpl::ComponentPackageImpl::getComponentInfo(
1182 : ComponentBackendDb::Data * data,
1183 : std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
1184 : Reference<XComponentContext> const & xContext )
1185 : {
1186 : const Reference<loader::XImplementationLoader> xLoader(
1187 2 : xContext->getServiceManager()->createInstanceWithContext(
1188 1 : m_loader, xContext ), UNO_QUERY );
1189 1 : if (! xLoader.is())
1190 : {
1191 : throw css::deployment::DeploymentException(
1192 0 : "cannot instantiate loader " + m_loader,
1193 0 : static_cast< OWeakObject * >(this), Any());
1194 : }
1195 :
1196 : // HACK: highly dependent on stoc/source/servicemanager
1197 : // and stoc/source/implreg implementation which rely on the same
1198 : // services.rdb format!
1199 : // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
1200 : // writeRegistryInfo, however, but are known, fixed values here, so
1201 : // can be passed into extractComponentData
1202 2 : OUString url(getURL());
1203 : const Reference<registry::XSimpleRegistry> xMemReg(
1204 2 : xContext->getServiceManager()->createInstanceWithContext(
1205 1 : "com.sun.star.registry.SimpleRegistry", xContext ),
1206 2 : UNO_QUERY_THROW );
1207 1 : xMemReg->open( OUString() /* in mem */, false, true );
1208 1 : xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), url );
1209 : extractComponentData(
1210 2 : xContext, xMemReg->getRootKey(), data, factories, xLoader, url);
1211 1 : }
1212 :
1213 1 : void BackendImpl::ComponentPackageImpl::componentLiveInsertion(
1214 : ComponentBackendDb::Data const & data,
1215 : std::vector< css::uno::Reference< css::uno::XInterface > > const &
1216 : factories)
1217 : {
1218 : css::uno::Reference< css::uno::XComponentContext > rootContext(
1219 1 : getMyBackend()->getRootContext());
1220 : css::uno::Reference< css::container::XSet > set(
1221 2 : rootContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
1222 : std::vector< css::uno::Reference< css::uno::XInterface > >::const_iterator
1223 1 : factory(factories.begin());
1224 6 : for (t_stringlist::const_iterator i(data.implementationNames.begin());
1225 4 : i != data.implementationNames.end(); ++i)
1226 : {
1227 : try {
1228 1 : set->insert(css::uno::Any(*factory++));
1229 0 : } catch (const container::ElementExistException &) {
1230 : OSL_TRACE(
1231 : "implementation %s already registered",
1232 : OUStringToOString(*i, RTL_TEXTENCODING_UTF8).getStr());
1233 : }
1234 : }
1235 1 : if (!data.singletons.empty()) {
1236 : css::uno::Reference< css::container::XNameContainer > cont(
1237 0 : rootContext, css::uno::UNO_QUERY_THROW);
1238 0 : for (t_stringpairvec::const_iterator i(data.singletons.begin());
1239 0 : i != data.singletons.end(); ++i)
1240 : {
1241 0 : OUString name("/singletons/" + i->first);
1242 : //TODO: Update should be atomic:
1243 : try {
1244 0 : cont->removeByName( name + "/arguments");
1245 0 : } catch (const container::NoSuchElementException &) {}
1246 : try {
1247 0 : cont->insertByName( name + "/service", css::uno::Any(i->second));
1248 0 : } catch (const container::ElementExistException &) {
1249 0 : cont->replaceByName( name + "/service", css::uno::Any(i->second));
1250 : }
1251 : try {
1252 0 : cont->insertByName(name, css::uno::Any());
1253 0 : } catch (const container::ElementExistException &) {
1254 : OSL_TRACE(
1255 : "singleton %s already registered",
1256 : OUStringToOString(
1257 : i->first, RTL_TEXTENCODING_UTF8).getStr());
1258 0 : cont->replaceByName(name, css::uno::Any());
1259 : }
1260 0 : }
1261 1 : }
1262 1 : }
1263 :
1264 1 : void BackendImpl::ComponentPackageImpl::componentLiveRemoval(
1265 : ComponentBackendDb::Data const & data)
1266 : {
1267 : css::uno::Reference< css::uno::XComponentContext > rootContext(
1268 1 : getMyBackend()->getRootContext());
1269 : css::uno::Reference< css::container::XSet > set(
1270 2 : rootContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
1271 6 : for (t_stringlist::const_iterator i(data.implementationNames.begin());
1272 4 : i != data.implementationNames.end(); ++i)
1273 : {
1274 : try {
1275 1 : set->remove(css::uno::Any(*i));
1276 0 : } catch (const css::container::NoSuchElementException &) {
1277 : // ignore if factory has not been live deployed
1278 : }
1279 : }
1280 1 : if (!data.singletons.empty()) {
1281 : css::uno::Reference< css::container::XNameContainer > cont(
1282 0 : rootContext, css::uno::UNO_QUERY_THROW);
1283 0 : for (t_stringpairvec::const_iterator i(data.singletons.begin());
1284 0 : i != data.singletons.end(); ++i)
1285 : {
1286 0 : OUString name("/singletons/" + i->first);
1287 : //TODO: Removal should be atomic:
1288 : try {
1289 0 : cont->removeByName(name);
1290 0 : } catch (const container::NoSuchElementException &) {}
1291 : try {
1292 0 : cont->removeByName( name + "/service" );
1293 0 : } catch (const container::NoSuchElementException &) {}
1294 : try {
1295 0 : cont->removeByName( name + "/arguments" );
1296 0 : } catch (const container::NoSuchElementException &) {}
1297 0 : }
1298 1 : }
1299 1 : }
1300 :
1301 : // Package
1302 :
1303 : //We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
1304 : //And it also shows the problem if another extension has overwritten an implementation
1305 : //entry, because it contains the same service implementation
1306 : beans::Optional< beans::Ambiguous<sal_Bool> >
1307 6 : BackendImpl::ComponentPackageImpl::isRegistered_(
1308 : ::osl::ResettableMutexGuard &,
1309 : ::rtl::Reference<AbortChannel> const & abortChannel,
1310 : Reference<XCommandEnvironment> const & )
1311 : {
1312 6 : if (m_registered == REG_UNINIT)
1313 : {
1314 1 : m_registered = REG_NOT_REGISTERED;
1315 1 : const Reference<registry::XSimpleRegistry> xRDB( getRDB() );
1316 1 : if (xRDB.is())
1317 : {
1318 1 : bool bAmbiguousComponentName = false;
1319 : // lookup rdb for location URL:
1320 : const Reference<registry::XRegistryKey> xRootKey(
1321 1 : xRDB->getRootKey() );
1322 : const Reference<registry::XRegistryKey> xImplKey(
1323 2 : xRootKey->openKey( "IMPLEMENTATIONS" ) );
1324 2 : Sequence<OUString> implNames;
1325 1 : if (xImplKey.is() && xImplKey->isValid())
1326 0 : implNames = xImplKey->getKeyNames();
1327 1 : OUString const * pImplNames = implNames.getConstArray();
1328 1 : sal_Int32 pos = implNames.getLength();
1329 1 : for ( ; pos--; )
1330 : {
1331 0 : checkAborted( abortChannel );
1332 : const OUString key(
1333 0 : pImplNames[ pos ] + "/UNO/LOCATION" );
1334 : const Reference<registry::XRegistryKey> xKey(
1335 0 : xRootKey->openKey(key) );
1336 0 : if (xKey.is() && xKey->isValid())
1337 : {
1338 0 : const OUString location( xKey->getAsciiValue() );
1339 0 : if (location.equalsIgnoreAsciiCase( getURL() ))
1340 : {
1341 0 : break;
1342 : }
1343 : else
1344 : {
1345 : //try to match only the file name
1346 0 : OUString thisUrl(getURL());
1347 0 : OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
1348 :
1349 0 : OUString locationFileName(location.copy(location.lastIndexOf('/')));
1350 0 : if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
1351 0 : bAmbiguousComponentName = true;
1352 0 : }
1353 : }
1354 0 : }
1355 1 : if (pos >= 0)
1356 0 : m_registered = REG_REGISTERED;
1357 1 : else if (bAmbiguousComponentName)
1358 1 : m_registered = REG_MAYBE_REGISTERED;
1359 1 : }
1360 : }
1361 :
1362 : //Different extensions can use the same service implementations. Then the extensions
1363 : //which was installed last will overwrite the one from the other extension. That is
1364 : //the registry will contain the path (the location) of the library or jar of the
1365 : //second extension. In this case isRegistered called for the lib of the first extension
1366 : //would return "not registered". That would mean that during uninstallation
1367 : //XPackage::registerPackage is not called, because it just was not registered. This is,
1368 : //however, necessary for jar files. Registering and unregistering update
1369 : //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
1370 : //Therefore, we will return always "is ambiguous" if the path of this component cannot
1371 : //be found in the registry and if there is another path and both have the same file name (but
1372 : //the rest of the path is different).
1373 : //If the caller cannot precisely determine that this package was registered, then it must
1374 : //call registerPackage.
1375 6 : bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration
1376 6 : || m_registered == REG_MAYBE_REGISTERED;
1377 : return beans::Optional< beans::Ambiguous<sal_Bool> >(
1378 : true /* IsPresent */,
1379 : beans::Ambiguous<sal_Bool>(
1380 6 : m_registered == REG_REGISTERED, bAmbiguous) );
1381 : }
1382 :
1383 :
1384 2 : void BackendImpl::ComponentPackageImpl::processPackage_(
1385 : ::osl::ResettableMutexGuard &,
1386 : bool doRegisterPackage,
1387 : bool startup,
1388 : ::rtl::Reference<AbortChannel> const & abortChannel,
1389 : Reference<XCommandEnvironment> const & xCmdEnv )
1390 : {
1391 2 : BackendImpl * that = getMyBackend();
1392 2 : OUString url(getURL());
1393 2 : if (doRegisterPackage) {
1394 1 : ComponentBackendDb::Data data;
1395 2 : css::uno::Reference< css::uno::XComponentContext > context;
1396 1 : if (startup) {
1397 0 : context = that->getComponentContext();
1398 : } else {
1399 1 : context.set(that->getObject(url), css::uno::UNO_QUERY);
1400 1 : if (!context.is()) {
1401 : context.set(
1402 : that->insertObject(
1403 : url,
1404 : raise_uno_process(
1405 2 : that->getComponentContext(), abortChannel)),
1406 1 : css::uno::UNO_QUERY_THROW);
1407 : }
1408 : }
1409 : css::uno::Reference< css::registry::XImplementationRegistration> impreg(
1410 2 : context->getServiceManager()->createInstanceWithContext(
1411 : "com.sun.star.registry.ImplementationRegistration",
1412 1 : context),
1413 2 : css::uno::UNO_QUERY_THROW);
1414 2 : css::uno::Reference< css::registry::XSimpleRegistry > rdb(getRDB());
1415 1 : impreg->registerImplementation(m_loader, url, rdb);
1416 : // Only write to unorc after successful registration; it may fail if
1417 : // there is no suitable java
1418 1 : if (m_loader == "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url, "UNO-Type-Path", xCmdEnv))
1419 : {
1420 1 : that->addToUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
1421 1 : data.javaTypeLibrary = true;
1422 : }
1423 2 : std::vector< css::uno::Reference< css::uno::XInterface > > factories;
1424 1 : getComponentInfo(&data, startup ? 0 : &factories, context);
1425 1 : if (!startup) {
1426 : try {
1427 1 : componentLiveInsertion(data, factories);
1428 0 : } catch (css::uno::Exception & e) {
1429 : SAL_INFO(
1430 : "desktop.deployment", "caught Exception " << e.Message);
1431 : try {
1432 0 : impreg->revokeImplementation(url, rdb);
1433 0 : } catch (css::uno::RuntimeException & e2) {
1434 : SAL_WARN(
1435 : "desktop.deployment",
1436 : "ignored RuntimeException " << e2.Message);
1437 : }
1438 0 : throw;
1439 : }
1440 : }
1441 1 : m_registered = REG_REGISTERED;
1442 2 : that->addDataToDb(url, data);
1443 : } else { // revoke
1444 1 : m_registered = REG_VOID;
1445 1 : ComponentBackendDb::Data data(that->readDataFromDb(url));
1446 : css::uno::Reference< css::uno::XComponentContext > context(
1447 2 : that->getObject(url), css::uno::UNO_QUERY);
1448 1 : bool remoteContext = context.is();
1449 1 : if (!remoteContext) {
1450 0 : context = that->getComponentContext();
1451 : }
1452 1 : if (!startup) {
1453 1 : componentLiveRemoval(data);
1454 : }
1455 : css::uno::Reference< css::registry::XImplementationRegistration >(
1456 2 : context->getServiceManager()->createInstanceWithContext(
1457 : "com.sun.star.registry.ImplementationRegistration",
1458 1 : context),
1459 1 : css::uno::UNO_QUERY_THROW)->revokeImplementation(url, getRDB());
1460 1 : if (data.javaTypeLibrary) {
1461 1 : that->removeFromUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
1462 : }
1463 1 : if (remoteContext) {
1464 1 : that->releaseObject(url);
1465 : }
1466 1 : m_registered = REG_NOT_REGISTERED;
1467 2 : getMyBackend()->revokeEntryFromDb(url);
1468 2 : }
1469 2 : }
1470 :
1471 0 : BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
1472 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
1473 : OUString const & url, OUString const & name,
1474 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
1475 : bool jarFile, bool bRemoved, OUString const & identifier)
1476 : : Package( myBackend, url, name, name /* display-name */,
1477 : xPackageType, bRemoved, identifier),
1478 0 : m_jarFile( jarFile )
1479 : {
1480 0 : }
1481 :
1482 : // Package
1483 0 : BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const
1484 : {
1485 0 : BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
1486 0 : if (NULL == pBackend)
1487 : {
1488 : //May throw a DisposedException
1489 0 : check();
1490 : //We should never get here...
1491 : throw RuntimeException( "Failed to get the BackendImpl",
1492 0 : static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this)));
1493 : }
1494 0 : return pBackend;
1495 : }
1496 :
1497 : beans::Optional< beans::Ambiguous<sal_Bool> >
1498 0 : BackendImpl::TypelibraryPackageImpl::isRegistered_(
1499 : ::osl::ResettableMutexGuard &,
1500 : ::rtl::Reference<AbortChannel> const &,
1501 : Reference<XCommandEnvironment> const & )
1502 : {
1503 0 : BackendImpl * that = getMyBackend();
1504 : return beans::Optional< beans::Ambiguous<sal_Bool> >(
1505 : true /* IsPresent */,
1506 : beans::Ambiguous<sal_Bool>(
1507 : that->hasInUnoRc(
1508 0 : m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, getURL() ),
1509 0 : false /* IsAmbiguous */ ) );
1510 : }
1511 :
1512 :
1513 0 : void BackendImpl::TypelibraryPackageImpl::processPackage_(
1514 : ::osl::ResettableMutexGuard &,
1515 : bool doRegisterPackage,
1516 : bool /*startup*/,
1517 : ::rtl::Reference<AbortChannel> const &,
1518 : Reference<XCommandEnvironment> const & xCmdEnv )
1519 : {
1520 0 : BackendImpl * that = getMyBackend();
1521 0 : const OUString url( getURL() );
1522 :
1523 0 : if (doRegisterPackage)
1524 : {
1525 : // live insertion:
1526 0 : if (m_jarFile) {
1527 : // xxx todo add to classpath at runtime: ???
1528 : //SB: It is probably not worth it to add the live inserted type
1529 : // library JAR to the UnoClassLoader in the soffice process. Any
1530 : // live inserted component JAR that might reference this type
1531 : // library JAR runs in its own uno process, so there is probably no
1532 : // Java code in the soffice process that would see any UNO types
1533 : // introduced by this type library JAR.
1534 : }
1535 : else // RDB:
1536 : {
1537 : css::uno::Reference< css::container::XSet >(
1538 0 : that->getComponentContext()->getValueByName(
1539 : "/singletons"
1540 0 : "/com.sun.star.reflection.theTypeDescriptionManager"),
1541 0 : css::uno::UNO_QUERY_THROW)->insert(
1542 0 : css::uno::makeAny(expandUnoRcUrl(url)));
1543 : }
1544 :
1545 : that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB,
1546 0 : url, xCmdEnv );
1547 : }
1548 : else // revokePackage()
1549 : {
1550 : that->removeFromUnoRc(
1551 0 : m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, url, xCmdEnv );
1552 :
1553 : // revoking types at runtime, possible, sensible?
1554 0 : if (!m_jarFile) {
1555 : css::uno::Reference< css::container::XSet >(
1556 0 : that->getComponentContext()->getValueByName(
1557 : "/singletons"
1558 0 : "/com.sun.star.reflection.theTypeDescriptionManager"),
1559 0 : css::uno::UNO_QUERY_THROW)->remove(
1560 0 : css::uno::makeAny(expandUnoRcUrl(url)));
1561 : }
1562 0 : }
1563 0 : }
1564 :
1565 0 : BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
1566 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
1567 : OUString const & url, OUString const & name,
1568 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
1569 : bool bRemoved, OUString const & identifier, OUString const& rPlatform)
1570 : : Package(myBackend, url, name, name, xPackageType, bRemoved, identifier)
1571 0 : , m_aPlatform(rPlatform)
1572 : {
1573 : OSL_PRECOND(bRemoved, "this class can only be used for removing packages!");
1574 0 : }
1575 :
1576 : BackendImpl *
1577 0 : BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
1578 : {
1579 0 : BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
1580 0 : if (NULL == pBackend)
1581 : {
1582 : //Throws a DisposedException
1583 0 : check();
1584 : //We should never get here...
1585 : throw RuntimeException("Failed to get the BackendImpl",
1586 0 : static_cast<OWeakObject*>(const_cast<OtherPlatformPackageImpl*>(this)));
1587 : }
1588 0 : return pBackend;
1589 : }
1590 :
1591 : Reference<registry::XSimpleRegistry> const
1592 0 : BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
1593 : {
1594 0 : OUString const aRDB(m_aPlatform + ".rdb");
1595 0 : OUString const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB));
1596 :
1597 0 : Reference<registry::XSimpleRegistry> xRegistry;
1598 :
1599 : try
1600 : {
1601 : xRegistry.set(
1602 : impl_createInstance("com.sun.star.registry.SimpleRegistry"),
1603 0 : UNO_QUERY)
1604 0 : ;
1605 0 : if (xRegistry.is())
1606 0 : xRegistry->open(expandUnoRcUrl(aRDBPath), false, false);
1607 : }
1608 0 : catch (registry::InvalidRegistryException const&)
1609 : {
1610 : // If the registry does not exist, we do not need to bother at all
1611 0 : xRegistry.set(0);
1612 : }
1613 :
1614 : SAL_WARN_IF( !xRegistry.is(), "desktop.deployment", "could not create registry for the package's platform");
1615 0 : return xRegistry;
1616 : }
1617 :
1618 : Reference<XInterface> const
1619 0 : BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString const& rService)
1620 : const
1621 : {
1622 0 : Reference<XComponentContext> const xContext(getMyBackend()->getComponentContext());
1623 : OSL_ASSERT(xContext.is());
1624 0 : Reference<XInterface> xService;
1625 0 : if (xContext.is())
1626 0 : xService.set(xContext->getServiceManager()->createInstanceWithContext(rService, xContext));
1627 0 : return xService;
1628 : }
1629 :
1630 : beans::Optional<beans::Ambiguous<sal_Bool> >
1631 0 : BackendImpl::OtherPlatformPackageImpl::isRegistered_(
1632 : ::osl::ResettableMutexGuard& /* guard */,
1633 : ::rtl::Reference<AbortChannel> const& /* abortChannel */,
1634 : Reference<XCommandEnvironment> const& /* xCmdEnv */ )
1635 : {
1636 : return beans::Optional<beans::Ambiguous<sal_Bool> >(sal_True,
1637 0 : beans::Ambiguous<sal_Bool>(sal_True, sal_False));
1638 : }
1639 :
1640 : void
1641 0 : BackendImpl::OtherPlatformPackageImpl::processPackage_(
1642 : ::osl::ResettableMutexGuard& /* guard */,
1643 : bool bRegisterPackage,
1644 : bool /* bStartup */,
1645 : ::rtl::Reference<AbortChannel> const& /* abortChannel */,
1646 : Reference<XCommandEnvironment> const& /* xCmdEnv */)
1647 : {
1648 : OSL_PRECOND(!bRegisterPackage, "this class can only be used for removing packages!");
1649 : (void) bRegisterPackage;
1650 :
1651 0 : OUString const aURL(getURL());
1652 :
1653 0 : Reference<registry::XSimpleRegistry> const xServicesRDB(impl_openRDB());
1654 : Reference<registry::XImplementationRegistration> const xImplReg(
1655 : impl_createInstance("com.sun.star.registry.ImplementationRegistration"),
1656 0 : UNO_QUERY)
1657 : ;
1658 0 : if (xImplReg.is() && xServicesRDB.is())
1659 0 : xImplReg->revokeImplementation(aURL, xServicesRDB);
1660 0 : if (xServicesRDB.is())
1661 0 : xServicesRDB->close();
1662 :
1663 0 : getMyBackend()->revokeEntryFromDb(aURL);
1664 0 : }
1665 :
1666 0 : BackendImpl * BackendImpl::ComponentsPackageImpl::getMyBackend() const
1667 : {
1668 0 : BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
1669 0 : if (NULL == pBackend)
1670 : {
1671 : //Throws a DisposedException
1672 0 : check();
1673 : //We should never get here...
1674 : throw RuntimeException("Failed to get the BackendImpl",
1675 0 : static_cast<OWeakObject*>(const_cast<ComponentsPackageImpl *>(this)));
1676 : }
1677 0 : return pBackend;
1678 : }
1679 :
1680 : beans::Optional< beans::Ambiguous<sal_Bool> >
1681 0 : BackendImpl::ComponentsPackageImpl::isRegistered_(
1682 : ::osl::ResettableMutexGuard &,
1683 : ::rtl::Reference<AbortChannel> const &,
1684 : Reference<XCommandEnvironment> const & )
1685 : {
1686 : return beans::Optional< beans::Ambiguous<sal_Bool> >(
1687 : true,
1688 : beans::Ambiguous<sal_Bool>(
1689 0 : getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS, getURL()), false));
1690 : }
1691 :
1692 0 : void BackendImpl::ComponentsPackageImpl::processPackage_(
1693 : ::osl::ResettableMutexGuard &,
1694 : bool doRegisterPackage,
1695 : bool startup,
1696 : ::rtl::Reference<AbortChannel> const & abortChannel,
1697 : Reference<XCommandEnvironment> const & xCmdEnv )
1698 : {
1699 0 : BackendImpl * that = getMyBackend();
1700 0 : OUString url(getURL());
1701 0 : if (doRegisterPackage) {
1702 0 : if (!startup) {
1703 : css::uno::Reference< css::uno::XComponentContext > context(
1704 0 : that->getObject(url), css::uno::UNO_QUERY);
1705 0 : if (!context.is()) {
1706 : context.set(
1707 : that->insertObject(
1708 : url,
1709 : raise_uno_process(
1710 0 : that->getComponentContext(), abortChannel)),
1711 0 : css::uno::UNO_QUERY_THROW);
1712 : }
1713 : // This relies on the root component context's service manager
1714 : // supporting the extended XSet semantics:
1715 0 : css::uno::Sequence< css::beans::NamedValue > args(2);
1716 0 : args[0].Name = "uri";
1717 0 : args[0].Value <<= expandUnoRcUrl(url);
1718 0 : args[1].Name = "component-context";
1719 0 : args[1].Value <<= context;
1720 : css::uno::Reference< css::container::XSet > smgr(
1721 0 : that->getRootContext()->getServiceManager(),
1722 0 : css::uno::UNO_QUERY_THROW);
1723 0 : smgr->insert(css::uno::makeAny(args));
1724 : }
1725 0 : that->addToUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
1726 : } else { // revoke
1727 0 : that->removeFromUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
1728 0 : if (!startup) {
1729 : // This relies on the root component context's service manager
1730 : // supporting the extended XSet semantics:
1731 0 : css::uno::Sequence< css::beans::NamedValue > args(1);
1732 0 : args[0].Name = "uri";
1733 0 : args[0].Value <<= expandUnoRcUrl(url);
1734 : css::uno::Reference< css::container::XSet > smgr(
1735 0 : that->getRootContext()->getServiceManager(),
1736 0 : css::uno::UNO_QUERY_THROW);
1737 0 : smgr->remove(css::uno::makeAny(args));
1738 : }
1739 0 : that->releaseObject(url);
1740 0 : that->revokeEntryFromDb(url); // in case it got added with old code
1741 0 : }
1742 0 : }
1743 :
1744 0 : BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
1745 : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
1746 : OUString const & url, OUString const & name,
1747 : Reference<deployment::XPackageTypeInfo> const & xPackageType,
1748 : bool bRemoved, OUString const & identifier)
1749 : : Package( myBackend, url, name, name /* display-name */,
1750 0 : xPackageType, bRemoved, identifier)
1751 0 : {}
1752 :
1753 : } // anon namespace
1754 :
1755 : namespace sdecl = comphelper::service_decl;
1756 111 : sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
1757 111 : extern sdecl::ServiceDecl const serviceDecl(
1758 : serviceBI,
1759 : IMPLEMENTATION_NAME,
1760 : BACKEND_SERVICE_NAME );
1761 :
1762 : } // namespace component
1763 : } // namespace backend
1764 333 : } // namespace dp_registry
1765 :
1766 :
1767 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|