--- desktop/source/deployment/registry/component/dp_component.cxx 2010-11-11 20:08:58.000000000 +0100 +++ desktop/source/deployment/registry/component/dp_component.cxx-gil 2011-03-03 15:35:01.000000000 +0100 @@ -192,6 +192,42 @@ OUString const & identifier); }; friend class TypelibraryPackageImpl; + + /** Serves for unregistering packages that were registered on a + different platform. This can happen if one has remotely mounted + /home, for example. + */ + class OtherPlatformPackageImpl : public ::dp_registry::backend::Package + { + public: + OtherPlatformPackageImpl( + ::rtl::Reference const & myBackend, + OUString const & url, OUString const & name, + Reference const & xPackageType, + bool bRemoved, OUString const & identifier, OUString const& rPlatform); + + private: + BackendImpl * getMyBackend() const; + + const Reference impl_openRDB() const; + const Reference impl_createInstance(OUString const& rService) const; + + // Package + virtual beans::Optional< beans::Ambiguous > isRegistered_( + ::osl::ResettableMutexGuard & guard, + ::rtl::Reference const & abortChannel, + Reference const & xCmdEnv ); + virtual void processPackage_( + ::osl::ResettableMutexGuard & guard, + bool registerPackage, + bool startup, + ::rtl::Reference const & abortChannel, + Reference const & xCmdEnv ); + + private: + OUString const m_aPlatform; + }; + friend class OtherPlatformPackageImpl; t_stringlist m_jar_typelibs; t_stringlist m_rdb_typelibs; @@ -698,16 +734,30 @@ INetContentTypeParameter const * param = params.find( ByteString("platform") ); - if (param == 0 || platform_fits( param->m_sValue )) { + bool bPlatformFits(param == 0); + String aPlatform; + if (!bPlatformFits) // platform is specified, we have to check + { + aPlatform = param->m_sValue; + bPlatformFits = platform_fits(aPlatform); + } + // If the package is being removed, do not care whether + // platform fits. We won't be using it anyway. + if (bPlatformFits || bRemoved) { param = params.find( ByteString("type") ); if (param != 0) { String const & value = param->m_sValue; if (value.EqualsIgnoreCaseAscii("native")) { - return new BackendImpl::ComponentPackageImpl( - this, url, name, m_xDynComponentTypeInfo, - OUSTR("com.sun.star.loader.SharedLibrary"), - bRemoved, identifier); + if (bPlatformFits) + return new BackendImpl::ComponentPackageImpl( + this, url, name, m_xDynComponentTypeInfo, + OUSTR("com.sun.star.loader.SharedLibrary"), + bRemoved, identifier); + else + return new BackendImpl::OtherPlatformPackageImpl( + this, url, name, m_xDynComponentTypeInfo, + bRemoved, identifier, aPlatform); } if (value.EqualsIgnoreCaseAscii("Java")) { return new BackendImpl::ComponentPackageImpl( @@ -1571,6 +1621,110 @@ } } +BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl( + ::rtl::Reference const & myBackend, + OUString const & url, OUString const & name, + Reference const & xPackageType, + bool bRemoved, OUString const & identifier, OUString const& rPlatform) + : Package(myBackend, url, name, name, xPackageType, bRemoved, identifier) + , m_aPlatform(rPlatform) +{ + OSL_PRECOND(bRemoved, "this class can only be used for removing packages!"); +} + +BackendImpl * +BackendImpl::OtherPlatformPackageImpl::getMyBackend() const +{ + BackendImpl * pBackend = static_cast(m_myBackend.get()); + if (NULL == pBackend) + { + //Throws a DisposedException + check(); + //We should never get here... + throw RuntimeException( + OUSTR("Failed to get the BackendImpl"), + static_cast(const_cast(this))); + } + return pBackend; +} + +Reference const +BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const +{ + OUString const aRDB(m_aPlatform + OUString(RTL_CONSTASCII_USTRINGPARAM(".rdb"))); + OUString const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB)); + + Reference xRegistry; + + try + { + xRegistry.set( + impl_createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"))), + UNO_QUERY) + ; + if (xRegistry.is()) + xRegistry->open(expandUnoRcUrl(aRDBPath), false, false); + } + catch (registry::InvalidRegistryException const&) + { + // If the registry does not exist, we do not need to bother at all + xRegistry.set(0); + } + + OSL_POSTCOND(xRegistry.is(), "could not create registry for the package's platform"); + return xRegistry; +} + +Reference const +BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString const& rService) +const +{ + Reference const xContext(getMyBackend()->getComponentContext()); + OSL_ASSERT(xContext.is()); + Reference xService; + if (xContext.is()) + xService.set(xContext->getServiceManager()->createInstanceWithContext(rService, xContext)); + return xService; +} + +beans::Optional > +BackendImpl::OtherPlatformPackageImpl::isRegistered_( + ::osl::ResettableMutexGuard& /* guard */, + ::rtl::Reference const& /* abortChannel */, + Reference const& /* xCmdEnv */ ) +{ + return beans::Optional >(sal_True, + beans::Ambiguous(sal_True, sal_False)); +} + +void +BackendImpl::OtherPlatformPackageImpl::processPackage_( + ::osl::ResettableMutexGuard& /* guard */, + bool bRegisterPackage, + bool /* bStartup */, + ::rtl::Reference const& /* abortChannel */, + Reference const& /* xCmdEnv */) +{ + OSL_PRECOND(!bRegisterPackage, "this class can only be used for removing packages!"); + (void) bRegisterPackage; + + OUString const aURL(getURL()); + + Reference const xServicesRDB(impl_openRDB()); + Reference const xImplReg( + impl_createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration"))), + UNO_QUERY) + ; + if (xImplReg.is() && xServicesRDB.is()) + xImplReg->revokeImplementation(aURL, xServicesRDB); + if (xServicesRDB.is()) + xServicesRDB->close(); + + getMyBackend()->deleteDataFromDb(aURL); +} + } // anon namespace namespace sdecl = comphelper::service_decl;