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