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