4090557
From d7cc1b57990e1ebc2e1f2a4380dd8e66b0eff158 Mon Sep 17 00:00:00 2001
4090557
From: David Tardon <dtardon@redhat.com>
4090557
Date: Thu, 10 Feb 2011 13:54:19 +0100
4090557
Subject: [PATCH] rhbz#649310 don't crash deregistering diff. platform ext.
4090557
4090557
This happens, for example, if one switches between, lets say, x86 and
4090557
x86_64 systems and has the same /home mounted from both. Then
4090557
platform-dependent extensions from one system does not exist on the
4090557
other one, but must still be deregistered correctly.
4090557
---
4090557
 .../deployment/registry/component/dp_component.cxx |  164 +++++++++++++++++++-
4090557
 1 files changed, 159 insertions(+), 5 deletions(-)
4090557
4090557
diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx
4090557
index b7fe0b1..d4cb5dd 100644
4090557
--- a/desktop/source/deployment/registry/component/dp_component.cxx
4090557
+++ b/desktop/source/deployment/registry/component/dp_component.cxx
4090557
@@ -192,6 +192,42 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
4090557
             OUString const & identifier);
4090557
     };
4090557
     friend class TypelibraryPackageImpl;
4090557
+
4090557
+    /** Serves for unregistering packages that were registered on a
4090557
+        different platform. This can happen if one has remotely mounted
4090557
+        /home, for example.
4090557
+     */
4090557
+    class OtherPlatformPackageImpl : public ::dp_registry::backend::Package
4090557
+    {
4090557
+    public:
4090557
+        OtherPlatformPackageImpl(
4090557
+            ::rtl::Reference<PackageRegistryBackend> const & myBackend,
4090557
+            OUString const & url, OUString const & name,
4090557
+            Reference<deployment::XPackageTypeInfo> const & xPackageType,
4090557
+            bool bRemoved, OUString const & identifier, OUString const& rPlatform);
4090557
+
4090557
+    private:
4090557
+        BackendImpl * getMyBackend() const;
4090557
+
4090557
+        const Reference<registry::XSimpleRegistry> impl_openRDB() const;
4090557
+        const Reference<XInterface> impl_createInstance(OUString const& rService) const;
4090557
+
4090557
+        // Package
4090557
+        virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
4090557
+            ::osl::ResettableMutexGuard & guard,
4090557
+            ::rtl::Reference<AbortChannel> const & abortChannel,
4090557
+            Reference<XCommandEnvironment> const & xCmdEnv );
4090557
+        virtual void processPackage_(
4090557
+            ::osl::ResettableMutexGuard & guard,
4090557
+            bool registerPackage,
4090557
+            bool startup,
4090557
+            ::rtl::Reference<AbortChannel> const & abortChannel,
4090557
+            Reference<XCommandEnvironment> const & xCmdEnv );
4090557
+
4090557
+    private:
4090557
+        OUString const m_aPlatform;
4090557
+    };
4090557
+    friend class OtherPlatformPackageImpl;
4090557
     
4090557
     t_stringlist m_jar_typelibs;
4090557
     t_stringlist m_rdb_typelibs;
4090557
@@ -694,16 +730,30 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_(
4090557
                 
4090557
                 INetContentTypeParameter const * param = params.find(
4090557
                     ByteString("platform") );
4090557
-                if (param == 0 || platform_fits( param->m_sValue )) {
4090557
+                bool bPlatformFits(param == 0);
4090557
+                String aPlatform;
4090557
+                if (!bPlatformFits) // platform is specified, we have to check
4090557
+                {
4090557
+                    aPlatform = param->m_sValue;
4090557
+                    bPlatformFits = platform_fits(aPlatform);
4090557
+                }
4090557
+                // If the package is being removed, do not care whether
4090557
+                // platform fits. We won't be using it anyway.
4090557
+                if (bPlatformFits || bRemoved) {
4090557
                     param = params.find( ByteString("type") );
4090557
                     if (param != 0)
4090557
                     {
4090557
                         String const & value = param->m_sValue;
4090557
                         if (value.EqualsIgnoreCaseAscii("native")) {
4090557
-                            return new BackendImpl::ComponentPackageImpl(
4090557
-                                this, url, name, m_xDynComponentTypeInfo,
4090557
-                                OUSTR("com.sun.star.loader.SharedLibrary"),
4090557
-                                bRemoved, identifier);
4090557
+                            if (bPlatformFits)
4090557
+                                return new BackendImpl::ComponentPackageImpl(
4090557
+                                    this, url, name, m_xDynComponentTypeInfo,
4090557
+                                    OUSTR("com.sun.star.loader.SharedLibrary"),
4090557
+                                    bRemoved, identifier);
4090557
+                            else
4090557
+                                return new BackendImpl::OtherPlatformPackageImpl(
4090557
+                                    this, url, name, m_xDynComponentTypeInfo,
4090557
+                                    bRemoved, identifier, aPlatform);
4090557
                         }
4090557
                         if (value.EqualsIgnoreCaseAscii("Java")) {
4090557
                             return new BackendImpl::ComponentPackageImpl(
4090557
@@ -1567,6 +1617,110 @@ void BackendImpl::TypelibraryPackageImpl::processPackage_(
4090557
     }
4090557
 }
4090557
 
4090557
+BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
4090557
+    ::rtl::Reference<PackageRegistryBackend> const & myBackend,
4090557
+    OUString const & url, OUString const & name,
4090557
+    Reference<deployment::XPackageTypeInfo> const & xPackageType,
4090557
+    bool bRemoved, OUString const & identifier, OUString const& rPlatform)
4090557
+    : Package(myBackend, url, name, name, xPackageType, bRemoved, identifier)
4090557
+    , m_aPlatform(rPlatform)
4090557
+{
4090557
+    OSL_PRECOND(bRemoved, "this class can only be used for removing packages!");
4090557
+}
4090557
+
4090557
+BackendImpl *
4090557
+BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
4090557
+{
4090557
+    BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
4090557
+    if (NULL == pBackend)
4090557
+    {
4090557
+        //Throws a DisposedException
4090557
+        check();
4090557
+        //We should never get here...
4090557
+        throw RuntimeException(
4090557
+            OUSTR("Failed to get the BackendImpl"),
4090557
+            static_cast<OWeakObject*>(const_cast<OtherPlatformPackageImpl*>(this)));
4090557
+    }
4090557
+    return pBackend;
4090557
+}
4090557
+
4090557
+Reference<registry::XSimpleRegistry> const
4090557
+BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
4090557
+{
4090557
+    OUString const aRDB(m_aPlatform + OUString(RTL_CONSTASCII_USTRINGPARAM(".rdb")));
4090557
+    OUString const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB));
4090557
+
4090557
+    Reference<registry::XSimpleRegistry> xRegistry;
4090557
+
4090557
+    try
4090557
+    {
4090557
+        xRegistry.set(
4090557
+                impl_createInstance(
4090557
+                    OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"))),
4090557
+                UNO_QUERY)
4090557
+            ;
4090557
+        if (xRegistry.is())
4090557
+            xRegistry->open(expandUnoRcUrl(aRDBPath), false, false);
4090557
+    }
4090557
+    catch (registry::InvalidRegistryException const&)
4090557
+    {
4090557
+        // If the registry does not exist, we do not need to bother at all
4090557
+        xRegistry.set(0);
4090557
+    }
4090557
+
4090557
+    OSL_POSTCOND(xRegistry.is(), "could not create registry for the package's platform");
4090557
+    return xRegistry;
4090557
+}
4090557
+
4090557
+Reference<XInterface> const
4090557
+BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString const& rService)
4090557
+const
4090557
+{
4090557
+    Reference<XComponentContext> const xContext(getMyBackend()->getComponentContext());
4090557
+    OSL_ASSERT(xContext.is());
4090557
+    Reference<XInterface> xService;
4090557
+    if (xContext.is())
4090557
+        xService.set(xContext->getServiceManager()->createInstanceWithContext(rService, xContext));
4090557
+    return xService;
4090557
+}
4090557
+
4090557
+beans::Optional<beans::Ambiguous<sal_Bool> >
4090557
+BackendImpl::OtherPlatformPackageImpl::isRegistered_(
4090557
+    ::osl::ResettableMutexGuard& /* guard */,
4090557
+    ::rtl::Reference<AbortChannel> const& /* abortChannel */,
4090557
+    Reference<XCommandEnvironment> const& /* xCmdEnv */ )
4090557
+{
4090557
+    return beans::Optional<beans::Ambiguous<sal_Bool> >(sal_True,
4090557
+            beans::Ambiguous<sal_Bool>(sal_True, sal_False));
4090557
+}
4090557
+
4090557
+void
4090557
+BackendImpl::OtherPlatformPackageImpl::processPackage_(
4090557
+    ::osl::ResettableMutexGuard& /* guard */,
4090557
+    bool bRegisterPackage,
4090557
+    bool /* bStartup */,
4090557
+    ::rtl::Reference<AbortChannel> const& /* abortChannel */,
4090557
+    Reference<XCommandEnvironment> const& /* xCmdEnv */)
4090557
+{
4090557
+    OSL_PRECOND(!bRegisterPackage, "this class can only be used for removing packages!");
4090557
+    (void) bRegisterPackage;
4090557
+
4090557
+    OUString const aURL(getURL());
4090557
+
4090557
+    Reference<registry::XSimpleRegistry> const xServicesRDB(impl_openRDB());
4090557
+    Reference<registry::XImplementationRegistration> const xImplReg(
4090557
+            impl_createInstance(
4090557
+                OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration"))),
4090557
+            UNO_QUERY)
4090557
+        ;
4090557
+    if (xImplReg.is() && xServicesRDB.is())
4090557
+        xImplReg->revokeImplementation(aURL, xServicesRDB);
4090557
+    if (xServicesRDB.is())
4090557
+        xServicesRDB->close();
4090557
+
4090557
+    getMyBackend()->deleteDataFromDb(aURL);
4090557
+}
4090557
+
4090557
 } // anon namespace
4090557
 
4090557
 namespace sdecl = comphelper::service_decl;
4090557
-- 
4090557
1.7.4
4090557