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