summaryrefslogtreecommitdiff
path: root/desktop/source/deployment/registry/component/dp_component.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/deployment/registry/component/dp_component.cxx')
-rw-r--r--desktop/source/deployment/registry/component/dp_component.cxx1586
1 files changed, 1586 insertions, 0 deletions
diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx
new file mode 100644
index 000000000000..e0844c227669
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.cxx
@@ -0,0 +1,1586 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_component.hrc"
+#include "dp_backend.h"
+#include "dp_platform.hxx"
+#include "dp_ucb.h"
+#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svl/inettype.hxx"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XSet.hpp"
+#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/registry/XImplementationRegistration.hpp"
+#include "com/sun/star/loader/XImplementationLoader.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include <list>
+#include <hash_map>
+#include <vector>
+#include <memory>
+#include <algorithm>
+#include "dp_compbackenddb.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+namespace {
+
+typedef ::std::list<OUString> t_stringlist;
+typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
+
+#define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
+
+/** return a vector of bootstrap variables which have been provided
+ as command arguments.
+*/
+::std::vector<OUString> getCmdBootstrapVariables()
+{
+ ::std::vector<OUString> ret;
+ sal_uInt32 count = osl_getCommandArgCount();
+ for (sal_uInt32 i = 0; i < count; i++)
+ {
+ OUString arg;
+ osl_getCommandArg(i, &arg.pData);
+ if (arg.matchAsciiL("-env:", 5))
+ ret.push_back(arg);
+ }
+ return ret;
+}
+
+bool jarManifestHeaderPresent(
+ OUString const & url, OUString const & name,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append(
+ ::rtl::Uri::encode(
+ url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/META-INF/MANIFEST.MF") );
+ ::ucbhelper::Content manifestContent;
+ OUString line;
+ return
+ create_ucb_content(
+ &manifestContent, buf.makeStringAndClear(), xCmdEnv,
+ false /* no throw */ )
+ && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US );
+}
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class ComponentPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const OUString m_loader;
+ ComponentBackendDb::Data m_registeredComponentsDb;
+
+ enum reg {
+ REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_REGISTERED
+ } m_registered;
+
+ Reference<loader::XImplementationLoader> getComponentInfo(
+ t_stringlist * pImplNames, t_stringpairvec * pSingletons,
+ Reference<XComponentContext> const & xContext );
+
+ virtual void SAL_CALL disposing();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ const Reference<registry::XSimpleRegistry> getRDB() const;
+
+ //Provides the read-only registry (e.g. not the one based on the duplicated
+ //rdb files
+ const Reference<registry::XSimpleRegistry> getRDB_RO() const;
+
+ public:
+ ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader, bool bRemoved,
+ OUString const & identifier);
+ };
+ friend class ComponentPackageImpl;
+
+ class TypelibraryPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const bool m_jarFile;
+ Reference<container::XHierarchicalNameAccess> m_xTDprov;
+
+ virtual void SAL_CALL disposing();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile, bool bRemoved,
+ OUString const & identifier);
+ };
+ friend class TypelibraryPackageImpl;
+
+ t_stringlist m_jar_typelibs;
+ t_stringlist m_rdb_typelibs;
+ t_stringlist & getTypelibs( bool jar ) {
+ return jar ? m_jar_typelibs : m_rdb_typelibs;
+ }
+
+ bool m_unorc_inited;
+ bool m_unorc_modified;
+ bool bSwitchedRdbFiles;
+
+ typedef ::std::hash_map< OUString, Reference<XInterface>,
+ ::rtl::OUStringHash > t_string2object;
+ t_string2object m_backendObjects;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+ const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ OUString m_commonRDB;
+ OUString m_nativeRDB;
+
+ //URLs of the read-only rdbs (e.g. not the ones of the duplicated files)
+ OUString m_commonRDB_RO;
+ OUString m_nativeRDB_RO;
+
+ std::auto_ptr<ComponentBackendDb> m_backendDb;
+
+ void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data);
+ void deleteDataFromDb(OUString const & url);
+ ComponentBackendDb::Data readDataFromDb(OUString const & url);
+
+
+ //These rdbs are for writing new service entries. The rdb files are copies
+ //which are created when services are added or removed.
+ Reference<registry::XSimpleRegistry> m_xCommonRDB;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB;
+
+ //These rdbs are created on the read-only rdbs which are already used
+ //by UNO since the startup of the current session.
+ Reference<registry::XSimpleRegistry> m_xCommonRDB_RO;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB_RO;
+
+
+ void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv );
+ void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv );
+
+ Reference<XInterface> getObject( OUString const & id );
+ Reference<XInterface> insertObject(
+ OUString const & id, Reference<XInterface> const & xObject );
+ void releaseObject( OUString const & id );
+
+ bool addToUnoRc( bool jarFile, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool removeFromUnoRc( bool jarFile, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool hasInUnoRc( bool jarFile, OUString const & url );
+
+
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+
+ //Will be called from ComponentPackageImpl
+ void initServiceRdbFiles();
+
+ //Creates the READ ONLY registries (m_xCommonRDB_RO,m_xNativeRDB_RO)
+ void initServiceRdbFiles_RO();
+};
+
+//______________________________________________________________________________
+
+BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_loader( loader ),
+ m_registered( REG_UNINIT )
+{
+ if (bRemoved)
+ {
+ m_registeredComponentsDb = getMyBackend()->readDataFromDb(url);
+ }
+}
+
+
+const Reference<registry::XSimpleRegistry>
+BackendImpl::ComponentPackageImpl::getRDB() const
+{
+ BackendImpl * that = getMyBackend();
+
+ //Late "initialization" of the services rdb files
+ //This is to prevent problems when running several
+ //instances of OOo with root rights in parallel. This
+ //would otherwise cause problems when copying the rdbs.
+ //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
+ {
+ const ::osl::MutexGuard guard( getMutex() );
+ if (!that->bSwitchedRdbFiles)
+ {
+ that->bSwitchedRdbFiles = true;
+ that->initServiceRdbFiles();
+ }
+ }
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
+ return that->m_xNativeRDB;
+ else
+ return that->m_xCommonRDB;
+}
+
+//Returns the read only RDB.
+const Reference<registry::XSimpleRegistry>
+BackendImpl::ComponentPackageImpl::getRDB_RO() const
+{
+ BackendImpl * that = getMyBackend();
+
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
+ return that->m_xNativeRDB_RO;
+ else
+ return that->m_xCommonRDB_RO;
+}
+
+BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(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<OWeakObject*>(const_cast<ComponentPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::disposing()
+{
+// m_xRemoteContext.clear();
+ Package::disposing();
+}
+
+//______________________________________________________________________________
+void BackendImpl::TypelibraryPackageImpl::disposing()
+{
+ m_xTDprov.clear();
+ Package::disposing();
+}
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ try {
+ m_backendObjects = t_string2object();
+ if (m_xNativeRDB.is()) {
+ m_xNativeRDB->close();
+ m_xNativeRDB.clear();
+ }
+ if (m_xCommonRDB.is()) {
+ m_xCommonRDB->close();
+ m_xCommonRDB.clear();
+ }
+ unorc_flush( Reference<XCommandEnvironment>() );
+
+ PackageRegistryBackend::disposing();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing..."),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+
+void BackendImpl::initServiceRdbFiles()
+{
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv );
+ ::ucbhelper::Content oldRDB;
+ // switch common rdb:
+ if (m_commonRDB_RO.getLength() > 0)
+ {
+ create_ucb_content(
+ &oldRDB, makeURL( getCachePath(), m_commonRDB_RO),
+ xCmdEnv, false /* no throw */ );
+ }
+ m_commonRDB = m_commonRDB_RO.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("common.rdb") )
+ ? OUSTR("common_.rdb") : OUSTR("common.rdb");
+ if (oldRDB.get().is())
+ {
+ if (! cacheDir.transferContent(
+ oldRDB, ::ucbhelper::InsertOperation_COPY,
+ m_commonRDB, NameClash::OVERWRITE ))
+ {
+
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ }
+ oldRDB = ::ucbhelper::Content();
+ }
+ // switch native rdb:
+ if (m_nativeRDB_RO.getLength() > 0)
+ {
+ create_ucb_content(
+ &oldRDB, makeURL(getCachePath(), m_nativeRDB_RO),
+ xCmdEnv, false /* no throw */ );
+ }
+ const OUString plt_rdb( getPlatformString() + OUSTR(".rdb") );
+ const OUString plt_rdb_( getPlatformString() + OUSTR("_.rdb") );
+ m_nativeRDB = m_nativeRDB_RO.equals( plt_rdb ) ? plt_rdb_ : plt_rdb;
+ if (oldRDB.get().is())
+ {
+ if (! cacheDir.transferContent(
+ oldRDB, ::ucbhelper::InsertOperation_COPY,
+ m_nativeRDB, NameClash::OVERWRITE ))
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ }
+
+ // UNO is bootstrapped, flush for next process start:
+ m_unorc_modified = true;
+ unorc_flush( Reference<XCommandEnvironment>() );
+
+
+ // common rdb for java, native rdb for shared lib components
+ if (m_commonRDB.getLength() > 0) {
+ m_xCommonRDB.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext ), UNO_QUERY_THROW );
+ m_xCommonRDB->open(
+ makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ),
+// m_readOnly, !m_readOnly );
+ false, true);
+ }
+ if (m_nativeRDB.getLength() > 0) {
+ m_xNativeRDB.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext ), UNO_QUERY_THROW );
+ m_xNativeRDB->open(
+ makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ),
+// m_readOnly, !m_readOnly );
+ false, true);
+ }
+}
+
+void BackendImpl::initServiceRdbFiles_RO()
+{
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ // common rdb for java, native rdb for shared lib components
+ if (m_commonRDB_RO.getLength() > 0)
+ {
+ m_xCommonRDB_RO.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext), UNO_QUERY_THROW);
+ m_xCommonRDB_RO->open(
+ makeURL(expandUnoRcUrl(getCachePath()), m_commonRDB_RO),
+ sal_True, //read-only
+ sal_True); // create data source if necessary
+ }
+ if (m_nativeRDB_RO.getLength() > 0)
+ {
+ m_xNativeRDB_RO.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext), UNO_QUERY_THROW);
+ m_xNativeRDB_RO->open(
+ makeURL(expandUnoRcUrl(getCachePath()), m_nativeRDB_RO),
+ sal_True, //read-only
+ sal_True); // create data source if necessary
+ }
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_unorc_inited( false ),
+ m_unorc_modified( false ),
+ bSwitchedRdbFiles(false),
+ m_xDynComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=native;platform=") +
+ getPlatformString(),
+ OUSTR("*" SAL_DLLEXTENSION),
+ getResourceString(RID_STR_DYN_COMPONENT),
+ RID_IMG_COMPONENT,
+ RID_IMG_COMPONENT_HC ) ),
+ m_xJavaComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=Java"),
+ OUSTR("*.jar"),
+ getResourceString(RID_STR_JAVA_COMPONENT),
+ RID_IMG_JAVA_COMPONENT,
+ RID_IMG_JAVA_COMPONENT_HC ) ),
+ m_xPythonComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=Python"),
+ OUSTR("*.py"),
+ getResourceString(
+ RID_STR_PYTHON_COMPONENT),
+ RID_IMG_COMPONENT,
+ RID_IMG_COMPONENT_HC ) ),
+ m_xRDBTypelibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-typelibrary;"
+ "type=RDB"),
+ OUSTR("*.rdb"),
+ getResourceString(RID_STR_RDB_TYPELIB),
+ RID_IMG_TYPELIB, RID_IMG_TYPELIB_HC ) ),
+ m_xJavaTypelibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-typelibrary;"
+ "type=Java"),
+ OUSTR("*.jar"),
+ getResourceString(RID_STR_JAVA_TYPELIB),
+ RID_IMG_JAVA_TYPELIB,
+ RID_IMG_JAVA_TYPELIB_HC ) ),
+ m_typeInfos( 5 )
+{
+ m_typeInfos[ 0 ] = m_xDynComponentTypeInfo;
+ m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo;
+ m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo;
+ m_typeInfos[ 3 ] = m_xRDBTypelibTypeInfo;
+ m_typeInfos[ 4 ] = m_xJavaTypelibTypeInfo;
+
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ if (transientMode())
+ {
+ // in-mem rdbs:
+ // common rdb for java, native rdb for shared lib components
+ m_xCommonRDB.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xComponentContext ), UNO_QUERY_THROW );
+ m_xCommonRDB->open( OUString() /* in-mem */,
+ false /* ! read-only */, true /* create */ );
+ m_xNativeRDB.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xComponentContext ), UNO_QUERY_THROW );
+ m_xNativeRDB->open( OUString() /* in-mem */,
+ false /* ! read-only */, true /* create */ );
+ }
+ else
+ {
+ //do this before initServiceRdbFiles_RO, because it determines
+ //m_commonRDB and m_nativeRDB
+ unorc_verify_init( xCmdEnv );
+
+ initServiceRdbFiles_RO();
+
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ComponentBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ComponentBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url)
+{
+ ComponentBackendDb::Data data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0 ||
+ mediaType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-component") ) ||
+ mediaType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-typelibrary") ))
+ {
+ // detect exact media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv )) {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.uno-component;"
+ "type=native;platform=") +
+ getPlatformString();
+ }
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".jar") ))
+ {
+ if (jarManifestHeaderPresent(
+ url, OUSTR("RegistrationClassName"), xCmdEnv ))
+ mediaType = OUSTR(
+ "application/vnd.sun.star.uno-component;type=Java");
+ if (mediaType.getLength() == 0)
+ mediaType = OUSTR(
+ "application/vnd.sun.star.uno-typelibrary;type=Java");
+ }
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".py") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.uno-component;type=Python");
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".rdb") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.uno-typelibrary;type=RDB");
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.uno-component"))
+ {
+ // xxx todo: probe and evaluate component xml description
+
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param == 0 || platform_fits( param->m_sValue )) {
+ 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 (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xJavaComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Java2"),
+ bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Python")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xPythonComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Python"),
+ bRemoved, identifier);
+ }
+ }
+ }
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.uno-typelibrary"))
+ {
+ INetContentTypeParameter const * param = params.find(
+ ByteString("type") );
+ if (param != 0) {
+ String const & value = param->m_sValue;
+ if (value.EqualsIgnoreCaseAscii("RDB"))
+ {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xRDBTypelibTypeInfo,
+ false /* rdb */, bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xJavaTypelibTypeInfo,
+ true /* jar */, bRemoved, identifier);
+ }
+ }
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+void BackendImpl::unorc_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ const ::osl::MutexGuard guard( getMutex() );
+ if (! m_unorc_inited)
+ {
+ // common rc:
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), OUSTR("unorc") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OUString line;
+ if (readLine( &line, OUSTR("UNO_JAVA_CLASSPATH="), ucb_content,
+ RTL_TEXTENCODING_UTF8 ))
+ {
+ sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0)
+ {
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ ))
+ {
+ //The jar file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the unorc
+ //After running XExtensionManager::synchronize, the unorc is
+ //cleaned up
+ m_jar_typelibs.push_back( token );
+ }
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("UNO_TYPES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0)
+ {
+ if (token[ 0 ] == '?')
+ token = token.copy( 1 );
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ ))
+ {
+ //The RDB file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the unorc.
+ //After running XExtensionManager::synchronize, the unorc is
+ //cleaned up
+ m_rdb_typelibs.push_back( token );
+ }
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 start = sizeof ("UNO_SERVICES=?$ORIGIN/") - 1;
+ sal_Int32 sep = line.indexOf( ' ', start );
+ OSL_ASSERT( sep > 0 );
+ m_commonRDB_RO = line.copy( start, sep - start );
+ }
+
+ // native rc:
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), getPlatformString() + OUSTR("rc")),
+ xCmdEnv, false /* no throw */ )) {
+ if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ m_nativeRDB_RO = line.copy(
+ sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
+ }
+ }
+ }
+ m_unorc_modified = false;
+ m_unorc_inited = true;
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ if (!m_unorc_inited || !m_unorc_modified)
+ return;
+
+ ::rtl::OStringBuffer buf;
+
+ buf.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
+ OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
+ ::rtl::OString osOrigin = ::rtl::OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
+ buf.append(osOrigin);
+ buf.append(LF);
+
+ if (! m_jar_typelibs.empty())
+ {
+ t_stringlist::const_iterator iPos( m_jar_typelibs.begin() );
+ t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_JAVA_CLASSPATH=") );
+ while (iPos != iEnd) {
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+ if (! m_rdb_typelibs.empty())
+ {
+ t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() );
+ t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_TYPES=") );
+ while (iPos != iEnd) {
+ buf.append( '?' );
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+
+ // If we duplicated the common or native rdb then we must use those urls
+ //otherwise we use those of the original files. That is, m_commonRDB_RO and
+ //m_nativeRDB_RO;
+ OUString sCommonRDB(m_commonRDB.getLength() > 0 ? m_commonRDB : m_commonRDB_RO);
+ OUString sNativeRDB(m_nativeRDB.getLength() > 0 ? m_nativeRDB : m_nativeRDB_RO);
+
+ if (sCommonRDB.getLength() > 0 || sNativeRDB.getLength() > 0)
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf.append( ::rtl::OUStringToOString(
+ sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
+ if (sNativeRDB.getLength() > 0)
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM(
+ " ${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}") );
+ buf.append(LF);
+
+ // write native rc:
+ ::rtl::OStringBuffer buf2;
+ buf2.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
+ buf2.append(osOrigin);
+ buf2.append(LF);
+ buf2.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf2.append( ::rtl::OUStringToOString(
+ sNativeRDB, RTL_TEXTENCODING_ASCII_US ) );
+ buf2.append(LF);
+
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf2.getStr()),
+ buf2.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), getPlatformString() + OUSTR("rc") ),
+ xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+ }
+ }
+
+ // write unorc:
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf.getStr()),
+ buf.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), OUSTR("unorc") ), xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+
+ m_unorc_modified = false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::addToUnoRc( bool jarFile, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ unorc_verify_init( xCmdEnv );
+ t_stringlist & rSet = getTypelibs(jarFile);
+ if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
+ rSet.push_front( rcterm ); // prepend to list, thus overriding
+ // write immediately:
+ m_unorc_modified = true;
+ unorc_flush( xCmdEnv );
+ return true;
+ }
+ else
+ return false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::removeFromUnoRc(
+ bool jarFile, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ unorc_verify_init( xCmdEnv );
+ getTypelibs(jarFile).remove( rcterm );
+ // write immediately:
+ m_unorc_modified = true;
+ unorc_flush( xCmdEnv );
+ return true;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::hasInUnoRc(
+ bool jarFile, OUString const & url_ )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ t_stringlist const & rSet = getTypelibs(jarFile);
+ return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end();
+}
+
+//______________________________________________________________________________
+void BackendImpl::releaseObject( OUString const & id )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ if ( m_backendObjects.erase( id ) != 1 )
+ {
+ OSL_ASSERT( false );
+ }
+}
+
+//______________________________________________________________________________
+Reference<XInterface> BackendImpl::getObject( OUString const & id )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ const t_string2object::const_iterator iFind( m_backendObjects.find( id ) );
+ if (iFind == m_backendObjects.end())
+ return Reference<XInterface>();
+ else
+ return iFind->second;
+}
+
+//______________________________________________________________________________
+Reference<XInterface> BackendImpl::insertObject(
+ OUString const & id, Reference<XInterface> const & xObject )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ const ::std::pair<t_string2object::iterator, bool> insertion(
+ m_backendObjects.insert( t_string2object::value_type(
+ id, xObject ) ) );
+ return insertion.first->second;
+}
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> raise_uno_process(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::Reference<AbortChannel> const & abortChannel )
+{
+ OSL_ASSERT( xContext.is() );
+
+ ::rtl::OUString url(
+ Reference<util::XMacroExpander>(
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
+ UNO_QUERY_THROW )->
+ expandMacros( OUSTR("$URE_BIN_DIR/uno") ) );
+
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
+ OUString pipeId( generateRandomPipeId() );
+ buf.append( pipeId );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(";urp;uno.ComponentContext") );
+ const OUString connectStr( buf.makeStringAndClear() );
+
+ // raise core UNO process to register/run a component,
+ // javavm service uses unorc next to executable to retrieve deployed
+ // jar typelibs
+
+ ::std::vector<OUString> args;
+#if OSL_DEBUG_LEVEL <= 1
+ args.push_back( OUSTR("--quiet") );
+#endif
+ args.push_back( OUSTR("--singleaccept") );
+ args.push_back( OUSTR("-u") );
+ args.push_back( connectStr );
+ // don't inherit from unorc:
+ args.push_back( OUSTR("-env:INIFILENAME=") );
+
+ //now add the bootstrap variables which were supplied on the command line
+ ::std::vector<OUString> bootvars = getCmdBootstrapVariables();
+ args.insert(args.end(), bootvars.begin(), bootvars.end());
+
+ oslProcess hProcess = raiseProcess(
+ url, comphelper::containerToSequence(args) );
+ try {
+ return Reference<XComponentContext>(
+ resolveUnoURL( connectStr, xContext, abortChannel.get() ),
+ UNO_QUERY_THROW );
+ }
+ catch (...) {
+ // try to terminate process:
+ if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
+ {
+ OSL_ASSERT( false );
+ }
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+Reference<loader::XImplementationLoader>
+BackendImpl::ComponentPackageImpl::getComponentInfo(
+ t_stringlist * pImplNames, t_stringpairvec * pSingletons,
+ Reference<XComponentContext> const & xContext )
+{
+ const Reference<loader::XImplementationLoader> xLoader(
+ xContext->getServiceManager()->createInstanceWithContext(
+ m_loader, xContext ), UNO_QUERY );
+ if (! xLoader.is())
+ return Reference<loader::XImplementationLoader>();
+
+ // HACK: highly dependent on stoc/source/servicemanager
+ // and stoc/source/implreg implementation which rely on the same
+ // services.rdb format!
+
+ const Reference<registry::XSimpleRegistry> xMemReg(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"), xContext ),
+ UNO_QUERY_THROW );
+ xMemReg->open( OUString() /* in mem */, false, true );
+ xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), getURL() );
+
+ const Sequence< Reference<registry::XRegistryKey> > keys(
+ xMemReg->getRootKey()->openKeys() );
+ for ( sal_Int32 pos = keys.getLength(); pos--; )
+ {
+ Reference<registry::XRegistryKey> const & xImplKey = keys[ pos ];
+ const OUString implName(
+ xImplKey->getKeyName().copy( 1 /*leading slash*/ ) );
+
+ // check for singletons:
+ const Reference<registry::XRegistryKey> xSingletonKey(
+ xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
+ if (xSingletonKey.is() && xSingletonKey->isValid())
+ {
+ const Sequence< Reference<registry::XRegistryKey> > singletonKeys(
+ xSingletonKey->openKeys() );
+ for ( sal_Int32 i = singletonKeys.getLength(); i--; )
+ {
+ Reference<registry::XRegistryKey> const & xSingleton =
+ singletonKeys[ i ];
+ pSingletons->push_back(
+ ::std::pair<OUString, OUString>(
+ xSingleton->getKeyName().copy(
+ implName.getLength() +
+ sizeof ("//UNO/SINGLETONS/") - 1 ),
+ xSingleton->getStringValue() ) );
+ }
+ }
+ else
+ {
+ pImplNames->push_back( implName );
+ }
+ }
+
+ return xLoader;
+}
+
+// Package
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::ComponentPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & )
+{
+ if (m_registered == REG_UNINIT)
+ {
+ m_registered = REG_NOT_REGISTERED;
+ bool bAmbiguousComponentName = false;
+ const Reference<registry::XSimpleRegistry> xRDB( getRDB_RO() );
+ if (xRDB.is())
+ {
+ // lookup rdb for location URL:
+ const Reference<registry::XRegistryKey> xRootKey(
+ xRDB->getRootKey() );
+ const Reference<registry::XRegistryKey> xImplKey(
+ xRootKey->openKey( OUSTR("IMPLEMENTATIONS") ) );
+ Sequence<OUString> implNames;
+ if (xImplKey.is() && xImplKey->isValid())
+ implNames = xImplKey->getKeyNames();
+ OUString const * pImplNames = implNames.getConstArray();
+ sal_Int32 pos = implNames.getLength();
+ for ( ; pos--; )
+ {
+ checkAborted( abortChannel );
+ const OUString key(
+ pImplNames[ pos ] + OUSTR("/UNO/LOCATION") );
+ const Reference<registry::XRegistryKey> xKey(
+ xRootKey->openKey(key) );
+ if (xKey.is() && xKey->isValid())
+ {
+ const OUString location( xKey->getAsciiValue() );
+ if (location.equalsIgnoreAsciiCase( getURL() ))
+ {
+ break;
+ }
+ else
+ {
+ //try to match only the file name
+ OUString thisUrl(getURL());
+ OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
+
+ OUString locationFileName(location.copy(location.lastIndexOf('/')));
+ if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
+ bAmbiguousComponentName = true;
+ }
+ }
+ }
+ if (pos >= 0)
+ m_registered = REG_REGISTERED;
+ else if (bAmbiguousComponentName)
+ m_registered = REG_MAYBE_REGISTERED;
+ }
+ }
+
+ //Different extensions can use the same service implementations. Then the extensions
+ //which was installed last will overwrite the one from the other extension. That is
+ //the registry will contain the path (the location) of the library or jar of the
+ //second extension. In this case isRegistered called for the lib of the first extension
+ //would return "not registered". That would mean that during uninstallation
+ //XPackage::registerPackage is not called, because it just was not registered. This is,
+ //however, necessary for jar files. Registering and unregistering update
+ //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
+ //Therefore, we will return always "is ambiguous" if the path of this component cannot
+ //be found in the registry and if there is another path and both have the same file name (but
+ //the rest of the path is different).
+ //If the caller cannot precisely determine that this package was registered, then it must
+ //call registerPackage.
+ sal_Bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration
+ || m_registered == REG_MAYBE_REGISTERED;
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ m_registered == REG_REGISTERED, bAmbiguous) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+
+
+ const bool java = m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.Java2") );
+ const OUString url( getURL() );
+ bool isJavaTypelib;
+ if (m_bRemoved)
+ isJavaTypelib = m_registeredComponentsDb.javaTypeLibrary;
+ else
+ isJavaTypelib = java &&
+ !jarManifestHeaderPresent( url, OUSTR("UNO-Type-Path"), xCmdEnv );
+
+ ComponentBackendDb::Data data;
+ data.javaTypeLibrary = isJavaTypelib;
+ if (doRegisterPackage)
+ {
+ Reference <uno::XComponentContext> context(that->getComponentContext());
+ if (! startup)
+ {
+ context.set(
+ that->getObject( url ), UNO_QUERY );
+
+ if (! context.is()) {
+ context.set(
+ that->insertObject( url, raise_uno_process(
+ that->getComponentContext(),
+ abortChannel ) ),
+ UNO_QUERY_THROW );
+ }
+ }
+
+ const Reference<registry::XSimpleRegistry> xServicesRDB( getRDB() );
+ const Reference<registry::XImplementationRegistration> xImplReg(
+ context->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.ImplementationRegistration"),
+ context ), UNO_QUERY_THROW );
+
+ xImplReg->registerImplementation( m_loader, url, xServicesRDB );
+ //only write to unorc if registration was successful.
+ //It may fail if there is no suitable java.
+ if (isJavaTypelib)
+ {
+ that->addToUnoRc( java, url, xCmdEnv );
+ data.javaTypeLibrary = true;
+ }
+
+ t_stringlist implNames;
+ t_stringpairvec singletons;
+ const Reference<loader::XImplementationLoader> xLoader(
+ getComponentInfo( &implNames, &singletons, context ) );
+ data.implementationNames = implNames;
+ data.singletons = singletons;
+
+ if (!startup)
+ {
+ // factories live insertion:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getServiceManager(), UNO_QUERY_THROW );
+ for ( t_stringlist::const_iterator iPos( implNames.begin() );
+ iPos != implNames.end(); ++iPos )
+ {
+ checkAborted( abortChannel );
+ OUString const & implName = *iPos;
+ // activate factory:
+ const Reference<XInterface> xFactory(
+ xLoader->activate(
+ implName, OUString(), url,
+ xServicesRDB->getRootKey()->openKey(
+ OUSTR("/IMPLEMENTATIONS/") + implName ) ) );
+ try {
+ xSet->insert( Any(xFactory) );
+ } // ignore if factory has already been inserted:
+ catch (container::ElementExistException &) {
+ OSL_ENSURE( 0, "### factory already registered?" );
+ }
+ }
+
+ if (! singletons.empty())
+ {
+ // singletons live insertion:
+ const Reference<container::XNameContainer> xRootContext(
+ that->getComponentContext()->getValueByName(
+ OUSTR("_root") ), UNO_QUERY );
+ if (xRootContext.is())
+ {
+ for ( t_stringpairvec::const_iterator iPos(
+ singletons.begin() );
+ iPos != singletons.end(); ++iPos )
+ {
+ ::std::pair<OUString, OUString> const & sp = *iPos;
+ const OUString name( OUSTR("/singletons/") + sp.first );
+ // assure no arguments:
+ try {
+ xRootContext->removeByName( name + OUSTR("/arguments"));
+ } catch (container::NoSuchElementException &) {}
+ // used service:
+ try {
+ xRootContext->insertByName(
+ name + OUSTR("/service"), Any(sp.second) );
+ } catch (container::ElementExistException &) {
+ xRootContext->replaceByName(
+ name + OUSTR("/service"), Any(sp.second) );
+ }
+ // singleton entry:
+ try {
+ xRootContext->insertByName( name, Any() );
+ } catch (container::ElementExistException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE(
+ 0, OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ xRootContext->replaceByName( name, Any() );
+ }
+ }
+ }
+ }
+ }
+
+ m_registered = REG_REGISTERED;
+ getMyBackend()->addDataToDb(url, data);
+ }
+ else // revokePackage()
+ {
+ // set to VOID during revocation process:
+ m_registered = REG_VOID;
+
+ //get the remote context. If it does not exist then use the local one
+ Reference<XComponentContext> xContext(
+ that->getObject( url ), UNO_QUERY );
+ bool bRemoteContext = false;
+ if (!xContext.is())
+ xContext = that->getComponentContext();
+ else
+ bRemoteContext = true;
+
+ t_stringlist implNames;
+ t_stringpairvec singletons;
+ if (m_bRemoved)
+ {
+ implNames = m_registeredComponentsDb.implementationNames;
+ singletons = m_registeredComponentsDb.singletons;
+ }
+ else
+ {
+ getComponentInfo( &implNames, &singletons, xContext );
+ }
+
+ if (!startup)
+ {
+ // factories live removal:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getServiceManager(), UNO_QUERY_THROW );
+ for ( t_stringlist::const_iterator iPos( implNames.begin() );
+ iPos != implNames.end(); ++iPos )
+ {
+ OUString const & implName = *iPos;
+ try {
+ xSet->remove( Any(implName) );
+ } // ignore if factory has not been live deployed:
+ catch (container::NoSuchElementException &) {
+ }
+ }
+
+ if (! singletons.empty())
+ {
+ // singletons live removal:
+ const Reference<container::XNameContainer> xRootContext(
+ that->getComponentContext()->getValueByName(
+ OUSTR("_root") ), UNO_QUERY );
+ if (xRootContext.is())
+ {
+ for ( t_stringpairvec::const_iterator iPos(
+ singletons.begin() );
+ iPos != singletons.end(); ++iPos )
+ {
+ ::std::pair<OUString, OUString> const & sp = *iPos;
+ const OUString name( OUSTR("/singletons/") + sp.first );
+ // arguments:
+ try {
+ xRootContext->removeByName( name + OUSTR("/arguments"));
+ }
+ catch (container::NoSuchElementException &) {}
+ // used service:
+ try {
+ xRootContext->removeByName( name + OUSTR("/service") );
+ }
+ catch (container::NoSuchElementException &) {}
+ // singleton entry:
+ try {
+ xRootContext->removeByName( name );
+ }
+ catch (container::NoSuchElementException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE(
+ 0, OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ }
+ }
+ }
+
+ const Reference<registry::XSimpleRegistry> xServicesRDB( getRDB() );
+ const Reference<registry::XImplementationRegistration> xImplReg(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.ImplementationRegistration"),
+ xContext ), UNO_QUERY_THROW );
+ xImplReg->revokeImplementation( url, xServicesRDB );
+
+ if (isJavaTypelib)
+ that->removeFromUnoRc( java, url, xCmdEnv );
+
+ if (bRemoteContext)
+ that->releaseObject( url );
+
+ m_registered = REG_NOT_REGISTERED;
+ getMyBackend()->deleteDataFromDb(url);
+ }
+}
+
+//##############################################################################
+BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_jarFile( jarFile )
+{
+}
+
+// Package
+BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::TypelibraryPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ that->hasInUnoRc( m_jarFile, getURL() ),
+ false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::TypelibraryPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /*startup*/,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ const OUString url( getURL() );
+
+ if (doRegisterPackage)
+ {
+ // live insertion:
+ if (m_jarFile) {
+ // xxx todo add to classpath at runtime: ???
+ //SB: It is probably not worth it to add the live inserted type
+ // library JAR to the UnoClassLoader in the soffice process. Any
+ // live inserted component JAR that might reference this type
+ // library JAR runs in its own uno process, so there is probably no
+ // Java code in the soffice process that would see any UNO types
+ // introduced by this type library JAR.
+ }
+ else // RDB:
+ {
+ Reference<XComponentContext> const & xContext =
+ that->getComponentContext();
+ if (! m_xTDprov.is())
+ {
+ m_xTDprov.set( that->getObject( url ), UNO_QUERY );
+ if (! m_xTDprov.is())
+ {
+ const Reference<registry::XSimpleRegistry> xReg(
+ xContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xContext ), UNO_QUERY_THROW );
+ xReg->open( expandUnoRcUrl(url),
+ true /* read-only */, false /* ! create */ );
+ const Any arg(xReg);
+ Reference<container::XHierarchicalNameAccess> xTDprov(
+ xContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.comp.stoc."
+ "RegistryTypeDescriptionProvider"),
+ Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY );
+ OSL_ASSERT( xTDprov.is() );
+ if (xTDprov.is())
+ m_xTDprov.set( that->insertObject( url, xTDprov ),
+ UNO_QUERY_THROW );
+ }
+ }
+ if (m_xTDprov.is()) {
+ Reference<container::XSet> xSet(
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "reflection.theTypeDescriptionManager") ),
+ UNO_QUERY_THROW );
+ xSet->insert( Any(m_xTDprov) );
+ }
+ }
+
+ that->addToUnoRc( m_jarFile, url, xCmdEnv );
+ }
+ else // revokePackage()
+ {
+ that->removeFromUnoRc( m_jarFile, url, xCmdEnv );
+
+ // revoking types at runtime, possible, sensible?
+ if (!m_xTDprov.is())
+ m_xTDprov.set( that->getObject( url ), UNO_QUERY );
+ if (m_xTDprov.is()) {
+ // remove live:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "reflection.theTypeDescriptionManager") ),
+ UNO_QUERY_THROW );
+ xSet->remove( Any(m_xTDprov) );
+
+ that->releaseObject( url );
+ m_xTDprov.clear();
+ }
+ }
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ IMPLEMENTATION_NAME,
+ BACKEND_SERVICE_NAME );
+
+} // namespace component
+} // namespace backend
+} // namespace dp_registry
+
+